diff --git a/.gitignore b/.gitignore index 1dfa7f9aa0..3427518389 100644 --- a/.gitignore +++ b/.gitignore @@ -83,6 +83,7 @@ wiiu/wut/elf2rpl/elf2rpl *.smdh /retroarch_3ds.core /retroarch_3ds.icn +/retroarch_3ds_salamander.icn # Ctags /tags diff --git a/CHANGES.md b/CHANGES.md index 83effa6e63..da5022db79 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ - 3DS: Now correctly reports amount of CPU cores. - 3DS: Frontend rating is now correctly implemented for both New 3DS/2DS and Old 3DS/2DS. - 3DS: Initial networking support, HTTP requests won't work yet. +- 3DS: Now reports memory and battery state. - AUDIO: Added 'Audio Resampler Quality' setting to Audio Settings. Setting this higher will increase sound quality at the expense of sound latency and/or performance. Setting this value lower will improve sound latency/performance at the expense of sound quality. Only has an effect if the Sinc resampler is used, and you have to restart the game for changes to take effect. - CHEEVOS: Fix unofficial achievements not being loaded. - CHEEVOS: Show the menu entries when no achievements are found even if hardcore mode is enabled. @@ -25,6 +26,8 @@ - WIIU: Overlay support. - WIIU: Transparency support in menu + overlays. - WIIU: New HID pad support. +- WIIU: Shader support. +- WIIU: Ribbon menu effect added (shaders). # 1.7.0 - CHEEVOS: Add badges for achievements, shows thumbnail images of achievements. diff --git a/Makefile.common b/Makefile.common index 885d94eefc..b255b1937a 100644 --- a/Makefile.common +++ b/Makefile.common @@ -199,7 +199,7 @@ OBJ += frontend/frontend.o \ $(LIBRETRO_COMM_DIR)/audio/audio_mixer.o \ input/input_driver.o \ led/led_driver.o \ - led/null_led_driver.o \ + led/drivers/led_null.o \ gfx/video_coord_array.o \ gfx/video_display_server.o \ gfx/video_driver.o \ @@ -796,7 +796,7 @@ ifeq ($(HAVE_OVERLAY), 1) OBJ += \ tasks/task_overlay.o \ input/input_overlay.o \ - led/overlay_led_driver.o + led/drivers/led_overlay.o endif ifeq ($(HAVE_STB_FONT), 1) @@ -1355,6 +1355,7 @@ ifeq ($(HAVE_IBXM), 1) endif ifeq ($(HAVE_BUILTINFLAC),1) + HAVE_FLAC = 1 CFLAGS += -DHAVE_FLAC -I$(DEPS_DIR)/libFLAC/include DEFINES += -DHAVE_STDINT_H -DHAVE_LROUND -DFLAC__HAS_OGG=0 \ -DFLAC_PACKAGE_VERSION="\"retroarch\"" @@ -1666,5 +1667,5 @@ OBJ += libretro-common/audio/dsp_filters/echo.o \ endif ifeq ($(HAVE_RPILED), 1) - OBJ += led/rpi_led_driver.o + OBJ += led/drivers/led_rpi.o endif diff --git a/Makefile.wiiu b/Makefile.wiiu index 789b6c9fcc..453d22a9be 100644 --- a/Makefile.wiiu +++ b/Makefile.wiiu @@ -6,7 +6,6 @@ DEBUG = 0 GRIFFIN_BUILD = 0 SALAMANDER_BUILD = 0 WHOLE_ARCHIVE_LINK = 0 -HAVE_HID = 0 WIIU_HID = 0 BUILD_DIR = objs/wiiu PC_DEVELOPMENT_IP_ADDRESS ?= @@ -15,6 +14,8 @@ PC_DEVELOPMENT_TCP_PORT ?= ifeq ($(SALAMANDER_BUILD),1) BUILD_DIR := $(BUILD_DIR)-salamander TARGET := $(TARGET)_salamander +else ifeq ($(GRIFFIN_BUILD),1) + BUILD_DIR := $(BUILD_DIR)-griffin endif ifeq ($(DEBUG),1) @@ -70,12 +71,14 @@ else DEFINES += -DHAVE_UPDATE_ASSETS DEFINES += -DHAVE_FILTERS_BUILTIN DEFINES += -DHAVE_SLANG + DEFINES += -DHAVE_SHADERPIPELINE OBJ += wiiu/system/missing_libc_functions.o OBJ += wiiu/shader_utils.o OBJ += wiiu/tex_shader.o OBJ += wiiu/sprite_shader.o OBJ += wiiu/frame_shader.o + OBJ += wiiu/ribbon_shader.o OBJ += gfx/drivers_shader/slang_preprocess.o OBJ += gfx/drivers_shader/glslang_util.o @@ -87,6 +90,7 @@ else # DEFINES += -DWANT_IFADDRS # DEFINES += -DHAVE_FREETYPE DEFINES += -DHAVE_XMB -DHAVE_MATERIALUI +# DEFINES += -DHAVE_HID else HAVE_MENU_COMMON = 1 HAVE_RTGA = 1 @@ -112,6 +116,7 @@ else HAVE_OVERLAY = 1 HAVE_STATIC_VIDEO_FILTERS = 1 HAVE_STATIC_AUDIO_FILTERS = 1 +# HAVE_HID = 1 WANT_LIBFAT = 1 WANT_IOSUHAX = 1 diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index ec1030047b..529580d5ab 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -24,6 +24,8 @@ #include <3ds/svc.h> #include <3ds/os.h> #include <3ds/services/cfgu.h> +#include <3ds/services/ptmu.h> +#include <3ds/services/mcuhwc.h> #include @@ -135,6 +137,8 @@ static void frontend_ctr_deinit(void *data) parallax_layer_reg_state = (*(float*)0x1FF81080 == 0.0)? 0x0 : 0x00010001; GSPGPU_WriteHWRegs(0x202000, ¶llax_layer_reg_state, 4); + mcuHwcExit(); + ptmuExit(); cfguExit(); ndspExit(); csndExit(); @@ -373,6 +377,8 @@ static void frontend_ctr_init(void *data) if(ndspInit() != 0) audio_ctr_dsp = audio_null; cfguInit(); + ptmuInit(); + mcuHwcInit(); #endif } @@ -430,6 +436,100 @@ static int frontend_ctr_parse_drive_list(void *data, bool load_content) return 0; } +static uint64_t frontend_ctr_get_mem_total(void) +{ + return osGetMemRegionSize(MEMREGION_ALL); +} + +static uint64_t frontend_ctr_get_mem_used(void) +{ + return osGetMemRegionUsed(MEMREGION_ALL); +} + +static enum frontend_powerstate frontend_ctr_get_powerstate(int *seconds, int *percent) +{ + u8 battery_percent = 0; + u8 charging = 0; + enum frontend_powerstate pwr_state = FRONTEND_POWERSTATE_NONE; + + mcuHwcGetBatteryLevel(&battery_percent); + *percent = battery_percent; + + /* 3ds does not support seconds of charge remaining */ + *seconds = -1; + + PTMU_GetBatteryChargeState(&charging); + if (charging) + { + if (battery_percent == 100) + { + pwr_state = FRONTEND_POWERSTATE_CHARGED; + } + else + { + pwr_state = FRONTEND_POWERSTATE_CHARGING; + } + } + else + { + pwr_state = FRONTEND_POWERSTATE_ON_POWER_SOURCE; + } + + return pwr_state; +} + +static void frontend_ctr_get_os(char *s, size_t len, int *major, int *minor) +{ + OS_VersionBin cver; + OS_VersionBin nver; + + strlcpy(s, "3DS OS", len); + Result data_invalid = osGetSystemVersionData(&nver, &cver); + if (data_invalid == 0) + { + *major = cver.mainver; + *minor = cver.minor; + } + else + { + *major = 0; + *minor = 0; + } + +} + +static void frontend_ctr_get_name(char *s, size_t len) +{ + u8 device_model = 0xFF; + CFGU_GetSystemModel(&device_model);/*(0 = O3DS, 1 = O3DSXL, 2 = N3DS, 3 = 2DS, 4 = N3DSXL, 5 = N2DSXL)*/ + + switch (device_model) + { + case 0: + strlcpy(s, "Old 3DS", len); + break; + case 1: + strlcpy(s, "Old 3DS XL", len); + break; + case 2: + strlcpy(s, "New 3DS", len); + break; + case 3: + strlcpy(s, "Old 2DS", len); + break; + case 4: + strlcpy(s, "New 3DS XL", len); + break; + case 5: + strlcpy(s, "New 2DS XL", len); + break; + + default: + strlcpy(s, "Unknown Device", len); + break; + } +} + frontend_ctx_driver_t frontend_ctx_ctr = { frontend_ctr_get_environment_settings, frontend_ctr_init, @@ -443,15 +543,15 @@ frontend_ctx_driver_t frontend_ctx_ctr = { frontend_ctr_set_fork, #endif frontend_ctr_shutdown, - NULL, /* get_name */ - NULL, /* get_os */ + frontend_ctr_get_name, + frontend_ctr_get_os, frontend_ctr_get_rating, NULL, /* load_content */ frontend_ctr_get_architecture, - NULL, /* get_powerstate */ + frontend_ctr_get_powerstate, frontend_ctr_parse_drive_list, - NULL, /* get_mem_total */ - NULL, /* get_mem_free */ + frontend_ctr_get_mem_total, + frontend_ctr_get_mem_used, NULL, /* install_signal_handler */ NULL, /* get_signal_handler_state */ NULL, /* set_signal_handler_state */ diff --git a/gfx/common/d3d_common.c b/gfx/common/d3d_common.c index 51e90f377a..26de8a3f73 100644 --- a/gfx/common/d3d_common.c +++ b/gfx/common/d3d_common.c @@ -767,11 +767,14 @@ static void d3d_set_texture_stage_state(LPDIRECT3DDEVICE dev, unsigned sampler, unsigned value, unsigned type) { #if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_SetTextureStageState(dev, sampler, (D3DTEXTURESTAGESTATETYPE)type, value); + if (IDirect3DDevice9_SetTextureStageState(dev, sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) + RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); #elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DDevice8_SetTextureStageState(dev, sampler, (D3DTEXTURESTAGESTATETYPE)type, value); + if (IDirect3DDevice8_SetTextureStageState(dev, sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) + RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); #else - dev->SetTextureStageState(sampler, (D3DTEXTURESTAGESTATETYPE)type, value); + if (dev->SetTextureStageState(sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) + RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); #endif } #endif diff --git a/gfx/common/gx2_common.h b/gfx/common/gx2_common.h index 736a12d44a..6412870379 100644 --- a/gfx/common/gx2_common.h +++ b/gfx/common/gx2_common.h @@ -1,7 +1,11 @@ +#pragma once + #include #include "wiiu/frame_shader.h" +#include "wiiu/tex_shader.h" #include "wiiu/sprite_shader.h" +#include "wiiu/ribbon_shader.h" #include "gfx/video_shader_parse.h" #undef _X @@ -55,8 +59,8 @@ typedef struct bool overlay_full_screen; #endif - GX2Sampler sampler_nearest; - GX2Sampler sampler_linear; + GX2Sampler sampler_nearest[RARCH_WRAP_MAX]; + GX2Sampler sampler_linear[RARCH_WRAP_MAX]; GX2Texture texture; frame_vertex_t* v; GX2_vec2* ubo_vp; @@ -70,12 +74,21 @@ typedef struct int width; int height; + float* menu_display_coord_array; + ribbon_uniform_t* ribbon_ubo; + struct { sprite_vertex_t* v; int size; int current; } vertex_cache; + struct + { + tex_shader_vertex_t* v; + int size; + int current; + } vertex_cache_tex; void* drc_scan_buffer; void* tv_scan_buffer; @@ -86,11 +99,13 @@ typedef struct struct { GFDFile* gfd; - float* vs_ubo; - float* ps_ubo; + float* vs_ubos[2]; + float* ps_ubos[2]; GX2Texture texture; GX2ColorBuffer color_buffer; + bool mem1; }pass[GFX_MAX_SHADERS]; + GX2Texture luts[GFX_MAX_TEXTURES]; wiiu_render_mode_t render_mode; video_viewport_t vp; diff --git a/gfx/common/win32_common.c b/gfx/common/win32_common.c index bffbec8db6..d3985c1f0b 100644 --- a/gfx/common/win32_common.c +++ b/gfx/common/win32_common.c @@ -816,7 +816,8 @@ bool win32_window_create(void *data, unsigned style, SetWindowLongPtr(main_window.hwnd, GWL_EXSTYLE, GetWindowLongPtr(main_window.hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); - SetLayeredWindowAttributes(main_window.hwnd, 0, (255 * settings->uints.video_window_opacity) / 100, LWA_ALPHA); + SetLayeredWindowAttributes(main_window.hwnd, 0, (255 * + settings->uints.video_window_opacity) / 100, LWA_ALPHA); #endif #endif return true; @@ -944,7 +945,7 @@ bool win32_suppress_screensaver(void *data, bool enable) if (frontend->get_os) frontend->get_os(tmp, sizeof(tmp), &major, &minor); - if (major*100+minor >= 601) + if (major * 100 + minor >= 601) { #if _WIN32_WINNT >= 0x0601 /* Windows 7, 8, 10 codepath */ @@ -973,7 +974,7 @@ bool win32_suppress_screensaver(void *data, bool enable) } #endif } - else if (major*100+minor >= 410) + else if (major * 100 + minor >= 410) { #if _WIN32_WINDOWS >= 0x0410 || _WIN32_WINNT >= 0x0410 /* 98 / 2K / XP / Vista codepath */ @@ -981,12 +982,12 @@ bool win32_suppress_screensaver(void *data, bool enable) return true; #endif } - else - { + else + { /* 95 / NT codepath */ - /* No way to block the screensaver. */ + /* No way to block the screensaver. */ return true; - } + } } #endif @@ -998,18 +999,17 @@ void win32_set_style(MONITORINFOEX *current_mon, HMONITOR *hm_to_use, RECT *rect, RECT *mon_rect, DWORD *style) { #ifndef _XBOX - settings_t *settings = config_get_ptr(); - - /* Windows only reports the refresh rates for modelines as - * an integer, so video_refresh_rate needs to be rounded. Also, account - * for black frame insertion using video_refresh_rate set to half - * of the display refresh rate, as well as higher vsync swap intervals. */ - float refresh_mod = settings->bools.video_black_frame_insertion ? 2.0f : 1.0f; - unsigned refresh = roundf(settings->floats.video_refresh_rate - * refresh_mod * settings->uints.video_swap_interval); - if (fullscreen) { + settings_t *settings = config_get_ptr(); + /* Windows only reports the refresh rates for modelines as + * an integer, so video_refresh_rate needs to be rounded. Also, account + * for black frame insertion using video_refresh_rate set to half + * of the display refresh rate, as well as higher vsync swap intervals. */ + float refresh_mod = settings->bools.video_black_frame_insertion ? 2.0f : 1.0f; + unsigned refresh = roundf(settings->floats.video_refresh_rate + * refresh_mod * settings->uints.video_swap_interval); + if (windowed_full) { *style = WS_EX_TOPMOST | WS_POPUP; @@ -1022,7 +1022,7 @@ void win32_set_style(MONITORINFOEX *current_mon, HMONITOR *hm_to_use, if (!win32_monitor_set_fullscreen(*width, *height, refresh, current_mon->szDevice)) - {} + {} /* Display settings might have changed, get new coordinates. */ GetMonitorInfo(*hm_to_use, (LPMONITORINFO)current_mon); @@ -1031,10 +1031,12 @@ void win32_set_style(MONITORINFOEX *current_mon, HMONITOR *hm_to_use, } else { - *style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - rect->right = *width; - rect->bottom = *height; + *style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; + rect->right = *width; + rect->bottom = *height; + AdjustWindowRect(rect, *style, FALSE); + g_resize_width = *width = rect->right - rect->left; g_resize_height = *height = rect->bottom - rect->top; } @@ -1179,7 +1181,11 @@ bool win32_has_focus(void) HWND win32_get_window(void) { +#ifdef _XBOX + return NULL; +#else return main_window.hwnd; +#endif } void win32_window_reset(void) @@ -1192,9 +1198,9 @@ void win32_destroy_window(void) { #ifndef _XBOX UnregisterClass("RetroArch", GetModuleHandle(NULL)); -#endif #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x500 /* 2K */ UnregisterDeviceNotification(notification_handler); +#endif #endif main_window.hwnd = NULL; } @@ -1203,7 +1209,7 @@ void win32_get_video_output_prev( unsigned *width, unsigned *height) { DEVMODE dm; - int iModeNum; + unsigned i; bool found = false; unsigned prev_width = 0; unsigned prev_height = 0; @@ -1216,9 +1222,9 @@ void win32_get_video_output_prev( win32_get_video_output_size(&curr_width, &curr_height); - for (iModeNum = 0; - EnumDisplaySettings(NULL, iModeNum, &dm) != 0; - iModeNum++) + for (i = 0; + EnumDisplaySettings(NULL, i, &dm) != 0; + i++) { if ( dm.dmPelsWidth == curr_width && dm.dmPelsHeight == curr_height) @@ -1246,7 +1252,7 @@ void win32_get_video_output_next( unsigned *width, unsigned *height) { DEVMODE dm; - int iModeNum; + int i; bool found = false; unsigned curr_width = 0; unsigned curr_height = 0; @@ -1256,9 +1262,9 @@ void win32_get_video_output_next( win32_get_video_output_size(&curr_width, &curr_height); - for (iModeNum = 0; - EnumDisplaySettings(NULL, iModeNum, &dm) != 0; - iModeNum++) + for (i = 0; + EnumDisplaySettings(NULL, i, &dm) != 0; + i++) { if (found) { diff --git a/gfx/drivers/d3d.c b/gfx/drivers/d3d.c index 0cf7fbd79a..e20de55124 100644 --- a/gfx/drivers/d3d.c +++ b/gfx/drivers/d3d.c @@ -586,9 +586,7 @@ void d3d_make_d3dpp(void *data, d3dpp->BackBufferCount = 2; d3dpp->BackBufferFormat = d3d_get_color_format_backbuffer( info->rgb32, windowed_enable); -#ifndef _XBOX d3dpp->hDeviceWindow = win32_get_window(); -#endif #ifdef _XBOX360 d3dpp->FrontBufferFormat = d3d_get_color_format_front_buffer(); @@ -672,11 +670,7 @@ void d3d_make_d3dpp(void *data, static bool d3d_init_base(void *data, const video_info_t *info) { D3DPRESENT_PARAMETERS d3dpp; -#ifdef _XBOX - HWND focus_window = NULL; -#else HWND focus_window = win32_get_window(); -#endif d3d_video_t *d3d = (d3d_video_t*)data; memset(&d3dpp, 0, sizeof(d3dpp)); @@ -1290,9 +1284,7 @@ static void d3d_free(void *data) d3d->dev = NULL; g_pD3D = NULL; -#ifndef _XBOX win32_monitor_from_window(); -#endif if (d3d) free(d3d); @@ -1453,9 +1445,7 @@ static bool d3d_frame(void *data, const void *frame, D3DVIEWPORT screen_vp; unsigned i = 0; d3d_video_t *d3d = (d3d_video_t*)data; -#ifndef _XBOX HWND window = win32_get_window(); -#endif unsigned width = video_info->width; unsigned height = video_info->height; @@ -1467,10 +1457,8 @@ static bool d3d_frame(void *data, const void *frame, /* We cannot recover in fullscreen. */ if (d3d->needs_restore) { -#ifndef _XBOX if (IsIconic(window)) return true; -#endif if (!d3d_restore(d3d)) { diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index f37d39dc8a..3dc0d88338 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -1202,7 +1202,8 @@ static bool gl_frame(void *data, const void *frame, video_info->cb_swap_buffers(video_info->context_data, video_info); - if (video_info->hard_sync && gl->have_sync) + /* check if we are fast forwarding, if we are ignore hard sync */ + if (gl->have_sync && video_info->hard_sync && !video_info->input_driver_nonblock_state) { glClear(GL_COLOR_BUFFER_BIT); diff --git a/gfx/drivers/switch_gfx.c b/gfx/drivers/switch_gfx.c index d756b6e286..d4ab9f5823 100644 --- a/gfx/drivers/switch_gfx.c +++ b/gfx/drivers/switch_gfx.c @@ -165,15 +165,17 @@ static bool switch_frame(void *data, const void *frame, { for(y = 0; y < height; y++) { + unsigned subx, suby; uint32_t pixel = 0; if (sw->rgb32) { const uint32_t *frame_pixels = frame; pixel = frame_pixels[(y*pitch/sizeof(uint32_t)) + x]; - } else { + } + else + { const uint16_t *frame_pixels = frame; - unsigned subx, suby; uint32_t spixel = frame_pixels[(y*pitch/sizeof(uint16_t)) + x]; uint8_t r = (spixel >> 11) & 31; uint8_t g = (spixel >> 5) & 63; @@ -434,4 +436,4 @@ video_driver_t video_switch = { NULL, /* overlay_interface */ #endif switch_get_poke_interface, -}; \ No newline at end of file +}; diff --git a/gfx/drivers/wiiu_gfx.c b/gfx/drivers/wiiu_gfx.c index a129e7fdc5..0f0c3d3389 100644 --- a/gfx/drivers/wiiu_gfx.c +++ b/gfx/drivers/wiiu_gfx.c @@ -53,7 +53,8 @@ static const wiiu_render_mode_t wiiu_render_mode_map[] = {1920, 1080, GX2_TV_RENDER_MODE_WIDE_1080P} /* GX2_TV_SCAN_MODE_1080P */ }; -static void wiiu_set_tex_coords(frame_vertex_t *v, GX2Texture *texture, float u0, float v0, float u1, float v1, +static void wiiu_set_tex_coords(frame_vertex_t *v, GX2Texture *texture, float u0, float v0, + float u1, float v1, unsigned rotation) { v[0].coord.u = u0 / texture->surface.width; @@ -222,6 +223,8 @@ static void *wiiu_gfx_init(const video_info_t *video, }; GX2Init(init_attributes); + wiiu->rgb32 = video->rgb32; + /* setup scanbuffers */ wiiu->render_mode = wiiu_render_mode_map[GX2GetSystemTVScanMode()]; // wiiu->render_mode = wiiu_render_mode_map[GX2_TV_SCAN_MODE_480P]; @@ -263,22 +266,27 @@ static void *wiiu_gfx_init(const video_info_t *video, GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->color_buffer.surface.image, wiiu->color_buffer.surface.imageSize); - wiiu->ctx_state = (GX2ContextState *)MEM2_alloc(sizeof(GX2ContextState), GX2_CONTEXT_STATE_ALIGNMENT); + wiiu->ctx_state = (GX2ContextState *)MEM2_alloc(sizeof(GX2ContextState), + GX2_CONTEXT_STATE_ALIGNMENT); GX2SetupContextStateEx(wiiu->ctx_state, GX2_TRUE); 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); + 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); 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); + GX2_ENABLE, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, + GX2_BLEND_COMBINE_MODE_ADD); GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_DISABLE); GX2InitShader(&frame_shader); + GX2InitShader(&tex_shader); GX2InitShader(&sprite_shader); + GX2InitShader(&ribbon_shader); GX2SetShader(&frame_shader); wiiu->ubo_vp = MEM1_alloc(sizeof(*wiiu->ubo_vp), GX2_UNIFORM_BLOCK_ALIGNMENT); @@ -294,8 +302,10 @@ static void *wiiu_gfx_init(const video_info_t *video, wiiu->ubo_mvp = MEM1_alloc(sizeof(*wiiu->ubo_mvp), GX2_UNIFORM_BLOCK_ALIGNMENT); wiiu_set_projection(wiiu); - wiiu->input_ring_buffer_size = GX2CalcGeometryShaderInputRingBufferSize(sprite_shader.vs.ringItemSize); - wiiu->output_ring_buffer_size = GX2CalcGeometryShaderOutputRingBufferSize(sprite_shader.gs.ringItemSize); + wiiu->input_ring_buffer_size = GX2CalcGeometryShaderInputRingBufferSize( + sprite_shader.vs.ringItemSize); + wiiu->output_ring_buffer_size = GX2CalcGeometryShaderOutputRingBufferSize( + sprite_shader.gs.ringItemSize); wiiu->input_ring_buffer = MEM1_alloc(wiiu->input_ring_buffer_size, 0x1000); wiiu->output_ring_buffer = MEM1_alloc(wiiu->output_ring_buffer_size, 0x1000); @@ -353,13 +363,44 @@ static void *wiiu_gfx_init(const video_info_t *video, wiiu->vertex_cache.v = MEM2_alloc(wiiu->vertex_cache.size * sizeof(*wiiu->vertex_cache.v), GX2_VERTEX_BUFFER_ALIGNMENT); + wiiu->vertex_cache_tex.size = 0x1000; + wiiu->vertex_cache_tex.current = 0; + wiiu->vertex_cache_tex.v = MEM2_alloc(wiiu->vertex_cache_tex.size + * sizeof(*wiiu->vertex_cache_tex.v), GX2_VERTEX_BUFFER_ALIGNMENT); + /* Initialize 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); + for (int i = 0; i < RARCH_WRAP_MAX; i++) + { + switch (i) + { + case RARCH_WRAP_BORDER: + GX2InitSampler(&wiiu->sampler_nearest[i], GX2_TEX_CLAMP_MODE_CLAMP_BORDER, + GX2_TEX_XY_FILTER_MODE_POINT); + GX2InitSampler(&wiiu->sampler_linear[i], GX2_TEX_CLAMP_MODE_CLAMP_BORDER, + GX2_TEX_XY_FILTER_MODE_LINEAR); + break; + + case RARCH_WRAP_EDGE: + GX2InitSampler(&wiiu->sampler_nearest[i], GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT); + GX2InitSampler(&wiiu->sampler_linear[i], GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR); + break; + + case RARCH_WRAP_REPEAT: + GX2InitSampler(&wiiu->sampler_nearest[i], GX2_TEX_CLAMP_MODE_WRAP, GX2_TEX_XY_FILTER_MODE_POINT); + GX2InitSampler(&wiiu->sampler_linear[i], GX2_TEX_CLAMP_MODE_WRAP, GX2_TEX_XY_FILTER_MODE_LINEAR); + break; + + case RARCH_WRAP_MIRRORED_REPEAT: + GX2InitSampler(&wiiu->sampler_nearest[i], GX2_TEX_CLAMP_MODE_MIRROR, GX2_TEX_XY_FILTER_MODE_POINT); + GX2InitSampler(&wiiu->sampler_linear[i], GX2_TEX_CLAMP_MODE_MIRROR, GX2_TEX_XY_FILTER_MODE_LINEAR); + break; + } + } /* set Texture and Sampler */ GX2SetPixelTexture(&wiiu->texture, frame_shader.ps.samplerVars[0].location); - GX2SetPixelSampler(&wiiu->sampler_linear, frame_shader.ps.samplerVars[0].location); + GX2SetPixelSampler(&wiiu->sampler_linear[RARCH_WRAP_DEFAULT], + frame_shader.ps.samplerVars[0].location); /* clear leftover image */ GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.0f, 0.0f, 1.0f); @@ -526,7 +567,8 @@ static void gx2_overlay_set_alpha(void *data, unsigned image, float mod) { gx2->overlay[image].alpha_mod = mod; gx2->overlay[image].v.color = COLOR_RGBA(0xFF, 0xFF, 0xFF, 0xFF * gx2->overlay[image].alpha_mod); - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, &gx2->overlay[image].v, sizeof(gx2->overlay[image].v)); + GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, &gx2->overlay[image].v, + sizeof(gx2->overlay[image].v)); } } @@ -542,7 +584,7 @@ static void gx2_render_overlay(void *data) GX2SetAttribBuffer(0, sizeof(gx2->overlay[i].v), sizeof(gx2->overlay[i].v), &gx2->overlay[i].v); GX2SetPixelTexture(&gx2->overlay[i].tex, sprite_shader.ps.samplerVars[0].location); - GX2SetPixelSampler(&gx2->sampler_linear, sprite_shader.ps.samplerVars[0].location); + GX2SetPixelSampler(&gx2->sampler_linear[RARCH_WRAP_EDGE], sprite_shader.ps.samplerVars[0].location); GX2DrawEx(GX2_PRIMITIVE_MODE_POINTS, 1, 0, 1); @@ -576,13 +618,24 @@ static void wiiu_free_shader_preset(wiiu_video_t *wiiu) for (int i = 0; i < wiiu->shader_preset->passes; i++) { gfd_free(wiiu->pass[i].gfd); - MEM2_free(wiiu->pass[i].vs_ubo); - MEM2_free(wiiu->pass[i].ps_ubo); - MEM1_free(wiiu->pass[i].texture.surface.image); + MEM2_free(wiiu->pass[i].vs_ubos[0]); + MEM2_free(wiiu->pass[i].vs_ubos[1]); + MEM2_free(wiiu->pass[i].ps_ubos[0]); + MEM2_free(wiiu->pass[i].ps_ubos[1]); + if(wiiu->pass[i].mem1) + MEM1_free(wiiu->pass[i].texture.surface.image); + else + MEM2_free(wiiu->pass[i].texture.surface.image); } memset(wiiu->pass, 0, sizeof(wiiu->pass)); + for (int i = 0; i < wiiu->shader_preset->luts; i++) + { + MEM2_free(wiiu->luts[i].surface.image); + wiiu->luts[i].surface.image = NULL; + } + free(wiiu->shader_preset); wiiu->shader_preset = NULL; } @@ -610,7 +663,9 @@ static void wiiu_gfx_free(void *data) GX2SetDRCEnable(GX2_DISABLE); GX2DestroyShader(&frame_shader); + GX2DestroyShader(&tex_shader); GX2DestroyShader(&sprite_shader); + GX2DestroyShader(&ribbon_shader); wiiu_free_shader_preset(wiiu); #ifdef HAVE_OVERLAY @@ -624,6 +679,9 @@ static void wiiu_gfx_free(void *data) MEM2_free(wiiu->v); MEM2_free(wiiu->menu.v); MEM2_free(wiiu->vertex_cache.v); + MEM2_free(wiiu->vertex_cache_tex.v); + MEM2_free(wiiu->menu_display_coord_array); + MEM2_free(wiiu->ribbon_ubo); MEM1_free(wiiu->color_buffer.surface.image); MEM1_free(wiiu->ubo_vp); @@ -641,10 +699,18 @@ static void wiiu_gfx_free(void *data) static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigned height) { MEM2_free(wiiu->texture.surface.image); - if(wiiu->shader_preset) + + if (wiiu->shader_preset) { for (int i = 0; i < wiiu->shader_preset->passes; i++) - MEM1_free(wiiu->pass[i].texture.surface.image); + { + if(wiiu->pass[i].mem1) + MEM1_free(wiiu->pass[i].texture.surface.image); + else + MEM2_free(wiiu->pass[i].texture.surface.image); + + wiiu->pass[i].texture.surface.image = NULL; + } } /* Initialize frame texture */ @@ -655,7 +721,6 @@ static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigne wiiu->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D; wiiu->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED; wiiu->texture.viewNumSlices = 1; - wiiu->rgb32 = wiiu->rgb32; if (wiiu->rgb32) { @@ -677,7 +742,7 @@ static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigne GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->texture.surface.image, wiiu->texture.surface.imageSize); - if(wiiu->shader_preset) + if (wiiu->shader_preset) { for (int i = 0; i < wiiu->shader_preset->passes; i++) { @@ -732,11 +797,13 @@ static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigne wiiu->pass[i].texture.surface.width = width; wiiu->pass[i].texture.surface.height = height; wiiu->pass[i].texture.surface.depth = 1; - // wiiu->pass[i].texture.surface.mipLevels = 1; - wiiu->pass[i].texture.surface.format = pass->fbo.fp_fbo? GX2_SURFACE_FORMAT_FLOAT_R32_G32_B32_A32 : - pass->fbo.srgb_fbo? GX2_SURFACE_FORMAT_SRGB_R8_G8_B8_A8 : - GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; - wiiu->pass[i].texture.surface.use = (GX2_SURFACE_USE_TEXTURE | GX2_SURFACE_USE_COLOR_BUFFER); + // wiiu->pass[i].texture.surface.mipLevels = 1; + wiiu->pass[i].texture.surface.format = pass->fbo.fp_fbo ? + GX2_SURFACE_FORMAT_FLOAT_R32_G32_B32_A32 : + pass->fbo.srgb_fbo ? GX2_SURFACE_FORMAT_SRGB_R8_G8_B8_A8 : + GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; + wiiu->pass[i].texture.surface.use = (GX2_SURFACE_USE_TEXTURE | + GX2_SURFACE_USE_COLOR_BUFFER); wiiu->pass[i].texture.viewNumSlices = 1; wiiu->pass[i].texture.compMap = GX2_COMP_SEL(_R, _G, _B, _A); @@ -744,16 +811,27 @@ static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigne GX2InitTextureRegs(&wiiu->pass[i].texture); - if((i != (wiiu->shader_preset->passes - 1)) || (width != wiiu->vp.width) || (height != wiiu->vp.height)) + if ((i != (wiiu->shader_preset->passes - 1)) || (width != wiiu->vp.width) + || (height != wiiu->vp.height)) { + wiiu->pass[i].mem1 = true; wiiu->pass[i].texture.surface.image = MEM1_alloc(wiiu->pass[i].texture.surface.imageSize, wiiu->pass[i].texture.surface.alignment); if (!wiiu->pass[i].texture.surface.image) { - printf("failed to allocate Render target memory from MEM1. falling back to stock.\n"); - wiiu_free_shader_preset(wiiu); - return false; + printf("failed to allocate Render target memory from MEM1. trying MEM2.\n"); + wiiu->pass[i].mem1 = false; + wiiu->pass[i].texture.surface.image = MEM2_alloc(wiiu->pass[i].texture.surface.imageSize, + wiiu->pass[i].texture.surface.alignment); + + if (!wiiu->pass[i].texture.surface.image) + { + printf("failed to allocate Render target memory from MEM2. falling back to stock.\n"); + + wiiu_free_shader_preset(wiiu); + return false; + } } memset(wiiu->pass[i].texture.surface.image, 0x00, wiiu->pass[i].texture.surface.imageSize); @@ -770,6 +848,147 @@ static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigne return true; } +static void wiiu_gfx_update_uniform_block(wiiu_video_t *wiiu, int pass, float *ubo, int id, + int size, int uniformVarCount, GX2UniformVar *uniformVars, uint64_t frame_count) +{ + for (int i = 0; i < uniformVarCount; i++) + { + if (uniformVars[i].block != id) + continue; + + const char *id = strrchr(uniformVars[i].name, '.'); + + if (!id) + continue; + + id++; + + float *dst = ubo + uniformVars[i].offset; + + if (!strcmp(id, "OutputSize")) + { + ((GX2_vec4 *)dst)->x = wiiu->pass[pass].color_buffer.surface.width; + ((GX2_vec4 *)dst)->y = wiiu->pass[pass].color_buffer.surface.height; + ((GX2_vec4 *)dst)->z = 1.0f / wiiu->pass[pass].color_buffer.surface.width; + ((GX2_vec4 *)dst)->w = 1.0f / wiiu->pass[pass].color_buffer.surface.height; + continue; + } + + if (!strcmp(id, "FinalViewportSize")) + { + ((GX2_vec4 *)dst)->x = wiiu->vp.width; + ((GX2_vec4 *)dst)->y = wiiu->vp.height; + ((GX2_vec4 *)dst)->z = 1.0f / wiiu->vp.width; + ((GX2_vec4 *)dst)->w = 1.0f / wiiu->vp.height; + continue; + } + + if (!strcmp(id, "FrameCount")) + { + *dst = wiiu->shader_preset->pass[pass].frame_count_mod ? + frame_count % wiiu->shader_preset->pass[pass].frame_count_mod : + frame_count; + *(u32 *)dst = __builtin_bswap32(*(u32 *)dst); + continue; + } + + if (!strcmp(id, "OriginalSize")) + { + ((GX2_vec4 *)dst)->x = wiiu->texture.surface.width; + ((GX2_vec4 *)dst)->y = wiiu->texture.surface.height; + ((GX2_vec4 *)dst)->z = 1.0f / wiiu->texture.surface.width; + ((GX2_vec4 *)dst)->w = 1.0f / wiiu->texture.surface.height; + continue; + } + + if (!strcmp(id, "SourceSize")) + { + GX2Surface *source = (pass > 0) ? &wiiu->pass[pass - 1].texture.surface : &wiiu->texture.surface; + ((GX2_vec4 *)dst)->x = source->width; + ((GX2_vec4 *)dst)->y = source->height; + ((GX2_vec4 *)dst)->z = 1.0f / source->width; + ((GX2_vec4 *)dst)->w = 1.0f / source->height; + continue; + } + + if (!strncmp(id, "OriginalHistorySize", strlen("OriginalHistorySize"))) + { + unsigned index = strtoul(id + strlen("OriginalHistorySize"), NULL, 0); + if(index > pass) + index = 0; + + if(index) + index = pass - index; + + GX2Surface *source = (index > 0) ? &wiiu->pass[index - 1].texture.surface : &wiiu->texture.surface; + ((GX2_vec4 *)dst)->x = source->width; + ((GX2_vec4 *)dst)->y = source->height; + ((GX2_vec4 *)dst)->z = 1.0f / source->width; + ((GX2_vec4 *)dst)->w = 1.0f / source->height; + continue; + } + + if ((pass > 0 ) && !strncmp(id, "PassOutputSize", strlen("PassOutputSize"))) + { + unsigned index = strtoul(id + strlen("PassOutputSize"), NULL, 0); + if(index > pass - 1) + index = pass - 1; + GX2Surface *output = &wiiu->pass[index].texture.surface; + ((GX2_vec4 *)dst)->x = output->width; + ((GX2_vec4 *)dst)->y = output->height; + ((GX2_vec4 *)dst)->z = 1.0f / output->width; + ((GX2_vec4 *)dst)->w = 1.0f / output->height; + continue; + } + + /* feedback not supported yet */ + if (!strncmp(id, "PassFeedbackSize", strlen("PassFeedbackSize"))) + { + unsigned index = strtoul(id + strlen("PassFeedbackSize"), NULL, 0); + if(index > wiiu->shader_preset->passes - 1) + index = wiiu->shader_preset->passes - 1; + GX2Surface *output = &wiiu->pass[index].texture.surface; + ((GX2_vec4 *)dst)->x = output->width; + ((GX2_vec4 *)dst)->y = output->height; + ((GX2_vec4 *)dst)->z = 1.0f / output->width; + ((GX2_vec4 *)dst)->w = 1.0f / output->height; + continue; + } + + for (int k = 0; k < wiiu->shader_preset->luts; k++) + { + if (!strncmp(id, wiiu->shader_preset->lut[k].id, strlen(wiiu->shader_preset->lut[k].id)) + && !!strcmp(id + strlen(wiiu->shader_preset->lut[k].id), "Size")) + { + GX2Surface *surface = &wiiu->luts[k].surface; + ((GX2_vec4 *)dst)->x = surface->width; + ((GX2_vec4 *)dst)->y = surface->height; + ((GX2_vec4 *)dst)->z = 1.0f / surface->width; + ((GX2_vec4 *)dst)->w = 1.0f / surface->height; + } + } + + if (!strcmp(id, "MVP")) + { + memcpy(dst, wiiu->ubo_mvp, sizeof(*wiiu->ubo_mvp)); + continue; + } + + + for (int k = 0; k < wiiu->shader_preset->num_parameters; k++) + { + if (!strcmp(id, wiiu->shader_preset->parameters[k].id)) + { + *dst = wiiu->shader_preset->parameters[k].current; + *(u32 *)dst = __builtin_bswap32(*(u32 *)dst); + break; + } + } + + } + + GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, ubo, size); +} static bool wiiu_gfx_frame(void *data, const void *frame, unsigned width, unsigned height, uint64_t frame_count, @@ -842,8 +1061,8 @@ static bool wiiu_gfx_frame(void *data, const void *frame, if (frame) { - if((width != wiiu->texture.surface.width) || - (height != wiiu->texture.surface.height)) + if ((width != wiiu->texture.surface.width) || + (height != wiiu->texture.surface.height)) wiiu_init_frame_textures(wiiu, width, height); wiiu->width = width; @@ -892,105 +1111,134 @@ static bool wiiu_gfx_frame(void *data, const void *frame, GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK); GX2SetFetchShader(&frame_shader.fs); - GX2SetVertexUniformBlock(frame_shader.vs.uniformBlocks[0].offset, frame_shader.vs.uniformBlocks[0].size, wiiu->ubo_mvp); GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->v), sizeof(*wiiu->v), wiiu->v); GX2Texture *texture = &wiiu->texture; + if (wiiu->shader_preset && !wiiu->pass[0].texture.surface.image) + wiiu_init_frame_textures(wiiu, width, height); + if (wiiu->shader_preset) { - if(!wiiu->pass[0].texture.surface.image) - wiiu_init_frame_textures(wiiu, width, height); - for (int i = 0; i < wiiu->shader_preset->passes; i++) { GX2SetVertexShader(wiiu->pass[i].gfd->vs); + + for (int j = 0; j < 2 && j < wiiu->pass[i].gfd->vs->uniformBlockCount; j++) + { + wiiu_gfx_update_uniform_block(wiiu, i, wiiu->pass[i].vs_ubos[j], j, + wiiu->pass[i].gfd->vs->uniformBlocks[j].size, + wiiu->pass[i].gfd->vs->uniformVarCount, wiiu->pass[i].gfd->vs->uniformVars, frame_count); + GX2SetVertexUniformBlock(wiiu->pass[i].gfd->vs->uniformBlocks[j].offset, + wiiu->pass[i].gfd->vs->uniformBlocks[j].size, wiiu->pass[i].vs_ubos[j]); + } + GX2SetPixelShader(wiiu->pass[i].gfd->ps); -// if (wiiu->pass[i].gfd->vs->uniformBlockCount > 0) -// GX2SetVertexUniformBlock(wiiu->pass[i].gfd->vs->uniformBlocks[0].offset, wiiu->pass[i].gfd->vs->uniformBlocks[0].size, wiiu->ubo_mvp); - -// GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->v), sizeof(*wiiu->v), wiiu->v); - -// if(wiiu->pass[i].vs_ubo) -// GX2SetVertexUniformBlock(wiiu->pass[i].gfd->vs->uniformBlocks[1].offset, -// wiiu->pass[i].gfd->vs->uniformBlocks[1].size, -// wiiu->pass[i].vs_ubo); - - if (wiiu->pass[i].ps_ubo) + for (int j = 0; j < 2 && j < wiiu->pass[i].gfd->ps->uniformBlockCount; j++) { - for (int j = 0; j < wiiu->pass[i].gfd->ps->uniformVarCount; j++) + wiiu_gfx_update_uniform_block(wiiu, i, wiiu->pass[i].ps_ubos[j], j, + wiiu->pass[i].gfd->ps->uniformBlocks[j].size, + wiiu->pass[i].gfd->ps->uniformVarCount, wiiu->pass[i].gfd->ps->uniformVars, frame_count); + GX2SetPixelUniformBlock(wiiu->pass[i].gfd->ps->uniformBlocks[j].offset, + wiiu->pass[i].gfd->ps->uniformBlocks[j].size, wiiu->pass[i].ps_ubos[j]); + } + + for (int j = 0; j < wiiu->pass[i].gfd->ps->samplerVarCount; j++) + { + if (!strcmp(wiiu->pass[i].gfd->ps->samplerVars[j].name, "Source")) { - if (wiiu->pass[i].gfd->ps->uniformVars[j].block != 0) - continue; + GX2SetPixelTexture(texture, wiiu->pass[i].gfd->ps->samplerVars[j].location); + GX2SetPixelSampler(wiiu->shader_preset->pass[i].filter ? + &wiiu->sampler_linear[wiiu->shader_preset->pass[i].wrap] : + &wiiu->sampler_nearest[wiiu->shader_preset->pass[i].wrap], + wiiu->pass[i].gfd->ps->samplerVars[j].location); + continue; + } - const char *id = strrchr(wiiu->pass[i].gfd->ps->uniformVars[j].name, '.'); + if (!strcmp(wiiu->pass[i].gfd->ps->samplerVars[j].name, "Original")) + { + GX2SetPixelTexture(&wiiu->texture, wiiu->pass[i].gfd->ps->samplerVars[j].location); + GX2SetPixelSampler(wiiu->shader_preset->pass[0].filter ? + &wiiu->sampler_linear[wiiu->shader_preset->pass[0].wrap] : + &wiiu->sampler_nearest[wiiu->shader_preset->pass[0].wrap], + wiiu->pass[i].gfd->ps->samplerVars[j].location); + continue; + } - if (!id) - continue; + if (!strncmp(wiiu->pass[i].gfd->ps->samplerVars[j].name, "OriginalHistory", strlen("OriginalHistory"))) + { + unsigned index = strtoul(wiiu->pass[i].gfd->ps->samplerVars[j].name + strlen("OriginalHistory"), NULL, 0); + if(index > i) + index = 0; - id++; + if(index) + index = i - index; - float *dst = wiiu->pass[i].ps_ubo + wiiu->pass[i].gfd->ps->uniformVars[j].offset; + GX2Texture *source = (index > 0) ? &wiiu->pass[index - 1].texture : &wiiu->texture; + GX2SetPixelTexture(source, wiiu->pass[i].gfd->ps->samplerVars[j].location); + GX2SetPixelSampler(wiiu->shader_preset->pass[index].filter ? + &wiiu->sampler_linear[wiiu->shader_preset->pass[index].wrap] : + &wiiu->sampler_nearest[wiiu->shader_preset->pass[index].wrap], + wiiu->pass[i].gfd->ps->samplerVars[j].location); + continue; + } - if (!strcmp(id, "OutputSize")) + if ((i > 0) && !strncmp(wiiu->pass[i].gfd->ps->samplerVars[j].name, "PassOutput", strlen("PassOutput"))) + { + unsigned index = strtoul(wiiu->pass[i].gfd->ps->samplerVars[j].name + strlen("PassOutput"), NULL, 0); + if(index > i - 1) + index = i - 1; + GX2SetPixelTexture(&wiiu->pass[index].texture, wiiu->pass[i].gfd->ps->samplerVars[j].location); + GX2SetPixelSampler(wiiu->shader_preset->pass[index].filter ? + &wiiu->sampler_linear[wiiu->shader_preset->pass[index].wrap] : + &wiiu->sampler_nearest[wiiu->shader_preset->pass[index].wrap], + wiiu->pass[i].gfd->ps->samplerVars[j].location); + continue; + } + + /* feedback not supported yet */ + if (!strncmp(wiiu->pass[i].gfd->ps->samplerVars[j].name, "PassFeedback", strlen("PassFeedback"))) + { + unsigned index = strtoul(wiiu->pass[i].gfd->ps->samplerVars[j].name + strlen("PassFeedback"), NULL, 0); + if(index > wiiu->shader_preset->passes - 1) + index = wiiu->shader_preset->passes - 1; + + GX2SetPixelTexture(&wiiu->pass[index].texture, wiiu->pass[i].gfd->ps->samplerVars[j].location); + GX2SetPixelSampler(wiiu->shader_preset->pass[i].filter ? + &wiiu->sampler_linear[wiiu->shader_preset->pass[i].wrap] : + &wiiu->sampler_nearest[wiiu->shader_preset->pass[i].wrap], + wiiu->pass[i].gfd->ps->samplerVars[j].location); + continue; + } + + + + for (int k = 0; k < wiiu->shader_preset->luts; k++) + { + if (wiiu->luts[k].surface.image + && !strcmp(wiiu->pass[i].gfd->ps->samplerVars[j].name, wiiu->shader_preset->lut[k].id)) { - ((GX2_vec4 *)dst)->x = wiiu->pass[i].color_buffer.surface.width; - ((GX2_vec4 *)dst)->y = wiiu->pass[i].color_buffer.surface.height; - ((GX2_vec4 *)dst)->z = 1.0f / wiiu->pass[i].color_buffer.surface.width; - ((GX2_vec4 *)dst)->w = 1.0f / wiiu->pass[i].color_buffer.surface.height; - continue; - } - - if (!strcmp(id, "OriginalSize")) - { - ((GX2_vec4 *)dst)->x = wiiu->texture.surface.width; - ((GX2_vec4 *)dst)->y = wiiu->texture.surface.height; - ((GX2_vec4 *)dst)->z = 1.0f / wiiu->texture.surface.width; - ((GX2_vec4 *)dst)->w = 1.0f / wiiu->texture.surface.height; - continue; - } - - if (!strcmp(id, "SourceSize")) - { - ((GX2_vec4 *)dst)->x = texture->surface.width; - ((GX2_vec4 *)dst)->y = texture->surface.height; - ((GX2_vec4 *)dst)->z = 1.0f / texture->surface.width; - ((GX2_vec4 *)dst)->w = 1.0f / texture->surface.height; - continue; - } - - for (int k = 0; k < wiiu->shader_preset->num_parameters; k++) - { - if (!strcmp(id, wiiu->shader_preset->parameters[k].id)) - { - *dst = wiiu->shader_preset->parameters[k].current; - *(u32 *)dst = __builtin_bswap32(*(u32 *)dst); - break; - } + GX2SetPixelTexture(&wiiu->luts[k], wiiu->pass[i].gfd->ps->samplerVars[j].location); + GX2SetPixelSampler(wiiu->shader_preset->lut[k].filter ? + &wiiu->sampler_linear[wiiu->shader_preset->lut[k].wrap] : + &wiiu->sampler_nearest[wiiu->shader_preset->lut[k].wrap], + wiiu->pass[i].gfd->ps->samplerVars[j].location); } } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].ps_ubo, - wiiu->pass[i].gfd->ps->uniformBlocks[0].size); - - GX2SetPixelUniformBlock(wiiu->pass[i].gfd->ps->uniformBlocks[0].offset, - wiiu->pass[i].gfd->ps->uniformBlocks[0].size, wiiu->pass[i].ps_ubo); } - - GX2SetPixelTexture(texture, wiiu->pass[i].gfd->ps->samplerVars[0].location); - GX2SetPixelSampler(wiiu->shader_preset->pass[i].filter ? &wiiu->sampler_linear : &wiiu->sampler_nearest, - wiiu->pass[i].gfd->ps->samplerVars[0].location); - - if(wiiu->pass[i].color_buffer.surface.image) + if (wiiu->pass[i].color_buffer.surface.image) { GX2SetColorBuffer(&wiiu->pass[i].color_buffer, GX2_RENDER_TARGET_0); - GX2SetViewport(0.0f, 0.0f, wiiu->pass[i].color_buffer.surface.width, wiiu->pass[i].color_buffer.surface.height, 0.0f, + GX2SetViewport(0.0f, 0.0f, wiiu->pass[i].color_buffer.surface.width, + wiiu->pass[i].color_buffer.surface.height, 0.0f, 1.0f); - GX2SetScissor(0, 0, wiiu->pass[i].color_buffer.surface.width, wiiu->pass[i].color_buffer.surface.height); + GX2SetScissor(0, 0, wiiu->pass[i].color_buffer.surface.width, + wiiu->pass[i].color_buffer.surface.height); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); GX2Invalidate(GX2_INVALIDATE_MODE_TEXTURE, wiiu->pass[i].texture.surface.image, @@ -1007,12 +1255,16 @@ static bool wiiu_gfx_frame(void *data, const void *frame, GX2SetColorBuffer(&wiiu->color_buffer, GX2_RENDER_TARGET_0); } - if(texture) + if (texture) { GX2SetVertexShader(&frame_shader.vs); + GX2SetVertexUniformBlock(frame_shader.vs.uniformBlocks[0].offset, + frame_shader.vs.uniformBlocks[0].size, wiiu->ubo_mvp); + GX2SetPixelShader(&frame_shader.ps); GX2SetPixelTexture(texture, frame_shader.ps.samplerVars[0].location); - GX2SetPixelSampler(wiiu->smooth ? &wiiu->sampler_linear : &wiiu->sampler_nearest, + GX2SetPixelSampler(wiiu->smooth ? &wiiu->sampler_linear[RARCH_WRAP_DEFAULT] : + &wiiu->sampler_nearest[RARCH_WRAP_DEFAULT], frame_shader.ps.samplerVars[0].location); } @@ -1020,16 +1272,18 @@ static bool wiiu_gfx_frame(void *data, const void *frame, GX2SetScissor(wiiu->vp.x, wiiu->vp.y, wiiu->vp.width, wiiu->vp.height); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); - GX2SetShaderMode(GX2_SHADER_MODE_GEOMETRY_SHADER); GX2SetShader(&sprite_shader); GX2SetGeometryShaderInputRingBuffer(wiiu->input_ring_buffer, wiiu->input_ring_buffer_size); GX2SetGeometryShaderOutputRingBuffer(wiiu->output_ring_buffer, wiiu->output_ring_buffer_size); - GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[0].offset, sprite_shader.vs.uniformBlocks[0].size, + GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[0].offset, + sprite_shader.vs.uniformBlocks[0].size, wiiu->ubo_vp); - GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[1].offset, sprite_shader.vs.uniformBlocks[1].size, + GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[1].offset, + sprite_shader.vs.uniformBlocks[1].size, wiiu->ubo_tex); - GX2SetViewport(0.0f, 0.0f, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height, 0.0f, 1.0f); + 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); #ifdef HAVE_OVERLAY @@ -1044,15 +1298,18 @@ static bool wiiu_gfx_frame(void *data, const void *frame, GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->menu.v), sizeof(*wiiu->menu.v), wiiu->menu.v); GX2SetPixelTexture(&wiiu->menu.texture, sprite_shader.ps.samplerVars[0].location); - GX2SetPixelSampler(&wiiu->sampler_linear, sprite_shader.ps.samplerVars[0].location); + GX2SetPixelSampler(&wiiu->sampler_linear[RARCH_WRAP_DEFAULT], + sprite_shader.ps.samplerVars[0].location); GX2DrawEx(GX2_PRIMITIVE_MODE_POINTS, 1, 0, 1); } wiiu->vertex_cache.current = 0; + wiiu->vertex_cache_tex.current = 0; GX2SetAttribBuffer(0, wiiu->vertex_cache.size * sizeof(*wiiu->vertex_cache.v), sizeof(*wiiu->vertex_cache.v), wiiu->vertex_cache.v); - GX2SetPixelSampler(&wiiu->sampler_linear, sprite_shader.ps.samplerVars[0].location); + GX2SetPixelSampler(&wiiu->sampler_linear[RARCH_WRAP_EDGE], + sprite_shader.ps.samplerVars[0].location); wiiu->render_msg_enabled = true; @@ -1066,6 +1323,8 @@ static bool wiiu_gfx_frame(void *data, const void *frame, GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, wiiu->vertex_cache.v, wiiu->vertex_cache.current * sizeof(*wiiu->vertex_cache.v)); + GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, + wiiu->vertex_cache_tex.v, wiiu->vertex_cache_tex.current * sizeof(*wiiu->vertex_cache_tex.v)); if (wiiu->menu.enable) GX2DrawDone(); @@ -1177,23 +1436,58 @@ static bool wiiu_gfx_set_shader(void *data, return false; } - if (wiiu->pass[i].gfd->vs->uniformBlockCount > 1) + for (int j = 0; j < 2 && j < wiiu->pass[i].gfd->vs->uniformBlockCount; j++) { - wiiu->pass[i].vs_ubo = MEM2_alloc(wiiu->pass[i].gfd->vs->uniformBlocks[1].size, GX2_UNIFORM_BLOCK_ALIGNMENT); - memset(wiiu->pass[i].vs_ubo, 0, wiiu->pass[i].gfd->vs->uniformBlocks[1].size); - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].vs_ubo, - wiiu->pass[i].gfd->vs->uniformBlocks[1].size); + wiiu->pass[i].vs_ubos[j] = MEM2_alloc(wiiu->pass[i].gfd->vs->uniformBlocks[j].size, + GX2_UNIFORM_BLOCK_ALIGNMENT); + memset(wiiu->pass[i].vs_ubos[j], 0, wiiu->pass[i].gfd->vs->uniformBlocks[j].size); + GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].vs_ubos[j], + wiiu->pass[i].gfd->vs->uniformBlocks[j].size); } - if (wiiu->pass[i].gfd->ps->uniformBlockCount > 0) + for (int j = 0; j < 2 && j < wiiu->pass[i].gfd->ps->uniformBlockCount; j++) { - wiiu->pass[i].ps_ubo = MEM2_alloc(wiiu->pass[i].gfd->ps->uniformBlocks[0].size, GX2_UNIFORM_BLOCK_ALIGNMENT); - memset(wiiu->pass[i].ps_ubo, 0, wiiu->pass[i].gfd->ps->uniformBlocks[0].size); - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].ps_ubo, - wiiu->pass[i].gfd->ps->uniformBlocks[0].size); + wiiu->pass[i].ps_ubos[j] = MEM2_alloc(wiiu->pass[i].gfd->ps->uniformBlocks[j].size, + GX2_UNIFORM_BLOCK_ALIGNMENT); + memset(wiiu->pass[i].ps_ubos[j], 0, wiiu->pass[i].gfd->ps->uniformBlocks[j].size); + GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].ps_ubos[j], + wiiu->pass[i].gfd->ps->uniformBlocks[j].size); } } + for (int i = 0; i < wiiu->shader_preset->luts; i++) + { + struct texture_image image = {}; + + if (image_texture_load(&image, wiiu->shader_preset->lut[i].path)) + { + wiiu->luts[i].surface.width = image.width; + wiiu->luts[i].surface.height = image.height; + wiiu->luts[i].surface.depth = 1; + wiiu->luts[i].surface.dim = GX2_SURFACE_DIM_TEXTURE_2D; + wiiu->luts[i].surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED; + wiiu->luts[i].viewNumSlices = 1; + + wiiu->luts[i].surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; + wiiu->luts[i].compMap = GX2_COMP_SEL(_G, _B, _A, _R); + + GX2CalcSurfaceSizeAndAlignment(&wiiu->luts[i].surface); + GX2InitTextureRegs(&wiiu->luts[i]); + wiiu->luts[i].surface.image = MEM2_alloc(wiiu->luts[i].surface.imageSize, + wiiu->luts[i].surface.alignment); + + for (int j = 0; (j < image.height) && (j < wiiu->luts[i].surface.height); j++) + memcpy((uint32_t *)wiiu->luts[i].surface.image + (j * wiiu->luts[i].surface.pitch), + image.pixels + (j * image.width), image.width * sizeof(image.pixels)); + + GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->luts[i].surface.image, + wiiu->luts[i].surface.imageSize); + + image_texture_free(&image); + } + } + + return true; } diff --git a/gfx/drivers_shader/glslang_util.cpp b/gfx/drivers_shader/glslang_util.cpp index 241866d901..0b0c33d499 100644 --- a/gfx/drivers_shader/glslang_util.cpp +++ b/gfx/drivers_shader/glslang_util.cpp @@ -369,6 +369,12 @@ bool glslang_parse_meta(const vector &lines, glslang_meta *meta) } #ifdef HAVE_VULKAN +#ifdef _MSC_VER +bool glslang_compile_shader(const char *shader_path, glslang_output *output) +{ + return false; +} +#else bool glslang_compile_shader(const char *shader_path, glslang_output *output) { vector lines; @@ -398,3 +404,4 @@ bool glslang_compile_shader(const char *shader_path, glslang_output *output) return true; } #endif +#endif diff --git a/gfx/video_shader_parse.h b/gfx/video_shader_parse.h index cb79c1f09c..ba1cd2f0a4 100644 --- a/gfx/video_shader_parse.h +++ b/gfx/video_shader_parse.h @@ -72,7 +72,8 @@ enum gfx_wrap_type RARCH_WRAP_DEFAULT = RARCH_WRAP_BORDER, RARCH_WRAP_EDGE, RARCH_WRAP_REPEAT, - RARCH_WRAP_MIRRORED_REPEAT + RARCH_WRAP_MIRRORED_REPEAT, + RARCH_WRAP_MAX }; struct gfx_fbo_scale diff --git a/griffin/griffin.c b/griffin/griffin.c index 4f7fc0384a..8143f57739 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -352,6 +352,10 @@ VIDEO DRIVER #endif #endif +#if defined(__wiiu__) +#include "../gfx/drivers/wiiu_gfx.c" +#endif + #ifdef HAVE_SDL2 #include "../gfx/drivers/sdl2_gfx.c" #endif @@ -498,7 +502,7 @@ INPUT #ifdef HAVE_OVERLAY #include "../input/input_overlay.c" -#include "../led/overlay_led_driver.c" +#include "../led/drivers/led_overlay.c" #include "../tasks/task_overlay.c" #endif @@ -527,6 +531,9 @@ INPUT #elif defined(GEKKO) #include "../input/drivers/gx_input.c" #include "../input/drivers_joypad/gx_joypad.c" +#elif defined(__wiiu__) +#include "../input/drivers/wiiu_input.c" +#include "../input/drivers_joypad/wiiu_joypad.c" #elif defined(_XBOX) #include "../input/drivers/xdk_xinput_input.c" #include "../input/drivers_joypad/xdk_joypad.c" @@ -674,10 +681,10 @@ LEDS #include "../led/led_driver.c" -#include "../led/null_led_driver.c" +#include "../led/drivers/led_null.c" #if defined(HAVE_RPILED) -#include "../led/rpi_led_driver.c" +#include "../led/drivers/led_rpi.c" #endif /*============================================================ @@ -706,6 +713,8 @@ AUDIO #include "../audio/drivers/xenon360_audio.c" #elif defined(GEKKO) #include "../audio/drivers/gx_audio.c" +#elif defined(__wiiu__) +#include "../audio/drivers/wiiu_audio.c" #elif defined(EMSCRIPTEN) #include "../audio/drivers/rwebaudio.c" #elif defined(PSP) || defined(VITA) @@ -882,6 +891,8 @@ FRONTEND #ifdef HW_RVL #include "../frontend/drivers/platform_wii.c" #endif +#elif defined(__wiiu__) +#include "../frontend/drivers/platform_wiiu.c" #elif defined(PSP) || defined(VITA) #include "../frontend/drivers/platform_psp.c" #elif defined(_3DS) @@ -1038,7 +1049,7 @@ NETPLAY #include "../libretro-common/net/net_http.c" #include "../libretro-common/net/net_natt.c" #include "../libretro-common/formats/json/jsonsax_full.c" -#ifndef HAVE_SOCKET_LEGACY +#if !defined(HAVE_SOCKET_LEGACY) && !defined(__wiiu__) #include "../libretro-common/net/net_ifinfo.c" #endif #include "../tasks/task_http.c" @@ -1164,7 +1175,7 @@ MENU #include "../menu/drivers/rgui.c" #endif -#if defined(HAVE_OPENGL) || defined(HAVE_VITA2D) || defined(_3DS) || defined(_MSC_VER) +#if defined(HAVE_OPENGL) || defined(HAVE_VITA2D) || defined(_3DS) || defined(_MSC_VER) || defined(__wiiu__) #ifdef HAVE_XMB #include "../menu/drivers/xmb.c" #endif diff --git a/led/null_led_driver.c b/led/drivers/led_null.c similarity index 79% rename from led/null_led_driver.c rename to led/drivers/led_null.c index 08827e7782..3f178a1389 100644 --- a/led/null_led_driver.c +++ b/led/drivers/led_null.c @@ -12,18 +12,17 @@ * If not, see . */ -#include "led_driver.h" -#include "../verbosity.h" +#include "../led_driver.h" +#include "../../verbosity.h" static void null_init(void) { } static void null_free(void) { } -static void null_set(int led,int state) { } +static void null_set(int led, int state) { } -static led_driver_t null_led_driver_ins = { +const led_driver_t null_led_driver = { null_init, null_free, - null_set + null_set, + "null" }; -led_driver_t *null_led_driver = &null_led_driver_ins; - diff --git a/led/overlay_led_driver.c b/led/drivers/led_overlay.c similarity index 69% rename from led/overlay_led_driver.c rename to led/drivers/led_overlay.c index e47066face..f8f7bcd21b 100644 --- a/led/overlay_led_driver.c +++ b/led/drivers/led_overlay.c @@ -1,12 +1,12 @@ #include -#include "led_driver.h" -#include "led_defines.h" +#include "../led_driver.h" +#include "../led_defines.h" -#include "../configuration.h" -#include "../verbosity.h" +#include "../../configuration.h" +#include "../../verbosity.h" -#include "../gfx/video_driver.h" -#include "../input/input_overlay.h" +#include "../../gfx/video_driver.h" +#include "../../input/input_overlay.h" typedef struct { @@ -41,12 +41,12 @@ static void overlay_free(void) RARCH_LOG("[LED]: overlay LED driver free\n"); } -static void overlay_set(int led,int state) +static void overlay_set(int led, int state) { int gpio = 0; if ((led < 0) || (led >= MAX_LEDS)) { - RARCH_WARN("[LED]: invalid led %d\n",led); + RARCH_WARN("[LED]: invalid led %d\n", led); return; } @@ -59,13 +59,12 @@ static void overlay_set(int led,int state) state ? OVERLAY_VISIBILITY_VISIBLE : OVERLAY_VISIBILITY_HIDDEN); - RARCH_LOG("[LED]: set visibility %d %d\n",gpio,state); + RARCH_LOG("[LED]: set visibility %d %d\n", gpio, state); } -static led_driver_t overlay_led_driver_ins = { +const led_driver_t overlay_led_driver = { overlay_init, overlay_free, - overlay_set + overlay_set, + "Overlay" }; - -led_driver_t *overlay_led_driver = &overlay_led_driver_ins; diff --git a/led/rpi_led_driver.c b/led/drivers/led_rpi.c similarity index 75% rename from led/rpi_led_driver.c rename to led/drivers/led_rpi.c index b17600d5f5..d6797fcb98 100644 --- a/led/rpi_led_driver.c +++ b/led/drivers/led_rpi.c @@ -14,11 +14,11 @@ #include -#include "led_driver.h" -#include "led_defines.h" +#include "../led_driver.h" +#include "../led_defines.h" -#include "../configuration.h" -#include "../verbosity.h" +#include "../../configuration.h" +#include "../../verbosity.h" typedef struct { @@ -41,7 +41,7 @@ static void rpi_init(void) { cur->setup[i] = 0; cur->map[i] = settings->uints.led_map[i]; - RARCH_LOG("[LED]: rpi map[%d]=%d\n",i,cur->map[i]); + RARCH_LOG("[LED]: rpi map[%d]=%d\n", i, cur->map[i]); } } @@ -49,20 +49,20 @@ static void rpi_free(void) { } -static int set_gpio(int gpio,int value) +static int set_gpio(int gpio, int value) { FILE *fp; char buf[256]; snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); - fp = fopen(buf,"w"); + fp = fopen(buf, "w"); if(!fp) { - RARCH_WARN("[LED]: failed to set GPIO %d\n",gpio); + RARCH_WARN("[LED]: failed to set GPIO %d\n", gpio); return -1; } - fprintf(fp,"%d\n",value?1:0); + fprintf(fp, "%d\n", value ? 1 : 0); fclose(fp); return 1; } @@ -72,24 +72,24 @@ static int setup_gpio(int gpio) FILE *fp; char buf[256]; snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); - fp = fopen(buf,"w"); + fp = fopen(buf, "w"); if(!fp) { snprintf(buf, sizeof(buf), "/sys/class/gpio/export"); - fp = fopen(buf,"w"); + fp = fopen(buf, "w"); if(!fp) { - RARCH_WARN("[LED]: failed to export GPIO %d\n",gpio); + RARCH_WARN("[LED]: failed to export GPIO %d\n", gpio); return -1; } - fprintf(fp,"%d\n",gpio); + fprintf(fp,"%d\n", gpio); fclose(fp); - snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction",gpio); - fp = fopen(buf,"w"); + snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); + fp = fopen(buf, "w"); } if(!fp) @@ -99,18 +99,18 @@ static int setup_gpio(int gpio) return -1; } - fprintf(fp,"out\n"); + fprintf(fp, "out\n"); fclose(fp); return 1; } -static void rpi_set(int led,int state) +static void rpi_set(int led, int state) { int gpio = 0; if((led < 0) || (led >= MAX_LEDS)) { - RARCH_WARN("[LED]: invalid led %d\n",led); + RARCH_WARN("[LED]: invalid led %d\n", led); return; } @@ -118,7 +118,7 @@ static void rpi_set(int led,int state) if(gpio <= 0) return; - if(cur->setup[led]==0) + if(cur->setup[led] == 0) { RARCH_LOG("[LED]: rpi setup led %d gpio %d\n", led, gpio, state); @@ -133,14 +133,13 @@ static void rpi_set(int led,int state) { RARCH_LOG("[LED]: rpi LED driver set led %d gpio %d = %d\n", led, gpio, state); - set_gpio(gpio,state); + set_gpio(gpio, state); } } -static led_driver_t rpi_led_driver_ins = { +const led_driver_t rpi_led_driver = { rpi_init, rpi_free, - rpi_set + rpi_set, + "rpi" }; - -led_driver_t *rpi_led_driver = &rpi_led_driver_ins; diff --git a/led/led_defines.h b/led/led_defines.h index 3789886c5a..67756a802a 100644 --- a/led/led_defines.h +++ b/led/led_defines.h @@ -12,8 +12,8 @@ * If not, see . */ -#ifndef __OUTPUT_DEFINES__H -#define __OUTPUT_DEFINES__H +#ifndef __LED_DEFINES__H +#define __LED_DEFINES__H #define MAX_LEDS 32 diff --git a/led/led_driver.c b/led/led_driver.c index fb1e796078..185245c6de 100644 --- a/led/led_driver.c +++ b/led/led_driver.c @@ -19,7 +19,7 @@ #include "../configuration.h" #include "../verbosity.h" -static led_driver_t *current_led_driver = NULL; +static const led_driver_t *current_led_driver = NULL; bool led_driver_init(void) { @@ -29,20 +29,20 @@ bool led_driver_init(void) if(!drivername) drivername = (char*)"null"; - current_led_driver = null_led_driver; + current_led_driver = &null_led_driver; #ifdef HAVE_OVERLAY - if(string_is_equal("overlay",drivername)) - current_led_driver = overlay_led_driver; + if(string_is_equal("overlay", drivername)) + current_led_driver = &overlay_led_driver; #endif #if HAVE_RPILED if(string_is_equal("rpi", drivername)) - current_led_driver = rpi_led_driver; + current_led_driver = &rpi_led_driver; #endif RARCH_LOG("[LED]: LED driver = '%s' %p\n", - drivername,current_led_driver); + drivername, current_led_driver); if(current_led_driver) (*current_led_driver->init)(); @@ -56,8 +56,8 @@ void led_driver_free(void) (*current_led_driver->free)(); } -void led_driver_set_led(int led,int value) +void led_driver_set_led(int led, int value) { if(current_led_driver) - (*current_led_driver->set_led)(led,value); + (*current_led_driver->set_led)(led, value); } diff --git a/led/led_driver.h b/led/led_driver.h index 1e6dc8ba0c..916ee95306 100644 --- a/led/led_driver.h +++ b/led/led_driver.h @@ -31,7 +31,8 @@ typedef struct led_driver { void (*init)(void); void (*free)(void); - void (*set_led)(int led,int value); + void (*set_led)(int led, int value); + const char *ident; } led_driver_t; @@ -39,11 +40,11 @@ bool led_driver_init(void); void led_driver_free(void); -void led_driver_set_led(int led,int value); +void led_driver_set_led(int led, int value); -extern led_driver_t *null_led_driver; -extern led_driver_t *overlay_led_driver; -extern led_driver_t *rpi_led_driver; +extern const led_driver_t null_led_driver; +extern const led_driver_t overlay_led_driver; +extern const led_driver_t rpi_led_driver; RETRO_END_DECLS diff --git a/menu/drivers_display/menu_display_wiiu.c b/menu/drivers_display/menu_display_wiiu.c index 514ce091f0..c62c7ba430 100644 --- a/menu/drivers_display/menu_display_wiiu.c +++ b/menu/drivers_display/menu_display_wiiu.c @@ -26,6 +26,7 @@ #include "gfx/font_driver.h" #include "gfx/video_driver.h" #include "gfx/common/gx2_common.h" +#include "wiiu/system/memory.h" #include "wiiu/wiiu_dbg.h" static const float *menu_display_wiiu_get_default_vertices(void) @@ -61,7 +62,6 @@ static void menu_display_wiiu_viewport(void *data) static void menu_display_wiiu_draw(void *data) { - GX2Texture *texture = NULL; wiiu_video_t *wiiu = (wiiu_video_t*)video_driver_get_ptr(false); menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; @@ -69,69 +69,173 @@ static void menu_display_wiiu_draw(void *data) if (!wiiu || !draw) return; - texture = (GX2Texture*)draw->texture; - - if (!texture) - return; - - if (wiiu->vertex_cache.current + 4 > wiiu->vertex_cache.size) - return; - - sprite_vertex_t* v = wiiu->vertex_cache.v + wiiu->vertex_cache.current; - - if(draw->coords->vertex && draw->coords->vertices == 4) + if(draw->pipeline.id) { - v->pos.x = MIN(MIN(MIN(draw->coords->vertex[0], draw->coords->vertex[2]), draw->coords->vertex[4]), draw->coords->vertex[6]); - v->pos.y = 1.0 - MAX(MAX(MAX(draw->coords->vertex[1], draw->coords->vertex[3]), draw->coords->vertex[5]), draw->coords->vertex[7]); - v->pos.width = MAX(MAX(MAX(draw->coords->vertex[0], draw->coords->vertex[2]), draw->coords->vertex[4]), draw->coords->vertex[6]) - v->pos.x; - v->pos.height = 1.0 - MIN(MIN(MIN(draw->coords->vertex[1], draw->coords->vertex[3]), draw->coords->vertex[5]), draw->coords->vertex[7]) - v->pos.y; - v->pos.x *= wiiu->color_buffer.surface.width; - v->pos.y *= wiiu->color_buffer.surface.height; - v->pos.width *= wiiu->color_buffer.surface.width; - v->pos.height *= wiiu->color_buffer.surface.height; + if(draw->pipeline.id != VIDEO_SHADER_MENU) + return; + + GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK); + GX2SetShader(&ribbon_shader); + GX2SetVertexUniformBlock(ribbon_shader.vs.uniformBlocks[0].offset, + ribbon_shader.vs.uniformBlocks[0].size, + wiiu->ribbon_ubo); + GX2SetAttribBuffer(0, draw->coords->vertices * 2 * sizeof(float), 2 * sizeof(float), wiiu->menu_display_coord_array); + GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_ONE, + GX2_BLEND_COMBINE_MODE_ADD, GX2_DISABLE, 0, 0, 0); + + GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLE_STRIP, draw->coords->vertices, 0, 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 if(draw->coords->vertex || draw->coords->color[0] != draw->coords->color[12]) + { + if (wiiu->vertex_cache_tex.current + 4 > wiiu->vertex_cache_tex.size) + return; + + + tex_shader_vertex_t* v = wiiu->vertex_cache_tex.v + wiiu->vertex_cache_tex.current; + + + GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK); + GX2SetShader(&tex_shader); + GX2SetVertexUniformBlock(tex_shader.vs.uniformBlocks[0].offset, + tex_shader.vs.uniformBlocks[0].size, + wiiu->ubo_mvp); + GX2SetAttribBuffer(0, wiiu->vertex_cache_tex.size * sizeof(*wiiu->vertex_cache_tex.v), + sizeof(*wiiu->vertex_cache_tex.v), wiiu->vertex_cache_tex.v); + + if(!draw->coords->vertex) + { + v[0].pos.x = 0.0f; + v[0].pos.y = 1.0f; + v[1].pos.x = 1.0f; + v[1].pos.y = 1.0f; + v[2].pos.x = 0.0f; + v[2].pos.y = 0.0f; + v[3].pos.x = 1.0f; + v[3].pos.y = 0.0f; + } + else + { + v[0].pos.x = draw->coords->vertex[0]; + v[0].pos.y = 1.0 - draw->coords->vertex[1]; + v[1].pos.x = draw->coords->vertex[2]; + v[1].pos.y = 1.0 - draw->coords->vertex[3]; + v[2].pos.x = draw->coords->vertex[4]; + v[2].pos.y = 1.0 - draw->coords->vertex[5]; + v[3].pos.x = draw->coords->vertex[6]; + v[3].pos.y = 1.0 - draw->coords->vertex[7]; + } + + if(!draw->coords->tex_coord) + { + v[0].coord.u = 0.0f; + v[0].coord.v = 1.0f; + v[1].coord.u = 1.0f; + v[1].coord.v = 1.0f; + v[2].coord.u = 0.0f; + v[2].coord.v = 0.0f; + v[3].coord.u = 1.0f; + v[3].coord.v = 0.0f; + } + else + { + v[0].coord.u = draw->coords->tex_coord[0]; + v[0].coord.v = draw->coords->tex_coord[1]; + v[1].coord.u = draw->coords->tex_coord[2]; + v[1].coord.v = draw->coords->tex_coord[3]; + v[2].coord.u = draw->coords->tex_coord[4]; + v[2].coord.v = draw->coords->tex_coord[5]; + v[3].coord.u = draw->coords->tex_coord[6]; + v[3].coord.v = draw->coords->tex_coord[7]; + } + + for(int i = 0; i < 4; i++) + { + v[i].color.r = draw->coords->color[(i << 2) + 0]; + v[i].color.g = draw->coords->color[(i << 2) + 1]; + v[i].color.b = draw->coords->color[(i << 2) + 2]; + v[i].color.a = draw->coords->color[(i << 2) + 3]; + } + + + if(draw->texture) + GX2SetPixelTexture((GX2Texture*)draw->texture, tex_shader.ps.samplerVars[0].location); + + GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLE_STRIP, 4, wiiu->vertex_cache_tex.current, 1); + wiiu->vertex_cache_tex.current += 4; } else { + if (wiiu->vertex_cache.current + 1 > wiiu->vertex_cache.size) + return; + + sprite_vertex_t* v = wiiu->vertex_cache.v + wiiu->vertex_cache.current; v->pos.x = draw->x; v->pos.y = wiiu->color_buffer.surface.height - draw->y - draw->height; v->pos.width = draw->width; v->pos.height = draw->height; - } - if(draw->coords->tex_coord && draw->coords->vertices == 4) - { - v->coord.u = MIN(MIN(MIN(draw->coords->tex_coord[0], draw->coords->tex_coord[2]), draw->coords->tex_coord[4]), draw->coords->tex_coord[6]); - v->coord.v = MIN(MIN(MIN(draw->coords->tex_coord[1], draw->coords->tex_coord[3]), draw->coords->tex_coord[5]), draw->coords->tex_coord[7]); - v->coord.width = MAX(MAX(MAX(draw->coords->tex_coord[0], draw->coords->tex_coord[2]), draw->coords->tex_coord[4]), draw->coords->tex_coord[6]) - v->coord.u; - v->coord.height = MAX(MAX(MAX(draw->coords->tex_coord[1], draw->coords->tex_coord[3]), draw->coords->tex_coord[5]), draw->coords->tex_coord[7]) - v->coord.v; - } - else - { v->coord.u = 0.0f; v->coord.v = 0.0f; v->coord.width = 1.0f; v->coord.height = 1.0f; + + v->color = COLOR_RGBA(0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1], + 0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]); + + if(draw->texture) + GX2SetPixelTexture((GX2Texture*)draw->texture, sprite_shader.ps.samplerVars[0].location); + + GX2DrawEx(GX2_PRIMITIVE_MODE_POINTS, 1, wiiu->vertex_cache.current, 1); + wiiu->vertex_cache.current ++; + return; } - v->color = COLOR_RGBA(0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1], - 0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]); - GX2SetPixelTexture(texture, sprite_shader.ps.samplerVars[0].location); - - GX2DrawEx(GX2_PRIMITIVE_MODE_POINTS, 1, wiiu->vertex_cache.current, 1); - -#if 0 - printf("(%i,%i,%i,%i) , (%i,%i)\n", (int)draw->x, - (int)draw->y, (int)draw->width, (int)draw->height, - texture->surface.width, texture->surface.height); -#endif - - wiiu->vertex_cache.current ++; + GX2SetShaderMode(GX2_SHADER_MODE_GEOMETRY_SHADER); + GX2SetShader(&sprite_shader); +// GX2SetGeometryShaderInputRingBuffer(wiiu->input_ring_buffer, wiiu->input_ring_buffer_size); +// GX2SetGeometryShaderOutputRingBuffer(wiiu->output_ring_buffer, wiiu->output_ring_buffer_size); + GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[0].offset, + sprite_shader.vs.uniformBlocks[0].size, + wiiu->ubo_vp); + GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[1].offset, + sprite_shader.vs.uniformBlocks[1].size, + wiiu->ubo_tex); + GX2SetAttribBuffer(0, wiiu->vertex_cache.size * sizeof(*wiiu->vertex_cache.v), + sizeof(*wiiu->vertex_cache.v), wiiu->vertex_cache.v); } static void menu_display_wiiu_draw_pipeline(void *data) { + menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; + wiiu_video_t *wiiu = (wiiu_video_t*)video_driver_get_ptr(false); + + video_coord_array_t *ca = NULL; + + if (!wiiu || !draw || draw->pipeline.id != VIDEO_SHADER_MENU) + return; + + ca = menu_display_get_coords_array(); + if(!wiiu->menu_display_coord_array) + { + wiiu->menu_display_coord_array = MEM2_alloc(ca->coords.vertices * 2 * sizeof(float), GX2_VERTEX_BUFFER_ALIGNMENT); + memcpy(wiiu->menu_display_coord_array, ca->coords.vertex, ca->coords.vertices * 2 * sizeof(float)); + wiiu->ribbon_ubo = MEM2_alloc(sizeof(*wiiu->ribbon_ubo), GX2_UNIFORM_BLOCK_ALIGNMENT); + wiiu->ribbon_ubo->time = 0.0f; + GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, wiiu->menu_display_coord_array, ca->coords.vertices * 2 * sizeof(float)); + } + + draw->coords->vertex = wiiu->menu_display_coord_array; + draw->coords->vertices = ca->coords.vertices; + + wiiu->ribbon_ubo->time += 0.01; + GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->ribbon_ubo, sizeof(*wiiu->ribbon_ubo)); } static void menu_display_wiiu_restore_clear_color(void) diff --git a/pkg/msvc/RetroArch-msvc2017.sln b/pkg/msvc/RetroArch-msvc2017.sln index 31c8e476ac..a6526f5447 100644 --- a/pkg/msvc/RetroArch-msvc2017.sln +++ b/pkg/msvc/RetroArch-msvc2017.sln @@ -1,34 +1,40 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2015 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-msvc2017", "msvc-2017\RetroArch-msvc2017.vcxproj", "{27FF7CE1-4059-4AA1-8062-FD529560FA54}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug Cg|Win32 = Debug Cg|Win32 - Debug Cg|x64 = Debug Cg|x64 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release Cg|Win32 = Release Cg|Win32 - Release Cg|x64 = Release Cg|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|Win32.ActiveCfg = Debug Cg|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|Win32.Build.0 = Debug Cg|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x64.ActiveCfg = Debug Cg|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.ActiveCfg = Debug|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.Build.0 = Debug|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x64.ActiveCfg = Debug|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|Win32.ActiveCfg = Release Cg|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|Win32.Build.0 = Release Cg|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x64.ActiveCfg = Release Cg|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.ActiveCfg = Release|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.Build.0 = Release|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x64.ActiveCfg = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.9 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-msvc2017", "msvc-2017\RetroArch-msvc2017.vcxproj", "{27FF7CE1-4059-4AA1-8062-FD529560FA54}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug Cg|x64 = Debug Cg|x64 + Debug Cg|x86 = Debug Cg|x86 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release Cg|x64 = Release Cg|x64 + Release Cg|x86 = Release Cg|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x64.ActiveCfg = Debug Cg|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x64.Build.0 = Debug Cg|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x86.ActiveCfg = Debug Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x86.Build.0 = Debug Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x64.ActiveCfg = Debug|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x64.Build.0 = Debug|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x86.ActiveCfg = Debug|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x86.Build.0 = Debug|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x64.ActiveCfg = Release Cg|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x64.Build.0 = Release Cg|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x86.ActiveCfg = Release Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x86.Build.0 = Release Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x64.ActiveCfg = Release|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x64.Build.0 = Release|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x86.ActiveCfg = Release|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj index 5b77affb19..62c4ebf658 100644 --- a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj +++ b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj @@ -191,7 +191,7 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_VULKAN;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -210,7 +210,7 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -230,7 +230,7 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_VULKAN;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -249,7 +249,7 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -271,7 +271,7 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_VULKAN;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -295,7 +295,7 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -320,7 +320,7 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_VULKAN;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -344,7 +344,7 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -380,4 +380,4 @@ - + \ No newline at end of file diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 64c07d20ad..52f32a37dd 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -273,13 +273,11 @@ fi if [ "$HAVE_FLAC" = 'no' ]; then HAVE_BUILTINFLAC=no -elif [ "$HAVE_BUILTINFLAC" = 'yes' ]; then - HAVE_FLAC=yes -else - check_pkgconf FLAC flac - check_val '' FLAC '-lFLAC' fi +check_pkgconf FLAC flac +check_val '' FLAC '-lFLAC' + check_pkgconf LIBUSB libusb-1.0 1.0.13 check_val '' LIBUSB -lusb-1.0 libusb-1.0 diff --git a/record/record_driver.h b/record/record_driver.h index 8a4da8e44c..a8b087163a 100644 --- a/record/record_driver.h +++ b/record/record_driver.h @@ -84,7 +84,7 @@ typedef struct record_driver { void *(*init)(const struct ffemu_params *params); void (*free)(void *data); - bool (*push_video)(void *data,const struct ffemu_video_data *video_data); + bool (*push_video)(void *data, const struct ffemu_video_data *video_data); bool (*push_audio)(void *data, const struct ffemu_audio_data *audio_data); bool (*finalize)(void *data); const char *ident; diff --git a/retroarch.c b/retroarch.c index af98194dc9..bb56980c44 100644 --- a/retroarch.c +++ b/retroarch.c @@ -230,7 +230,6 @@ static bool runloop_remaps_game_active = false; static bool runloop_game_options_active = false; static bool runloop_missing_bios = false; static bool runloop_autosave = false; -static bool runloop_had_hard_sync = false; static rarch_system_info_t runloop_system; static struct retro_frame_time_callback runloop_frame_time; @@ -2802,18 +2801,6 @@ static enum runloop_state runloop_check_state( runloop_msg_queue_push( msg_hash_to_str(MSG_FAST_FORWARD), 1, 1, false); - /* Disable gpu hard sync in fast forward state for speed. */ - if (runloop_fastmotion && settings->bools.video_hard_sync) - { - settings->bools.video_hard_sync = false; - runloop_had_hard_sync = true; - } - else if (!runloop_fastmotion && runloop_had_hard_sync) - { - settings->bools.video_hard_sync = true; - runloop_had_hard_sync = false; - } - old_button_state = new_button_state; old_hold_button_state = new_hold_button_state; } diff --git a/translation/drivers/translation_cached_google.c b/translation/drivers/translation_cached_google.c new file mode 100644 index 0000000000..0e694b1128 --- /dev/null +++ b/translation/drivers/translation_cached_google.c @@ -0,0 +1,28 @@ +#include "../translation_driver.h" + +static void* translation_cached_google_init(const struct translation_driver_info *params) +{ + return NULL; +} + +static void translation_cached_google_free(void* data) +{ +} + +static char* translation_cached_google_translate_text(const char* game_text) +{ + return ""; +} + +static char* translation_cached_google_translate_image(struct ocr_image_info image) +{ + return ""; +} + +const translation_driver_t translation_cached_google = { + translation_cached_google_init, + translation_cached_google_free, + translation_cached_google_translate_text, + translation_cached_google_translate_image, + "cached_google" +}; \ No newline at end of file diff --git a/translation/drivers/translation_null.c b/translation/drivers/translation_null.c new file mode 100644 index 0000000000..deea614d98 --- /dev/null +++ b/translation/drivers/translation_null.c @@ -0,0 +1,23 @@ +#include "../translation_driver.h" + +static void* translation_null_init(const struct translation_driver_info *params) +{ + return NULL; +} + +static void translation_null_free(void* data) +{ +} + +static char* translation_null_translate_text(const char* game_text) +{ + return ""; +} + +const translation_driver_t translation_null = { + translation_null_init, + translation_null_free, + translation_null_translate_text, + NULL, + "null" +}; \ No newline at end of file diff --git a/translation/drivers_ocr/ocr_null.c b/translation/drivers_ocr/ocr_null.c new file mode 100644 index 0000000000..3ffd874ea2 --- /dev/null +++ b/translation/drivers_ocr/ocr_null.c @@ -0,0 +1,22 @@ +#include "../ocr_driver.h" + +static void* ocr_null_init() +{ + return NULL; +} + +static void ocr_null_free(void* data) +{ +} + +char* ocr_null_get_text(struct ocr_image_info image) +{ + return ""; +} + +const ocr_driver_t ocr_null = { + ocr_null_init, + ocr_null_free, + ocr_null_get_text, + "null" +}; \ No newline at end of file diff --git a/translation/drivers_ocr/ocr_tesseract.c b/translation/drivers_ocr/ocr_tesseract.c new file mode 100644 index 0000000000..9b0157a7bc --- /dev/null +++ b/translation/drivers_ocr/ocr_tesseract.c @@ -0,0 +1,22 @@ +#include "../ocr_driver.h" + +static void* ocr_tesseract_init() +{ + return NULL; +} + +static void ocr_tesseract_free(void* data) +{ +} + +char* ocr_tesseract_get_text(struct ocr_image_info image) +{ + return ""; +} + +const ocr_driver_t ocr_tesseract = { + ocr_tesseract_init, + ocr_tesseract_free, + ocr_tesseract_get_text, + "tesseract" +}; \ No newline at end of file diff --git a/translation/drivers_ocr/tesseract/capi.h b/translation/drivers_ocr/tesseract/capi.h new file mode 100644 index 0000000000..8195c68f12 --- /dev/null +++ b/translation/drivers_ocr/tesseract/capi.h @@ -0,0 +1,397 @@ +/////////////////////////////////////////////////////////////////////// +// File: capi.h +// Description: C-API TessBaseAPI +// +// (C) Copyright 2012, Google Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +/////////////////////////////////////////////////////////////////////// + +#ifndef API_CAPI_H_ +#define API_CAPI_H_ + +#ifdef TESS_CAPI_INCLUDE_BASEAPI +# include "baseapi.h" +# include "pageiterator.h" +# include "resultiterator.h" +# include "renderer.h" +#else +# include "platform.h" +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TESS_CALL +# if defined(WIN32) +# define TESS_CALL __cdecl +# else +# define TESS_CALL +# endif +#endif + +#ifndef BOOL +# define BOOL int +# define TRUE 1 +# define FALSE 0 +#endif + +#ifdef TESS_CAPI_INCLUDE_BASEAPI +typedef tesseract::TessResultRenderer TessResultRenderer; +typedef tesseract::TessTextRenderer TessTextRenderer; +typedef tesseract::TessHOcrRenderer TessHOcrRenderer; +typedef tesseract::TessPDFRenderer TessPDFRenderer; +typedef tesseract::TessUnlvRenderer TessUnlvRenderer; +typedef tesseract::TessBoxTextRenderer TessBoxTextRenderer; +typedef tesseract::TessBaseAPI TessBaseAPI; +typedef tesseract::PageIterator TessPageIterator; +typedef tesseract::ResultIterator TessResultIterator; +typedef tesseract::MutableIterator TessMutableIterator; +typedef tesseract::ChoiceIterator TessChoiceIterator; +typedef tesseract::OcrEngineMode TessOcrEngineMode; +typedef tesseract::PageSegMode TessPageSegMode; +typedef tesseract::ImageThresholder TessImageThresholder; +typedef tesseract::PageIteratorLevel TessPageIteratorLevel; +typedef tesseract::DictFunc TessDictFunc; +typedef tesseract::ProbabilityInContextFunc TessProbabilityInContextFunc; +// typedef tesseract::ParamsModelClassifyFunc TessParamsModelClassifyFunc; +typedef tesseract::FillLatticeFunc TessFillLatticeFunc; +typedef tesseract::Dawg TessDawg; +typedef tesseract::TruthCallback TessTruthCallback; +typedef tesseract::Orientation TessOrientation; +typedef tesseract::ParagraphJustification TessParagraphJustification; +typedef tesseract::WritingDirection TessWritingDirection; +typedef tesseract::TextlineOrder TessTextlineOrder; +typedef PolyBlockType TessPolyBlockType; +#else +typedef struct TessResultRenderer TessResultRenderer; +typedef struct TessTextRenderer TessTextRenderer; +typedef struct TessHOcrRenderer TessHOcrRenderer; +typedef struct TessPDFRenderer TessPDFRenderer; +typedef struct TessUnlvRenderer TessUnlvRenderer; +typedef struct TessBoxTextRenderer TessBoxTextRenderer; +typedef struct TessBaseAPI TessBaseAPI; +typedef struct TessPageIterator TessPageIterator; +typedef struct TessResultIterator TessResultIterator; +typedef struct TessMutableIterator TessMutableIterator; +typedef struct TessChoiceIterator TessChoiceIterator; +typedef enum TessOcrEngineMode { OEM_TESSERACT_ONLY, OEM_LSTM_ONLY, OEM_TESSERACT_LSTM_COMBINED, OEM_DEFAULT } TessOcrEngineMode; +typedef enum TessPageSegMode { PSM_OSD_ONLY, PSM_AUTO_OSD, PSM_AUTO_ONLY, PSM_AUTO, PSM_SINGLE_COLUMN, PSM_SINGLE_BLOCK_VERT_TEXT, + PSM_SINGLE_BLOCK, PSM_SINGLE_LINE, PSM_SINGLE_WORD, PSM_CIRCLE_WORD, PSM_SINGLE_CHAR, PSM_SPARSE_TEXT, + PSM_SPARSE_TEXT_OSD, PSM_COUNT } TessPageSegMode; +typedef enum TessPageIteratorLevel { RIL_BLOCK, RIL_PARA, RIL_TEXTLINE, RIL_WORD, RIL_SYMBOL} TessPageIteratorLevel; +typedef enum TessPolyBlockType { PT_UNKNOWN, PT_FLOWING_TEXT, PT_HEADING_TEXT, PT_PULLOUT_TEXT, PT_EQUATION, PT_INLINE_EQUATION, + PT_TABLE, PT_VERTICAL_TEXT, PT_CAPTION_TEXT, PT_FLOWING_IMAGE, PT_HEADING_IMAGE, + PT_PULLOUT_IMAGE, PT_HORZ_LINE, PT_VERT_LINE, PT_NOISE, PT_COUNT } TessPolyBlockType; +typedef enum TessOrientation { ORIENTATION_PAGE_UP, ORIENTATION_PAGE_RIGHT, ORIENTATION_PAGE_DOWN, ORIENTATION_PAGE_LEFT } TessOrientation; +typedef enum TessParagraphJustification { JUSTIFICATION_UNKNOWN, JUSTIFICATION_LEFT, JUSTIFICATION_CENTER, JUSTIFICATION_RIGHT } TessParagraphJustification; +typedef enum TessWritingDirection { WRITING_DIRECTION_LEFT_TO_RIGHT, WRITING_DIRECTION_RIGHT_TO_LEFT, WRITING_DIRECTION_TOP_TO_BOTTOM } TessWritingDirection; +typedef enum TessTextlineOrder { TEXTLINE_ORDER_LEFT_TO_RIGHT, TEXTLINE_ORDER_RIGHT_TO_LEFT, TEXTLINE_ORDER_TOP_TO_BOTTOM } TessTextlineOrder; +typedef struct ETEXT_DESC ETEXT_DESC; +#endif + +struct Pix; +struct Boxa; +struct Pixa; + +/* General free functions */ + +TESS_API const char* + TESS_CALL TessVersion(); +TESS_API void TESS_CALL TessDeleteText(char* text); +TESS_API void TESS_CALL TessDeleteTextArray(char** arr); +TESS_API void TESS_CALL TessDeleteIntArray(int* arr); +#ifdef TESS_CAPI_INCLUDE_BASEAPI +TESS_API void TESS_CALL TessDeleteBlockList(BLOCK_LIST* block_list); +#endif + +/* Renderer API */ +TESS_API TessResultRenderer* TESS_CALL TessTextRendererCreate(const char* outputbase); +TESS_API TessResultRenderer* TESS_CALL TessHOcrRendererCreate(const char* outputbase); +TESS_API TessResultRenderer* TESS_CALL TessHOcrRendererCreate2(const char* outputbase, BOOL font_info); +TESS_API TessResultRenderer* TESS_CALL TessPDFRendererCreate(const char* outputbase, const char* datadir, + BOOL textonly); +TESS_API TessResultRenderer* TESS_CALL TessUnlvRendererCreate(const char* outputbase); +TESS_API TessResultRenderer* TESS_CALL TessBoxTextRendererCreate(const char* outputbase); + +TESS_API void TESS_CALL TessDeleteResultRenderer(TessResultRenderer* renderer); +TESS_API void TESS_CALL TessResultRendererInsert(TessResultRenderer* renderer, TessResultRenderer* next); +TESS_API TessResultRenderer* + TESS_CALL TessResultRendererNext(TessResultRenderer* renderer); +TESS_API BOOL TESS_CALL TessResultRendererBeginDocument(TessResultRenderer* renderer, const char* title); +TESS_API BOOL TESS_CALL TessResultRendererAddImage(TessResultRenderer* renderer, TessBaseAPI* api); +TESS_API BOOL TESS_CALL TessResultRendererEndDocument(TessResultRenderer* renderer); + +TESS_API const char* TESS_CALL TessResultRendererExtention(TessResultRenderer* renderer); +TESS_API const char* TESS_CALL TessResultRendererTitle(TessResultRenderer* renderer); +TESS_API int TESS_CALL TessResultRendererImageNum(TessResultRenderer* renderer); + +/* Base API */ + +TESS_API TessBaseAPI* + TESS_CALL TessBaseAPICreate(); +TESS_API void TESS_CALL TessBaseAPIDelete(TessBaseAPI* handle); + +TESS_API size_t TESS_CALL TessBaseAPIGetOpenCLDevice(TessBaseAPI* handle, void **device); + +TESS_API void TESS_CALL TessBaseAPISetInputName( TessBaseAPI* handle, const char* name); +TESS_API const char* TESS_CALL TessBaseAPIGetInputName(TessBaseAPI* handle); + +TESS_API void TESS_CALL TessBaseAPISetInputImage(TessBaseAPI* handle, struct Pix* pix); +TESS_API struct Pix* TESS_CALL TessBaseAPIGetInputImage(TessBaseAPI* handle); + +TESS_API int TESS_CALL TessBaseAPIGetSourceYResolution(TessBaseAPI* handle); +TESS_API const char* TESS_CALL TessBaseAPIGetDatapath(TessBaseAPI* handle); + +TESS_API void TESS_CALL TessBaseAPISetOutputName(TessBaseAPI* handle, const char* name); + +TESS_API BOOL TESS_CALL TessBaseAPISetVariable(TessBaseAPI* handle, const char* name, const char* value); +TESS_API BOOL TESS_CALL TessBaseAPISetDebugVariable(TessBaseAPI* handle, const char* name, const char* value); + +TESS_API BOOL TESS_CALL TessBaseAPIGetIntVariable( const TessBaseAPI* handle, const char* name, int* value); +TESS_API BOOL TESS_CALL TessBaseAPIGetBoolVariable( const TessBaseAPI* handle, const char* name, BOOL* value); +TESS_API BOOL TESS_CALL TessBaseAPIGetDoubleVariable(const TessBaseAPI* handle, const char* name, double* value); +TESS_API const char* + TESS_CALL TessBaseAPIGetStringVariable(const TessBaseAPI* handle, const char* name); + +TESS_API void TESS_CALL TessBaseAPIPrintVariables( const TessBaseAPI* handle, FILE* fp); +TESS_API BOOL TESS_CALL TessBaseAPIPrintVariablesToFile(const TessBaseAPI* handle, const char* filename); +#ifdef TESS_CAPI_INCLUDE_BASEAPI +TESS_API BOOL TESS_CALL TessBaseAPIGetVariableAsString(TessBaseAPI* handle, const char* name, STRING* val); +#endif + +#ifdef TESS_CAPI_INCLUDE_BASEAPI +TESS_API int TESS_CALL TessBaseAPIInit(TessBaseAPI* handle, const char* datapath, const char* language, + TessOcrEngineMode mode, char** configs, int configs_size, + const STRING* vars_vec, size_t vars_vec_size, + const STRING* vars_values, size_t vars_values_size, BOOL set_only_init_params); +#endif +TESS_API int TESS_CALL TessBaseAPIInit1(TessBaseAPI* handle, const char* datapath, const char* language, TessOcrEngineMode oem, + char** configs, int configs_size); +TESS_API int TESS_CALL TessBaseAPIInit2(TessBaseAPI* handle, const char* datapath, const char* language, TessOcrEngineMode oem); +TESS_API int TESS_CALL TessBaseAPIInit3(TessBaseAPI* handle, const char* datapath, const char* language); + +TESS_API int TESS_CALL TessBaseAPIInit4(TessBaseAPI* handle, const char* datapath, const char* language, TessOcrEngineMode mode, + char** configs, int configs_size, + char** vars_vec, char** vars_values, size_t vars_vec_size, + BOOL set_only_non_debug_params); + +TESS_API const char* + TESS_CALL TessBaseAPIGetInitLanguagesAsString(const TessBaseAPI* handle); +TESS_API char** + TESS_CALL TessBaseAPIGetLoadedLanguagesAsVector(const TessBaseAPI* handle); +TESS_API char** + TESS_CALL TessBaseAPIGetAvailableLanguagesAsVector(const TessBaseAPI* handle); + +TESS_API int TESS_CALL TessBaseAPIInitLangMod(TessBaseAPI* handle, const char* datapath, const char* language); +TESS_API void TESS_CALL TessBaseAPIInitForAnalysePage(TessBaseAPI* handle); + +TESS_API void TESS_CALL TessBaseAPIReadConfigFile(TessBaseAPI* handle, const char* filename); +TESS_API void TESS_CALL TessBaseAPIReadDebugConfigFile(TessBaseAPI* handle, const char* filename); + +TESS_API void TESS_CALL TessBaseAPISetPageSegMode(TessBaseAPI* handle, TessPageSegMode mode); +TESS_API TessPageSegMode + TESS_CALL TessBaseAPIGetPageSegMode(const TessBaseAPI* handle); + +TESS_API char* TESS_CALL TessBaseAPIRect(TessBaseAPI* handle, const unsigned char* imagedata, + int bytes_per_pixel, int bytes_per_line, + int left, int top, int width, int height); + +TESS_API void TESS_CALL TessBaseAPIClearAdaptiveClassifier(TessBaseAPI* handle); + +TESS_API void TESS_CALL TessBaseAPISetImage(TessBaseAPI* handle, const unsigned char* imagedata, int width, int height, + int bytes_per_pixel, int bytes_per_line); +TESS_API void TESS_CALL TessBaseAPISetImage2(TessBaseAPI* handle, struct Pix* pix); + +TESS_API void TESS_CALL TessBaseAPISetSourceResolution(TessBaseAPI* handle, int ppi); + +TESS_API void TESS_CALL TessBaseAPISetRectangle(TessBaseAPI* handle, int left, int top, int width, int height); + +#ifdef TESS_CAPI_INCLUDE_BASEAPI +TESS_API void TESS_CALL TessBaseAPISetThresholder(TessBaseAPI* handle, TessImageThresholder* thresholder); +#endif + +TESS_API struct Pix* + TESS_CALL TessBaseAPIGetThresholdedImage( TessBaseAPI* handle); +TESS_API struct Boxa* + TESS_CALL TessBaseAPIGetRegions( TessBaseAPI* handle, struct Pixa** pixa); +TESS_API struct Boxa* + TESS_CALL TessBaseAPIGetTextlines( TessBaseAPI* handle, struct Pixa** pixa, int** blockids); +TESS_API struct Boxa* + TESS_CALL TessBaseAPIGetTextlines1( TessBaseAPI* handle, const BOOL raw_image, const int raw_padding, + struct Pixa** pixa, int** blockids, int** paraids); +TESS_API struct Boxa* + TESS_CALL TessBaseAPIGetStrips( TessBaseAPI* handle, struct Pixa** pixa, int** blockids); +TESS_API struct Boxa* + TESS_CALL TessBaseAPIGetWords( TessBaseAPI* handle, struct Pixa** pixa); +TESS_API struct Boxa* + TESS_CALL TessBaseAPIGetConnectedComponents(TessBaseAPI* handle, struct Pixa** cc); +TESS_API struct Boxa* + TESS_CALL TessBaseAPIGetComponentImages( TessBaseAPI* handle, const TessPageIteratorLevel level, const BOOL text_only, + struct Pixa** pixa, int** blockids); +TESS_API struct Boxa* + TESS_CALL TessBaseAPIGetComponentImages1( TessBaseAPI* handle, const TessPageIteratorLevel level, const BOOL text_only, + const BOOL raw_image, const int raw_padding, + struct Pixa** pixa, int** blockids, int** paraids); + +TESS_API int TESS_CALL TessBaseAPIGetThresholdedImageScaleFactor(const TessBaseAPI* handle); + +TESS_API void TESS_CALL TessBaseAPIDumpPGM(TessBaseAPI* handle, const char* filename); + +TESS_API TessPageIterator* + TESS_CALL TessBaseAPIAnalyseLayout(TessBaseAPI* handle); + +TESS_API int TESS_CALL TessBaseAPIRecognize(TessBaseAPI* handle, ETEXT_DESC* monitor); +TESS_API int TESS_CALL TessBaseAPIRecognizeForChopTest(TessBaseAPI* handle, ETEXT_DESC* monitor); +TESS_API BOOL TESS_CALL TessBaseAPIProcessPages(TessBaseAPI* handle, const char* filename, const char* retry_config, + int timeout_millisec, TessResultRenderer* renderer); +TESS_API BOOL TESS_CALL TessBaseAPIProcessPage(TessBaseAPI* handle, struct Pix* pix, int page_index, const char* filename, + const char* retry_config, int timeout_millisec, TessResultRenderer* renderer); + +TESS_API TessResultIterator* + TESS_CALL TessBaseAPIGetIterator(TessBaseAPI* handle); +TESS_API TessMutableIterator* + TESS_CALL TessBaseAPIGetMutableIterator(TessBaseAPI* handle); + +TESS_API char* TESS_CALL TessBaseAPIGetUTF8Text(TessBaseAPI* handle); +TESS_API char* TESS_CALL TessBaseAPIGetHOCRText(TessBaseAPI* handle, int page_number); +TESS_API char* TESS_CALL TessBaseAPIGetBoxText(TessBaseAPI* handle, int page_number); +TESS_API char* TESS_CALL TessBaseAPIGetUNLVText(TessBaseAPI* handle); +TESS_API int TESS_CALL TessBaseAPIMeanTextConf(TessBaseAPI* handle); +TESS_API int* TESS_CALL TessBaseAPIAllWordConfidences(TessBaseAPI* handle); +TESS_API BOOL TESS_CALL TessBaseAPIAdaptToWordStr(TessBaseAPI* handle, TessPageSegMode mode, const char* wordstr); + +TESS_API void TESS_CALL TessBaseAPIClear(TessBaseAPI* handle); +TESS_API void TESS_CALL TessBaseAPIEnd(TessBaseAPI* handle); + +TESS_API int TESS_CALL TessBaseAPIIsValidWord(TessBaseAPI* handle, const char* word); +TESS_API BOOL TESS_CALL TessBaseAPIGetTextDirection(TessBaseAPI* handle, int* out_offset, float* out_slope); + +#ifdef TESS_CAPI_INCLUDE_BASEAPI +TESS_API void TESS_CALL TessBaseAPISetDictFunc(TessBaseAPI* handle, TessDictFunc f); +TESS_API void TESS_CALL TessBaseAPIClearPersistentCache(TessBaseAPI* handle); +TESS_API void TESS_CALL TessBaseAPISetProbabilityInContextFunc(TessBaseAPI* handle, TessProbabilityInContextFunc f); + +TESS_API void TESS_CALL TessBaseAPISetFillLatticeFunc(TessBaseAPI* handle, TessFillLatticeFunc f); + +// Call TessDeleteText(*best_script_name) to free memory allocated by this function +TESS_API BOOL TESS_CALL TessBaseAPIDetectOrientationScript(TessBaseAPI* handle, + int* orient_deg, float* orient_conf, const char **script_name, float* script_conf); + +TESS_API void TESS_CALL TessBaseAPIGetFeaturesForBlob(TessBaseAPI* handle, TBLOB* blob, INT_FEATURE_STRUCT* int_features, + int* num_features, int* FeatureOutlineIndex); + +TESS_API ROW* TESS_CALL TessFindRowForBox(BLOCK_LIST* blocks, int left, int top, int right, int bottom); +TESS_API void TESS_CALL TessBaseAPIRunAdaptiveClassifier(TessBaseAPI* handle, TBLOB* blob, int num_max_matches, + int* unichar_ids, float* ratings, int* num_matches_returned); +#endif + +TESS_API const char* + TESS_CALL TessBaseAPIGetUnichar(TessBaseAPI* handle, int unichar_id); + +#ifdef TESS_CAPI_INCLUDE_BASEAPI +TESS_API const TessDawg* + TESS_CALL TessBaseAPIGetDawg(const TessBaseAPI* handle, int i); +TESS_API int TESS_CALL TessBaseAPINumDawgs(const TessBaseAPI* handle); +#endif + +#ifdef TESS_CAPI_INCLUDE_BASEAPI +TESS_API ROW* TESS_CALL TessMakeTessOCRRow(float baseline, float xheight, float descender, float ascender); +TESS_API TBLOB* + TESS_CALL TessMakeTBLOB(Pix* pix); +TESS_API void TESS_CALL TessNormalizeTBLOB(TBLOB* tblob, ROW* row, BOOL numeric_mode); + +TESS_API TessOcrEngineMode + TESS_CALL TessBaseAPIOem(const TessBaseAPI* handle); +TESS_API void TESS_CALL TessBaseAPIInitTruthCallback(TessBaseAPI* handle, TessTruthCallback* cb); +#endif + +TESS_API void TESS_CALL TessBaseAPISetMinOrientationMargin(TessBaseAPI* handle, double margin); +#ifdef TESS_CAPI_INCLUDE_BASEAPI +TESS_API void TESS_CALL TessBaseGetBlockTextOrientations(TessBaseAPI* handle, int** block_orientation, BOOL** vertical_writing); + +TESS_API BLOCK_LIST* + TESS_CALL TessBaseAPIFindLinesCreateBlockList(TessBaseAPI* handle); +#endif + +/* Page iterator */ + +TESS_API void TESS_CALL TessPageIteratorDelete(TessPageIterator* handle); +TESS_API TessPageIterator* + TESS_CALL TessPageIteratorCopy(const TessPageIterator* handle); + +TESS_API void TESS_CALL TessPageIteratorBegin(TessPageIterator* handle); +TESS_API BOOL TESS_CALL TessPageIteratorNext(TessPageIterator* handle, TessPageIteratorLevel level); +TESS_API BOOL TESS_CALL TessPageIteratorIsAtBeginningOf(const TessPageIterator* handle, TessPageIteratorLevel level); +TESS_API BOOL TESS_CALL TessPageIteratorIsAtFinalElement(const TessPageIterator* handle, TessPageIteratorLevel level, + TessPageIteratorLevel element); + +TESS_API BOOL TESS_CALL TessPageIteratorBoundingBox(const TessPageIterator* handle, TessPageIteratorLevel level, + int* left, int* top, int* right, int* bottom); +TESS_API TessPolyBlockType + TESS_CALL TessPageIteratorBlockType(const TessPageIterator* handle); + +TESS_API struct Pix* + TESS_CALL TessPageIteratorGetBinaryImage(const TessPageIterator* handle, TessPageIteratorLevel level); +TESS_API struct Pix* + TESS_CALL TessPageIteratorGetImage(const TessPageIterator* handle, TessPageIteratorLevel level, int padding, + struct Pix* original_image, int* left, int* top); + +TESS_API BOOL TESS_CALL TessPageIteratorBaseline(const TessPageIterator* handle, TessPageIteratorLevel level, + int* x1, int* y1, int* x2, int* y2); + +TESS_API void TESS_CALL TessPageIteratorOrientation(TessPageIterator* handle, TessOrientation* orientation, + TessWritingDirection* writing_direction, TessTextlineOrder* textline_order, + float* deskew_angle); + +TESS_API void TESS_CALL TessPageIteratorParagraphInfo(TessPageIterator* handle, TessParagraphJustification* justification, + BOOL *is_list_item, BOOL *is_crown, int *first_line_indent); + +/* Result iterator */ + +TESS_API void TESS_CALL TessResultIteratorDelete(TessResultIterator* handle); +TESS_API TessResultIterator* + TESS_CALL TessResultIteratorCopy(const TessResultIterator* handle); +TESS_API TessPageIterator* + TESS_CALL TessResultIteratorGetPageIterator(TessResultIterator* handle); +TESS_API const TessPageIterator* + TESS_CALL TessResultIteratorGetPageIteratorConst(const TessResultIterator* handle); +TESS_API TessChoiceIterator* + TESS_CALL TessResultIteratorGetChoiceIterator(const TessResultIterator* handle); + +TESS_API BOOL TESS_CALL TessResultIteratorNext(TessResultIterator* handle, TessPageIteratorLevel level); +TESS_API char* TESS_CALL TessResultIteratorGetUTF8Text(const TessResultIterator* handle, TessPageIteratorLevel level); +TESS_API float TESS_CALL TessResultIteratorConfidence(const TessResultIterator* handle, TessPageIteratorLevel level); +TESS_API const char* + TESS_CALL TessResultIteratorWordRecognitionLanguage(const TessResultIterator* handle); +TESS_API const char* + TESS_CALL TessResultIteratorWordFontAttributes(const TessResultIterator* handle, BOOL* is_bold, BOOL* is_italic, + BOOL* is_underlined, BOOL* is_monospace, BOOL* is_serif, + BOOL* is_smallcaps, int* pointsize, int* font_id); + +TESS_API BOOL TESS_CALL TessResultIteratorWordIsFromDictionary(const TessResultIterator* handle); +TESS_API BOOL TESS_CALL TessResultIteratorWordIsNumeric(const TessResultIterator* handle); +TESS_API BOOL TESS_CALL TessResultIteratorSymbolIsSuperscript(const TessResultIterator* handle); +TESS_API BOOL TESS_CALL TessResultIteratorSymbolIsSubscript(const TessResultIterator* handle); +TESS_API BOOL TESS_CALL TessResultIteratorSymbolIsDropcap(const TessResultIterator* handle); + +TESS_API void TESS_CALL TessChoiceIteratorDelete(TessChoiceIterator* handle); +TESS_API BOOL TESS_CALL TessChoiceIteratorNext(TessChoiceIterator* handle); +TESS_API const char* TESS_CALL TessChoiceIteratorGetUTF8Text(const TessChoiceIterator* handle); +TESS_API float TESS_CALL TessChoiceIteratorConfidence(const TessChoiceIterator* handle); + +#ifdef __cplusplus +} +#endif + +#endif // API_CAPI_H_ diff --git a/translation/ocr_driver.c b/translation/ocr_driver.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/translation/ocr_driver.h b/translation/ocr_driver.h new file mode 100644 index 0000000000..2bbfbf4805 --- /dev/null +++ b/translation/ocr_driver.h @@ -0,0 +1,28 @@ +#ifndef __OCR_DRIVER__H +#define __OCR_DRIVER__H + +struct ocr_image_info +{ + int game_character_set; + unsigned image_width; + unsigned image_height; + unsigned pixel_format; + void* image_data; +}; + +typedef struct ocr_driver +{ + void* (*init)(); + void (*free)(void* data); + + char* (*get_text)(struct ocr_image_info image); + + const char *ident; +} ocr_driver_t; + +extern const ocr_driver_t ocr_tesseract; +extern const ocr_driver_t ocr_null; + +char* ocr_get_text(struct ocr_image_info image); + +#endif \ No newline at end of file diff --git a/translation/translation_driver.c b/translation/translation_driver.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/translation/translation_driver.h b/translation/translation_driver.h new file mode 100644 index 0000000000..574d205b8b --- /dev/null +++ b/translation/translation_driver.h @@ -0,0 +1,39 @@ +#ifndef __TRANSLATION_DRIVER__H +#define __TRANSLATION_DRIVER__H + +#include "ocr_driver.h" + +enum translation_init_errors +{ + TRANSLATION_INIT_SUCCESS = 0, + TRANSLATION_INIT_UNSUPPORTED_DEVICE_LANGUAGE, + TRANSLATION_INIT_UNSUPPORTED_GAME_LANGUAGE, + TRANSLATION_INIT_UNKNOWN_DEVICE_LANGUAGE, + TRANSLATION_INIT_UNKNOWN_GAME_LANGUAGE +}; + +struct translation_driver_info +{ + int device_language; + int game_language; +}; + +typedef struct translation_driver +{ + void* (*init)(const struct translation_driver_info *params); + void (*free)(void* data); + + /* use translate_image if non NULL else run image through ocr driver then run translate_text */ + /* NOTE: translate_image is allowed to call the ocr driver itself if it wants */ + char* (*translate_text)(const char* game_text); + char* (*translate_image)(struct ocr_image_info image); + + const char *ident; +} translation_driver_t; + +extern const translation_driver_t translation_cached_google; +extern const translation_driver_t translation_null; + +char* translation_translate_image(struct ocr_image_info image); + +#endif \ No newline at end of file diff --git a/wiiu/gx2_shader_inl.h b/wiiu/gx2_shader_inl.h index 08cf3c2c88..8fce718ab9 100644 --- a/wiiu/gx2_shader_inl.h +++ b/wiiu/gx2_shader_inl.h @@ -111,6 +111,7 @@ #define _w 3 #define _0 4 #define _1 5 +#define _m 7 /*mask*/ #define _xyzw 0b1111 #define _xy__ 0b0011 @@ -118,6 +119,10 @@ #define GX2_COMP_SEL(c0, c1, c2, c3) (((c0) << 24) | ((c1) << 16) | ((c2) << 8) | (c3)) #define ALU_LITERAL(v) to_QWORD(to_LE(v), 0) +#define ALU_LITERAL2(v0,v1) to_QWORD(to_LE(v0), to_LE(v1)) +#define ALU_LITERAL3(v0,v1,v2) ALU_LITERAL2(v0,v1),ALU_LITERAL(v2) +#define ALU_LITERAL4(v0,v1,v2,v3) ALU_LITERAL2(v0,v1),ALU_LITERAL2(v2,v3) +#define ALU_LITERAL5(v0,v1,v2,v3,v5) ALU_LITERAL4(v0,v1,v2,v3),ALU_LITERAL(v4) /* SRCx_SEL special constants */ #define ALU_SRC_1_DBL_L 0xF4 @@ -195,11 +200,17 @@ #define CF_INST_EMIT_VERTEX 0x15 #define CF_INST_MEM_RING 0x26 /* ALU */ -#define OP2_INST_ADD 0x0 -#define OP2_INST_MUL 0x1 -#define OP2_INST_MUL_IEEE 0x2 -#define OP2_INST_MOV 0x19 -#define OP2_INST_RECIP_IEEE 0x66 +#define OP2_INST_ADD 0x0 +#define OP2_INST_MUL 0x1 +#define OP2_INST_MUL_IEEE 0x2 +#define OP2_INST_FRACT 0x10 +#define OP2_INST_FLOOR 0x14 +#define OP2_INST_MOV 0x19 +#define OP2_INST_DOT4_IEEE 0x51 +#define OP2_INST_RECIP_IEEE 0x66 +#define OP2_INST_RECIPSQRT_IEEE 0x69 +#define OP2_INST_SIN 0x6E +#define OP2_INST_COS 0x6F #define OP3_INST_MULADD 0x10 /* EXP */ @@ -207,7 +218,9 @@ #define CF_INST_EXP_DONE 0x28 /* TEX */ -#define TEX_INST_SAMPLE 0x10 +#define TEX_INST_GET_GRADIENTS_H 0x07 +#define TEX_INST_GET_GRADIENTS_V 0x08 +#define TEX_INST_SAMPLE 0x10 /* VTX */ #define VTX_INST_FETCH 0x0 @@ -298,35 +311,67 @@ to_QWORD(ALU_WORD0(src0Sel, 0x0, src0Chan, 0x0, src1Sel, 0x0, src1Chan, 0x0, 0x0, 0x0), \ ALU_WORD1_OP3(src2Sel, 0x0, src2Chan, 0x0, inst, 0x0, dstGpr, 0x0, dstChan, 0x0)) -#define ALU_MOV(dstGpr, dstChan, src0Sel, src0Chan) \ - ALU_OP2(OP2_INST_MOV, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_OFF) - -#define ALU_MOV_x2(dstGpr, dstChan, src0Sel, src0Chan) \ - ALU_OP2(OP2_INST_MOV, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_M2) - -#define ALU_MUL(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan) \ - ALU_OP2(OP2_INST_MUL, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, ALU_OMOD_OFF) - -#define ALU_MULADD(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, src2Sel, src2Chan) \ - ALU_OP3(OP3_INST_MULADD, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, src2Sel, src2Chan) - -#define ALU_MUL_IEEE(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan) \ - ALU_OP2(OP2_INST_MUL_IEEE, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, ALU_OMOD_OFF) - #define ALU_ADD(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan) \ ALU_OP2(OP2_INST_ADD, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, ALU_OMOD_OFF) #define ALU_ADD_x2(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan) \ ALU_OP2(OP2_INST_ADD, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, ALU_OMOD_M2) +#define ALU_MUL(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan) \ + ALU_OP2(OP2_INST_MUL, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, ALU_OMOD_OFF) + +#define ALU_MUL_IEEE(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan) \ + ALU_OP2(OP2_INST_MUL_IEEE, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, ALU_OMOD_OFF) + +#define ALU_FRACT(dstGpr, dstChan, src0Sel, src0Chan) \ + ALU_OP2(OP2_INST_FRACT, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_OFF) + +#define ALU_FLOOR(dstGpr, dstChan, src0Sel, src0Chan) \ + ALU_OP2(OP2_INST_FLOOR, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_OFF) + +#define ALU_MOV(dstGpr, dstChan, src0Sel, src0Chan) \ + ALU_OP2(OP2_INST_MOV, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_OFF) + +#define ALU_MOV_x2(dstGpr, dstChan, src0Sel, src0Chan) \ + ALU_OP2(OP2_INST_MOV, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_M2) + +#define ALU_MOV_x4(dstGpr, dstChan, src0Sel, src0Chan) \ + ALU_OP2(OP2_INST_MOV, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_M4) + +#define ALU_DOT4_IEEE(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan) \ + ALU_OP2(OP2_INST_DOT4_IEEE, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, ALU_OMOD_OFF) + #define ALU_RECIP_IEEE(dstGpr, dstChan, src0Sel, src0Chan) \ ALU_OP2(OP2_INST_RECIP_IEEE, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_OFF) +#define ALU_RECIPSQRT_IEEE(dstGpr, dstChan, src0Sel, src0Chan) \ + ALU_OP2(OP2_INST_RECIPSQRT_IEEE, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_OFF) + +#define ALU_SIN(dstGpr, dstChan, src0Sel, src0Chan) \ + ALU_OP2(OP2_INST_SIN, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_OFF) + +#define ALU_COS(dstGpr, dstChan, src0Sel, src0Chan) \ + ALU_OP2(OP2_INST_COS, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_OFF) + +#define ALU_MULADD(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, src2Sel, src2Chan) \ + ALU_OP3(OP3_INST_MULADD, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, src2Sel, src2Chan) + #define TEX_SAMPLE(dstReg, dstSelX, dstSelY, dstSelZ, dstSelW, srcReg, srcSelX, srcSelY, srcSelZ, srcSelW, resourceID, samplerID)\ to_QWORD(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)), \ to_QWORD(TEX_WORD2(0x0, 0x0, 0x0, samplerID, _x, _y, _0, _x), 0x00000000) +#define TEX_GET_GRADIENTS_H(dstReg, dstSelX, dstSelY, dstSelZ, dstSelW, srcReg, srcSelX, srcSelY, srcSelZ, srcSelW, resourceID, samplerID)\ + to_QWORD(TEX_WORD0(TEX_INST_GET_GRADIENTS_H, 0x0, 0x0, resourceID, srcReg, 0x0, 0x0), \ + TEX_WORD1(dstReg, 0x0, dstSelX, dstSelY, dstSelZ, dstSelW, 0x0, TEX_NORMALIZED, TEX_NORMALIZED, TEX_NORMALIZED, TEX_NORMALIZED)), \ + to_QWORD(TEX_WORD2(0x0, 0x0, 0x0, samplerID, _x, _y, _z, _x), 0x00000000) + +#define TEX_GET_GRADIENTS_V(dstReg, dstSelX, dstSelY, dstSelZ, dstSelW, srcReg, srcSelX, srcSelY, srcSelZ, srcSelW, resourceID, samplerID)\ + to_QWORD(TEX_WORD0(TEX_INST_GET_GRADIENTS_V, 0x0, 0x0, resourceID, srcReg, 0x0, 0x0), \ + TEX_WORD1(dstReg, 0x0, dstSelX, dstSelY, dstSelZ, dstSelW, 0x0, TEX_NORMALIZED, TEX_NORMALIZED, TEX_NORMALIZED, TEX_NORMALIZED)), \ + to_QWORD(TEX_WORD2(0x0, 0x0, 0x0, samplerID, _x, _y, _z, _x), 0x00000000) + + #define VTX_FETCH(dstReg, dstSelX, dstSelY, dstSelZ, dstSelW, srcReg, srcSelX, buffer_id, type, mega, offset) \ to_QWORD(VTX_WORD0(VTX_INST_FETCH, type, buffer_id, srcReg, srcSelX, mega), VTX_WORD1(dstReg, dstSelX, dstSelY, dstSelZ, dstSelW)) , \ to_QWORD(VTX_WORD2(offset, (mega >> 31)), 0x00000000) diff --git a/wiiu/net_listen.sh b/wiiu/net_listen.sh index ae39b5caa7..167be1fa63 100755 --- a/wiiu/net_listen.sh +++ b/wiiu/net_listen.sh @@ -1,14 +1,14 @@ #!/bin/sh +if [ -z $1 ] ; then + echo + echo "usage: $0 " + echo + exit 0 +fi + interrupt_count=0 -trap 'if [ $interrupt_count -eq 5 ]; then exit 0; else interrupt_count=$(($interrupt_count + 1)); fi' INT +trap 'if [ $interrupt_count -eq 20 ]; then exit 0; else interrupt_count=$(($interrupt_count + 1)); fi' INT -echo ===== START: `date` ===== -while true; do - netcat -p 4405 -l - if [ $? -ne 0 ]; then - break - fi -done -echo ===== END: `date` ===== +while true; do echo; echo ========= `date` =========; echo; netcat -p 4405 -l $1; done diff --git a/wiiu/ribbon_shader.c b/wiiu/ribbon_shader.c new file mode 100644 index 0000000000..a5d768f481 --- /dev/null +++ b/wiiu/ribbon_shader.c @@ -0,0 +1,389 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2014-2018 - Ali Bouhlel + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include +#include +#include +#include "frame_shader.h" +#include "gx2_shader_inl.h" + +__attribute__((aligned(GX2_SHADER_ALIGNMENT))) +static struct +{ + u64 cf[32]; + u64 alu[123 + 51]; +} vs_program = +{ + { + CALL_FS NO_BARRIER, + ALU(32, 123) KCACHE0(CB1, _0_15), + ALU(155, 51), + EXP_DONE(POS0, _R7, _x, _y, _z, _w), + EXP_DONE(PARAM0, _R7, _x, _y, _z, _w) NO_BARRIER + END_OF_PROGRAM + END_OF_PROGRAM + }, + { + ALU_MOV(_R7,_x, _R1,_x), + ALU_MUL_IEEE(__,_y, KC0(0),_x, ALU_SRC_LITERAL,_x), + ALU_MUL_IEEE(__,_z, KC0(0),_x, ALU_SRC_LITERAL,_y), + ALU_MUL_IEEE(__,_w, KC0(0),_x, ALU_SRC_LITERAL,_z), + ALU_MUL_IEEE(_R127,_w, KC0(0),_x, ALU_SRC_0_5,_x) + ALU_LAST, + ALU_LITERAL3(0x3E4CCCCD,0x3C23D70A,0x3DCCCCCD), + ALU_ADD(__,_x, ALU_SRC_PV _NEG,_z, ALU_SRC_0, _x), + ALU_ADD(__,_y, _R1,_y, ALU_SRC_PV _NEG ,_w), + ALU_MOV_x2(__,_z, ALU_SRC_PV,_x), + ALU_ADD(__,_w, ALU_SRC_PV,_x, ALU_SRC_PV _NEG,_y), + ALU_ADD(__,__, _R1,_y, ALU_SRC_PV,_w) + ALU_LAST, + ALU_MUL(_R127,_x, ALU_SRC_PV,_y, ALU_SRC_LITERAL,_x), + ALU_MUL(__,_y, ALU_SRC_PV,_x, ALU_SRC_LITERAL,_x), + ALU_MUL_IEEE(__,_z, ALU_SRC_PV,_w, ALU_SRC_LITERAL,_y), + ALU_ADD(_R126,_w, _R127 _NEG,_w, ALU_SRC_PV,_z), + ALU_ADD(_R127,_z, _R7,_x, ALU_SRC_PS,_x) + ALU_LAST, + ALU_LITERAL2(0x40E00000,0x3E800000), + ALU_FLOOR(__,_x, ALU_SRC_PV,_y), + ALU_FLOOR(__,_y, ALU_SRC_PV,_x), + ALU_MUL(__,_z, ALU_SRC_PV,_z, ALU_SRC_LITERAL,_x), + ALU_FRACT(_R127,_w, ALU_SRC_PV,_y), + ALU_MOV_x4(_R124,_x, _R1,_y) + ALU_LAST, + ALU_LITERAL(0x40E00000), + ALU_MUL(__,_x, ALU_SRC_PV,_x, ALU_SRC_LITERAL,_x), + ALU_MUL(_R127,_y, ALU_SRC_PV,_y, ALU_SRC_LITERAL,_y), + ALU_FRACT(__,_z, ALU_SRC_PV,_z), + ALU_FLOOR(__,_w, ALU_SRC_PV,_z), + ALU_MOV_x2(__,__, ALU_SRC_PV,_w) + ALU_LAST, + ALU_LITERAL2(0x42640000,0x42E20000), + ALU_MUL(_R125,_x, ALU_SRC_PV,_z, ALU_SRC_PV,_z), + ALU_MOV_x2(__,_y, ALU_SRC_PV,_z), + ALU_FRACT(_R124,_z, _R127,_x), + ALU_ADD(__,_w, ALU_SRC_PV,_w, ALU_SRC_PV,_x), + ALU_ADD(_R124,_y, ALU_SRC_PS _NEG,_x, ALU_SRC_LITERAL,_x) + ALU_LAST, + ALU_LITERAL(0x40400000), + ALU_ADD(_R126,_x, ALU_SRC_PV _NEG,_y, ALU_SRC_LITERAL,_x), + ALU_MUL(_R0,_y, _R127,_w, _R127,_w), + ALU_ADD(_R127,_z, _R127,_y, ALU_SRC_PV,_w), + ALU_MULADD(_R0,_w, _R126,_w, ALU_SRC_LITERAL,_y, ALU_SRC_0_5,_x) VEC_120, + ALU_MULADD(_R2,_y, _R127,_z, ALU_SRC_LITERAL,_y, ALU_SRC_0_5,_x) + ALU_LAST, + ALU_LITERAL2(0x40400000,0x3E22F983), + ALU_ADD(__,_x, ALU_SRC_PV,_z, ALU_SRC_LITERAL,_x), + ALU_ADD(_R127,_y, ALU_SRC_PV,_z, ALU_SRC_LITERAL,_y), + ALU_ADD(__,_z, ALU_SRC_PV,_z, ALU_SRC_1,_x), + ALU_ADD(_R127,_w, ALU_SRC_PV,_z, ALU_SRC_LITERAL,_z), + ALU_ADD(_R127,_x, ALU_SRC_PV,_z, ALU_SRC_LITERAL,_w) + ALU_LAST, + ALU_LITERAL4(0x42640000,0x42680000,0x42E20000,0x42E40000), + ALU_ADD(__,_x, _R127,_z, ALU_SRC_LITERAL,_x), + ALU_MULADD(_R126,_y, _R127,_z, ALU_SRC_LITERAL,_y, ALU_SRC_0_5,_x), + ALU_ADD(__,_z, _R127,_z, ALU_SRC_LITERAL,_z), + ALU_MULADD(_R126,_w, ALU_SRC_PV,_z, ALU_SRC_LITERAL,_y, ALU_SRC_0_5,_x), + ALU_MULADD(_R125,_w, ALU_SRC_PV,_x, ALU_SRC_LITERAL,_y, ALU_SRC_0_5,_x) + ALU_LAST, + ALU_LITERAL3(0x432B0000,0x3E22F983,0x432A0000), + ALU_MULADD(_R123,_x, _R127,_w, ALU_SRC_LITERAL,_x, ALU_SRC_0_5,_x), + ALU_MULADD(_R127,_y, _R127,_x, ALU_SRC_LITERAL,_x, ALU_SRC_0_5,_x), + ALU_MULADD(_R127,_z, ALU_SRC_PV,_z, ALU_SRC_LITERAL,_x, ALU_SRC_0_5,_x), + ALU_MULADD(_R123,_w, _R127,_y, ALU_SRC_LITERAL,_x, ALU_SRC_0_5,_x), + ALU_MULADD(_R125,_y, ALU_SRC_PV,_x, ALU_SRC_LITERAL,_x, ALU_SRC_0_5,_x) + ALU_LAST, + ALU_LITERAL(0x3E22F983), + ALU_FRACT(__,_x, _R126,_y), + ALU_FRACT(__,_y, _R126,_w), + ALU_FRACT(_R126,_z, _R125,_w) VEC_120, + ALU_FRACT(_R126,_w, ALU_SRC_PV,_w), + ALU_FRACT(_R125,_z, ALU_SRC_PV,_x) + ALU_LAST, + ALU_FRACT(__,_x, _R127,_z), + ALU_FRACT(_R127,_y, _R125,_y), + ALU_FRACT(__,_z, _R127,_y) VEC_120, + ALU_MULADD(_R125,_w, ALU_SRC_PV,_x, ALU_SRC_LITERAL,_y, ALU_SRC_LITERAL,_x), + ALU_MULADD(_R127,_w, ALU_SRC_PV,_y, ALU_SRC_LITERAL,_y, ALU_SRC_LITERAL,_x) + ALU_LAST, + ALU_LITERAL2(0xC0490FDB,0x40C90FDB), + ALU_MULADD(_R123,_x, _R126,_w, ALU_SRC_LITERAL,_y, ALU_SRC_LITERAL,_x), + ALU_MULADD(_R123,_y, _R126,_z, ALU_SRC_LITERAL,_y, ALU_SRC_LITERAL,_x), + ALU_MULADD(_R126,_z, _R125,_z, ALU_SRC_LITERAL,_y, ALU_SRC_LITERAL,_x) VEC_120, + ALU_MULADD(_R126,_w, ALU_SRC_PV,_z, ALU_SRC_LITERAL,_y, ALU_SRC_LITERAL,_x), + ALU_MULADD(_R124,_w, ALU_SRC_PV,_x, ALU_SRC_LITERAL,_y, ALU_SRC_LITERAL,_x) + ALU_LAST, + ALU_LITERAL2(0xC0490FDB,0x40C90FDB), + ALU_MUL(_R127,_x, _R127,_w, ALU_SRC_LITERAL,_x), + ALU_MUL(_R127,_y, ALU_SRC_PV,_y, ALU_SRC_LITERAL,_x), + ALU_MUL(__,_z, _R125,_w, ALU_SRC_LITERAL,_x) VEC_120, + ALU_MULADD(_R123,_w, _R127,_y, ALU_SRC_LITERAL,_z, ALU_SRC_LITERAL,_y), + ALU_MUL(_R0,_x, ALU_SRC_PV,_x, ALU_SRC_LITERAL,_x) + ALU_LAST, + ALU_LITERAL3(0x3E22F983,0xC0490FDB,0x40C90FDB), + ALU_MUL(_R2,_x, _R126,_z, ALU_SRC_LITERAL,_x), + ALU_MUL(_R3,_y, _R126,_w, ALU_SRC_LITERAL,_x), + ALU_MUL(_R126,_z, _R124,_w, ALU_SRC_LITERAL,_x) VEC_120, + ALU_MUL(_R126,_w, ALU_SRC_PV,_w, ALU_SRC_LITERAL,_x), + ALU_SIN(__,__, ALU_SRC_PV,_z) SCL_210 + ALU_LAST, + ALU_LITERAL(0x3E22F983), + ALU_MUL(__,_x, ALU_SRC_PS,_x, ALU_SRC_LITERAL,_x), + ALU_MUL(_R6,_y, _R126,_x, _R125,_x), + ALU_MOV_x2(_R0,_z, _R124,_z), + ALU_MUL(_R2,_w, _R124,_y, _R0,_y), + ALU_SIN(__,__, _R127,_x) SCL_210 + ALU_LAST, + ALU_LITERAL(0x472AEE8C), + ALU_MUL(__,_x, ALU_SRC_PS,_x, ALU_SRC_LITERAL,_x), + ALU_MULADD(_R123,_y, _R124,_x, ALU_SRC_LITERAL,_y, ALU_SRC_0_5,_x), + ALU_FRACT(_R125,_z, _R0,_w), + ALU_FRACT(_R124,_w, ALU_SRC_PV,_x), + ALU_SIN(__,__, _R127,_y) SCL_210 + ALU_LAST, + ALU_LITERAL2(0x472AEE8C,0x3E22F983), + ALU_FRACT(_R3,_x, _R2,_y), + ALU_FRACT(_R0,_y, ALU_SRC_PV,_y), + ALU_MUL(__,_z, ALU_SRC_PS,_x, ALU_SRC_LITERAL,_x), + ALU_FRACT(__,_w, ALU_SRC_PV,_x), + ALU_SIN(__,__, _R0,_x) SCL_210 + ALU_LAST, + ALU_LITERAL(0x472AEE8C), + ALU_ADD(__,_x, _R124 _NEG,_w, ALU_SRC_PV,_w), + ALU_FRACT(_R5,_y, ALU_SRC_PV,_z), + ALU_MUL(__,_z, ALU_SRC_PS,_x, ALU_SRC_LITERAL,_x), + ALU_MULADD(_R1,_w, _R125,_z, ALU_SRC_LITERAL,_z,ALU_SRC_LITERAL,_y), + ALU_SIN(__,__, _R126,_z) SCL_210 + ALU_LAST, + ALU_LITERAL3(0x472AEE8C,0xC0490FDB,0x40C90FDB), + ALU_MUL(_R0,_x, ALU_SRC_PS,_x, ALU_SRC_LITERAL,_x), + ALU_FRACT(_R4,_y, ALU_SRC_PV,_z), + ALU_MULADD(_R1,_z, ALU_SRC_PV,_x, _R6,_y, _R124,_w) VEC_021, + ALU_MUL(_R0,_w, _R124,_z, _R124,_z), + ALU_SIN(_R2,_y, _R126,_w) SCL_210 + ALU_LAST, + ALU_LITERAL(0x472AEE8C), + ALU_MUL(__,_x, _R2,_y, ALU_SRC_LITERAL,_x), + ALU_ADD(__,_y, _R0 _NEG,_z, ALU_SRC_LITERAL,_y), + ALU_MULADD(_R124,_z, _R0,_y, ALU_SRC_LITERAL,_w, ALU_SRC_LITERAL,_z) VEC_120, + ALU_FRACT(_R126,_w, _R0,_x), + ALU_SIN(__,__, _R3,_y) SCL_210 + ALU_LAST, + ALU_LITERAL4(0x472AEE8C,0x40400000,0xC0490FDB,0x40C90FDB), + ALU_ADD(__,_x, _R5 _NEG,_y, _R4,_y), + ALU_MUL(_R125,_y, ALU_SRC_PV,_y, _R0,_w), + ALU_MUL(__,_z, ALU_SRC_PS,_x, ALU_SRC_LITERAL,_x), + ALU_FRACT(__,_w, ALU_SRC_PV,_x), + ALU_SIN(__,__, _R2,_x) SCL_210 + ALU_LAST, + ALU_LITERAL(0x472AEE8C), + ALU_ADD(__,_x, _R126 _NEG,_w, ALU_SRC_PV,_w), + ALU_FRACT(_R127,_y, ALU_SRC_PV,_z), + ALU_MUL(__,_z, ALU_SRC_PS,_x, ALU_SRC_LITERAL,_x), + ALU_MULADD(_R123,_w, ALU_SRC_PV,_x, _R6,_y, _R5,_y), + ALU_MUL(__,__, _R1,_w, ALU_SRC_LITERAL,_y) + ALU_LAST, + ALU_LITERAL2(0x472AEE8C,0x3E22F983), + ALU_MULADD(_R124,_x, ALU_SRC_PV,_x, _R6,_y, _R126,_w), + ALU_FRACT(_R124,_y, ALU_SRC_PV,_z), + ALU_ADD(__,_z, _R1 _NEG,_z, ALU_SRC_PV,_w), + ALU_MULADD(_R123,_w, _R3,_x, ALU_SRC_LITERAL,_y, ALU_SRC_LITERAL,_x), + ALU_COS(__,__, ALU_SRC_PS,_x) SCL_210 + ALU_LAST, + ALU_LITERAL2(0xC0490FDB,0x40C90FDB), + ALU_ADD(__,_x, ALU_SRC_PV _NEG,_y, _R127,_y), + ALU_MULADD(_R127,_y, ALU_SRC_PV,_z, _R2,_w, _R1,_z), + ALU_MUL(_R124,_z, _R124,_z, ALU_SRC_LITERAL,_x), + ALU_MUL(__,_w, ALU_SRC_PV,_w, ALU_SRC_LITERAL,_x), + ALU_MUL_IEEE(_R124,_w, ALU_SRC_PS,_x, ALU_SRC_LITERAL,_y) + ALU_LAST, + ALU_LITERAL2(0x3E22F983,0x3E4CCCCD), + ALU_MULADD(_R126,_w, ALU_SRC_PV,_x, _R6,_y, _R124,_y), + ALU_COS(_R124,_y, ALU_SRC_PV,_w) SCL_210 + ALU_LAST, + ALU_ADD(__,_x, ALU_SRC_PV _NEG,_w, _R124,_x), + ALU_MOV(_R7,_w, ALU_SRC_LITERAL,_x), + ALU_COS(__,__, _R124,_z) SCL_210 + ALU_LAST, + ALU_LITERAL(0x3F800000), + ALU_MUL(__,_z, _R124,_y, ALU_SRC_PS,_x), + ALU_MULADD(_R123,_w, ALU_SRC_PV,_x, _R2,_w, _R126,_w) + ALU_LAST, + ALU_MUL_IEEE(_R124,_y, ALU_SRC_PV,_z, ALU_SRC_LITERAL,_x), + ALU_ADD(__,_z, _R127 _NEG,_y, ALU_SRC_PV,_w) + ALU_LAST, + ALU_LITERAL(0x3E000000), + ALU_MULADD(_R123,_y, ALU_SRC_PV,_z, _R125,_y, _R127,_y) + ALU_LAST, + ALU_MUL_IEEE(__,_x, ALU_SRC_PV,_y, ALU_SRC_LITERAL,_x) + ALU_LAST, + ALU_LITERAL(0x3D888889), + ALU_ADD(__,_y, ALU_SRC_PV,_x, _R124,_w), + ALU_ADD(_R7,_z, _R1,_y, ALU_SRC_PV _NEG,_x) + ALU_LAST, + ALU_ADD(__,_z, ALU_SRC_PV,_y, ALU_SRC_LITERAL,_x) + ALU_LAST, + ALU_LITERAL(0xBE99999A), + ALU_ADD(__,_x, _R124,_y, ALU_SRC_PV _NEG,_z) + ALU_LAST, + ALU_MOV(_R7,_y, ALU_SRC_PV _NEG,_x) + ALU_LAST, + } +}; + +__attribute__((aligned(GX2_SHADER_ALIGNMENT))) +static struct +{ + u64 cf[32]; + u64 alu[64-32]; + u64 tex[2 * 2]; +} +ps_program = +{ + { + TEX(64, 2) VALID_PIX, + ALU(32, 27), + EXP_DONE(PIX0, _R2, _z, _z, _z, _w) + END_OF_PROGRAM + + }, + { + ALU_MUL(__,_x, _R1,_z, _R0,_x), + ALU_MUL(__,_y, _R1,_y, _R0,_z), + ALU_MOV(_R2,_z, ALU_SRC_LITERAL,_x), + ALU_MUL(__,_w, _R1,_x, _R0,_y) + ALU_LAST, + ALU_LITERAL(0x3F800000), + ALU_MULADD(_R123,_x, _R0 _NEG,_y, _R1,_z, ALU_SRC_PV,_y), + ALU_MULADD(_R123,_y, _R0 _NEG,_z, _R1,_x, ALU_SRC_PV,_x), + ALU_MULADD(_R127,_z, _R0 _NEG,_x, _R1,_y, ALU_SRC_PV,_w) + ALU_LAST, + ALU_DOT4_IEEE(__,_x, ALU_SRC_PV,_x, ALU_SRC_PV,_x), + ALU_DOT4_IEEE(__,_y, ALU_SRC_PV,_y, ALU_SRC_PV,_y), + ALU_DOT4_IEEE(__,_z, ALU_SRC_PV,_z, ALU_SRC_PV,_z), + ALU_DOT4_IEEE(__,_w, ALU_SRC_LITERAL,_x, ALU_SRC_0,_x) + ALU_LAST, + ALU_LITERAL(0x80000000), + ALU_RECIPSQRT_IEEE(__,__, ALU_SRC_PV,_x) SCL_210 + ALU_LAST, + ALU_MULADD(_R123,_w, _R127 _NEG,_z, ALU_SRC_PS,_x, ALU_SRC_1,_x) + ALU_LAST, + ALU_MUL(__,_x, ALU_SRC_PV,_w, ALU_SRC_PV,_w) + ALU_LAST, + ALU_MULADD(_R123,_z, ALU_SRC_PV,_x, ALU_SRC_LITERAL,_x, ALU_SRC_0_5,_x) + ALU_LAST, + ALU_LITERAL(0x3E22F983), + ALU_FRACT(__,_y, ALU_SRC_PV,_z) + ALU_LAST, + ALU_MULADD(_R123,_w, ALU_SRC_PV,_y, ALU_SRC_LITERAL,_y,ALU_SRC_LITERAL,_x) + ALU_LAST, + ALU_LITERAL2(0xC0490FDB,0x40C90FDB), + ALU_MUL(__,_x, ALU_SRC_PV,_w, ALU_SRC_LITERAL,_x) + ALU_LAST, + ALU_LITERAL(0x3E22F983), + ALU_COS(__,__, ALU_SRC_PV,_x) SCL_210 + ALU_LAST, + ALU_ADD(__,_y, ALU_SRC_PS _NEG,_x, ALU_SRC_1,_x) + ALU_LAST, + ALU_MUL_IEEE(_R2,_w, ALU_SRC_PV,_y, ALU_SRC_LITERAL,_x) + ALU_LAST, + ALU_LITERAL(0x3D4CCCCD), + }, + { + TEX_GET_GRADIENTS_H(_R1,_x,_y,_z,_m, _R0,_x,_y,_z,_x, _t0, _s0), + TEX_GET_GRADIENTS_V(_R0,_x,_y,_z,_m, _R0,_x,_y,_z,_x, _t0, _s0) + } +}; + +static GX2AttribVar attributes[] = +{ + { "VertexCoord", GX2_SHADER_VAR_TYPE_FLOAT3, 0, 0}, +}; + +static GX2AttribStream attribute_stream[] = +{ + {0, 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32, + GX2_ATTRIB_INDEX_PER_VERTEX, 0, GX2_COMP_SEL(_x, _y, _0, _1), GX2_ENDIAN_SWAP_DEFAULT} +}; + +static GX2SamplerVar samplers[] = +{ + { "Source", GX2_SAMPLER_VAR_TYPE_SAMPLER_2D, 0 }, +}; + +static GX2UniformBlock uniform_blocks[] = { + {"UBO", 1, 16} +}; + +static GX2UniformVar uniform_vars[] = { + {"constants.time", GX2_SHADER_VAR_TYPE_FLOAT, 1, 0, 0}, +}; + + +GX2Shader ribbon_shader = +{ + { + { + .sq_pgm_resources_vs.num_gprs = 8, + .sq_pgm_resources_vs.stack_size = 1, + .spi_vs_out_config.vs_export_count = 0, + .num_spi_vs_out_id = 1, + { + {.semantic_0 = 0x00, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF}, + {.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF}, + {.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF}, + {.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF}, + {.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF}, + {.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF}, + {.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF}, + {.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF}, + {.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF}, + {.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF}, + }, + .sq_vtx_semantic_clear = ~0x1, + .num_sq_vtx_semantic = 1, + { + 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }, + .vgt_vertex_reuse_block_cntl.vtx_reuse_depth = 0xE, + .vgt_hos_reuse_depth.reuse_depth = 0x10, + }, /* regs */ + .size = sizeof(vs_program), + .program = (uint8_t*)&vs_program, + .mode = GX2_SHADER_MODE_UNIFORM_BLOCK, + .uniformBlockCount = countof(uniform_blocks), uniform_blocks, + .uniformVarCount = countof(uniform_vars), uniform_vars, + .attribVarCount = countof(attributes), attributes, + }, + { + { + .sq_pgm_resources_ps.num_gprs = 3, + .sq_pgm_exports_ps.export_mode = 0x2, + .spi_ps_in_control_0.num_interp = 1, + .spi_ps_in_control_0.persp_gradient_ena = 1, + .spi_ps_in_control_0.baryc_sample_cntl = spi_baryc_cntl_centers_only, + .num_spi_ps_input_cntl = 1, {{.semantic = 0, .default_val = 1}}, + .cb_shader_mask.output0_enable = 0xF, + .cb_shader_control.rt0_enable = TRUE, + .db_shader_control.z_order = db_z_order_early_z_then_late_z, + }, /* regs */ + .size = sizeof(ps_program), + .program = (uint8_t*)&ps_program, + .mode = GX2_SHADER_MODE_UNIFORM_BLOCK, + .samplerVarCount = countof(samplers), samplers, + }, + .attribute_stream = attribute_stream, +}; diff --git a/wiiu/ribbon_shader.h b/wiiu/ribbon_shader.h new file mode 100644 index 0000000000..c83fa9d1f4 --- /dev/null +++ b/wiiu/ribbon_shader.h @@ -0,0 +1,46 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2014-2018 - Ali Bouhlel + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + struct + { + float x; + float y; + float z; + }pos; +}ribbon_vertex_t; + +typedef struct +__attribute__((scalar_storage_order ("little-endian"))) +__attribute__((aligned (16))) +{ + float time; +}ribbon_uniform_t; + + +extern GX2Shader ribbon_shader; + +#ifdef __cplusplus +} +#endif diff --git a/wiiu/shaders/ribbon.frag b/wiiu/shaders/ribbon.frag new file mode 100644 index 0000000000..8c7aac21c1 --- /dev/null +++ b/wiiu/shaders/ribbon.frag @@ -0,0 +1,21 @@ +#version 150 + +uniform UBO +{ + float time; +} constants; + +layout(location = 0) in vec3 vEC; +layout(location = 0) out vec4 FragColor; + +void main() +{ + const vec3 up = vec3(0.0, 0.0, 1.0); + vec3 x = dFdx(vEC); + vec3 y = dFdy(vEC); + vec3 normal = normalize(cross(x, y)); + float c = 1.0 - dot(normal, up); + c = (1.0 - cos(c * c)) / 20.0; +// FragColor = vec4(c, c, c, 1.0); + FragColor = vec4(1.0, 1.0, 1.0, c); +} diff --git a/wiiu/shaders/ribbon.vert b/wiiu/shaders/ribbon.vert new file mode 100644 index 0000000000..f2bb7fb042 --- /dev/null +++ b/wiiu/shaders/ribbon.vert @@ -0,0 +1,53 @@ +#version 150 + +layout(location = 0) in vec3 VertexCoord; +layout(location = 0) out vec3 vEC; + +uniform UBO +{ + float time; +} constants; + +float iqhash(float n) +{ + return fract(sin(n) * 43758.5453); +} + +float noise(vec3 x) +{ + vec3 p = floor(x); + vec3 f = fract(x); + f = f * f * (3.0 - 2.0 * f); + float n = p.x + p.y * 57.0 + 113.0 * p.z; + return mix(mix(mix(iqhash(n), iqhash(n + 1.0), f.x), + mix(iqhash(n + 57.0), iqhash(n + 58.0), f.x), f.y), + mix(mix(iqhash(n + 113.0), iqhash(n + 114.0), f.x), + mix(iqhash(n + 170.0), iqhash(n + 171.0), f.x), f.y), f.z); +} + +float xmb_noise2(vec3 x) +{ + return cos(x.z * 4.0) * cos(x.z + constants.time / 10.0 + x.x); +} + +void main() +{ + vec3 v = vec3(VertexCoord.x, 0.0, VertexCoord.y); + vec3 v2 = v; + vec3 v3 = v; + + v.y = xmb_noise2(v2) / 8.0; + + v3.x -= constants.time / 5.0; + v3.x /= 4.0; + + v3.z -= constants.time / 10.0; + v3.y -= constants.time / 100.0; + + v.z -= noise(v3 * 7.0) / 15.0; + v.y -= noise(v3 * 7.0) / 15.0 + cos(v.x * 2.0 - constants.time / 2.0) / 5.0 - 0.3; + v.y = -v.y; + + vEC = v; + gl_Position = vec4(v, 1.0); +} diff --git a/wiiu/slang/Makefile b/wiiu/slang/Makefile index ed23d9cb37..64ad2fe4ff 100644 --- a/wiiu/slang/Makefile +++ b/wiiu/slang/Makefile @@ -1,8 +1,80 @@ -all: slang-convert +GLSLC = glslc -slang-convert: main.c - $(CC) $< -o $@ -g -O0 -Wall -Werror +GSH_COMPILER = ./compiler.exe +GSH_COMPILER_V = -v +GSH_COMPILER_P = -p +GSH_COMPILER_O = -o +GSH_COMPILER_ALIGN = -align -clean: - rm slang-convert main.o +SLANG_DIR = slang-shaders + +BLACKLIST := +BLACKLIST += $(SLANG_DIR)/dithering/shaders/bayer-matrix-dithering.slang +BLACKLIST += $(SLANG_DIR)/scalefx/shaders/old/scalefx-pass3.slang +BLACKLIST += $(SLANG_DIR)/scalefx/shaders/old/scalefx-pass7.slang +BLACKLIST += $(SLANG_DIR)/scalefx/shaders/scalefx-pass1.slang +BLACKLIST += $(SLANG_DIR)/scalefx/shaders/scalefx-pass2.slang +BLACKLIST += $(SLANG_DIR)/scalefx/shaders/scalefx-pass4.slang +BLACKLIST += $(SLANG_DIR)/scalefx/shaders/scalefx-pass4-hybrid.slang +BLACKLIST += $(SLANG_DIR)/test/decode-format.slang +BLACKLIST += $(SLANG_DIR)/test/format.slang +BLACKLIST += $(wildcard $(SLANG_DIR)/crt/shaders/crt-royale/src/*.slang) +BLACKLIST += $(SLANG_DIR)/slang-shaders/blurs/blur12x12shared.slang +BLACKLIST += $(SLANG_DIR)/blurs/blur5x5-gamma-encode-every-fbo.slang +BLACKLIST += $(SLANG_DIR)/blurs/blur12x12shared.slang +BLACKLIST += $(SLANG_DIR)/ntsc/shaders/ntsc-xot.slang +BLACKLIST += $(SLANG_DIR)/nedi/shaders/nedi-pass0.slang +BLACKLIST += $(SLANG_DIR)/nedi/shaders/nedi-pass1.slang +BLACKLIST += $(SLANG_DIR)/nedi/shaders/nedi-pass2.slang +BLACKLIST += $(wildcard $(SLANG_DIR)/anti-aliasing/shaders/smaa/*.slang) + +EXE_EXT := + +ifneq ($(findstring Linux,$(shell uname -a)),) +else ifneq ($(findstring Darwin,$(shell uname -a)),) +else +EXE_EXT := .exe +endif + +SLANG_PARSER = ./slang-parse$(EXE_EXT) + +rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) +SLANG_SHADERS := $(call rwildcard,$(SLANG_DIR)/,*.slang) +SLANG_SHADERS := $(filter-out $(BLACKLIST),$(SLANG_SHADERS)) +SLANG_SHADERS := $(SLANG_SHADERS:.slang=.gsh) + + + + +all: $(SLANG_SHADERS) +parser: $(SLANG_PARSER) + +$(SLANG_PARSER): slang-parse.cpp + $(CXX) $< -o $@ -g -O0 -Wall -I. + +shaders: $(SLANG_SHADERS) + +%.ppslang : %.slang + $(GLSLC) -E $< -o $@ + +%.vert %.frag: %.ppslang $(SLANG_PARSER) grammar.txt + $(SLANG_PARSER) --slang $< --vsh $*.vert --psh $*.frag + +%.gsh: %.vert %.frag + $(GSH_COMPILER) $(GSH_COMPILER_ALIGN) $(GSH_COMPILER_V) $*.vert $(GSH_COMPILER_P) $*.frag $(GSH_COMPILER_O) $@ + +.PRECIOUS: %.vert %.frag %.ppslang + +clean-shaders: + rm -rf $(SLANG_SHADERS) + +clean-temp: + rm -rf $(SLANG_SHADERS:.gsh=.ppslang) + rm -rf $(SLANG_SHADERS:.gsh=.vert) + rm -rf $(SLANG_SHADERS:.gsh=.frag) + +clean-parser: + rm -rf $(SLANG_PARSER) slang-parse.o + +clean: clean-parser clean-shaders clean-temp diff --git a/wiiu/slang/convert.sh b/wiiu/slang/convert.sh deleted file mode 100644 index 5837bff140..0000000000 --- a/wiiu/slang/convert.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -#### options #### - -slang_dir=slang-shaders -gshcompiler=$(pwd)/compiler.exe -vshflag=--vsh -pshflag=--psh -outputflag=--out -alignflag=--align - -################# - - -currentdir=$(pwd) - -die () -{ - echo error while converting $name - #mv -f tmp.vsh $currentdir - #mv -f tmp.psh $currentdir - #cp $1 $currentdir 2> /dev/null - #exit 1 -} - - -make - -cd $slang_dir -slang_dir=$(pwd) -slang_files=`find $slang_dir -name "*.slang"` - -for name in $slang_files ; do -echo $name -echo cd $(dirname $name) -cd $(dirname $name) -echo $currentdir/slang-convert --slang $name --vsh tmp.vsh --psh tmp.psh -$currentdir/slang-convert --slang $(basename $name) --vsh tmp.vsh --psh tmp.psh -echo $gshcompiler $alignflag $vshflag tmp.vsh $pshflag tmp.psh $outputflag `echo "$name" | sed "s/\.slang//"`.gsh -$gshcompiler $alignflag $vshflag tmp.vsh $pshflag tmp.psh $outputflag `echo "$name" | sed "s/\.slang//"`.gsh || die $name -rm -rf tmp.vsh tmp.psh -done diff --git a/wiiu/slang/grammar.txt b/wiiu/slang/grammar.txt new file mode 100644 index 0000000000..aab7c03a55 --- /dev/null +++ b/wiiu/slang/grammar.txt @@ -0,0 +1,55 @@ + +Program <- Version? (LineMarker / GoogleIncludeExtensionEnable / UniformBlock / Declaration / ConstArray / Stage / Indent / IgnoredKeyword / Line)* + +~LineMarker <- '#line' (!EndOfLine .)* EndOfLine +~GoogleIncludeExtensionEnable <- '#extension GL_GOOGLE_include_directive' (!EndOfLine .)* EndOfLine +Line <- <(!EndOfLine !EndOfFile .)*> (EndOfLine / EndOfFile) +~IgnoredKeyword <- !'const int' ('inline' / 'static ' / 'const ') +Version <- '#'_'version' Space+ <(!EndOfLine .)*> EndOfLine +Stage <- '#'_'pragma' Space+ 'stage' Space? <(!EndOfLine .)*> EndOfLine +#.*Include <- '#'_'include' _ '"' <(!'"' .)*> '"' _ EndOfLine + + +Declaration <- Layout? _ Qualifier Space _ Type Space _ Name _ ArraySize? _ EndOfStatement +ConstArray <- Type Space _ Name _ ArraySize? _ '=' _ Array _ EndOfStatement +UniformBlock <- Layout? _ 'uniform' _ StructName? _ '{' Member* '}' _ Name? _ EndOfStatement +Member <- (_ Type Space _ Name _ ArraySize? _ EndOfStatement? _ Comment?) +~Comment <- ('//' Line) + +Value <- (Float / Int / (!EndOfStatement .)*) +Array <- ('{' ( _ ArrayItem+ _ ',')* (_ ArrayItem+ _ )? '}') +ArrayItem <- <(!'}'!',' (groupedItem/.))+> +groupedItem <- '(' (!')' (groupedItem/.))+ ')' + +Qualifier <- 'in' / 'out' / 'uniform' +Type <- <'uint' / 'int' / 'ivec2' / 'ivec3' / 'ivec4' / + 'float' / 'vec2' / 'vec3' / 'vec4' / + 'bool' / 'bvec2' / 'bvec3' / 'bvec4' / + 'mat2x2' / 'mat2' / + 'mat3x2' / 'mat3x3' / 'mat3' / + 'mat4x2' / 'mat4x3' / 'mat4x4' / 'mat4' / + 'void' / 'sampler2D' / Name> +StructName <- +ArraySize <- '[' _ _ ']' +Name <- ([a-z]/[A-Z]/'_'/[0-9])+ +Layout <- 'layout' _ '(' ( _ (Location / Binding / Set / PushConstant / Std) _ ','?)+ ')' +Location <- 'location' _ '=' _ +Binding <- 'binding' _ '=' _ +Set <- 'set' _ '=' _ +PushConstant <- 'push_constant' +Std <- 'std' + + +#.*Block <- '{' (Directive/ Statement / Block _)* '}' + + +Float <- $< '-'? [0-9]+ '.' ([0-9]+ ('e-'[0-9]+)? )? 'f'? > +Int <- < '-'? [0-9]+ > +~EndOfStatement <- ';' +~EndOfLine <- '\r\n' / '\n' / '\r' +EndOfFile <- !. +End <- EndOfLine / EndOfFile +~_ <- [ \t\r\n]* +Indent <- [ \t] +~Space <- [ \t] + diff --git a/wiiu/slang/main.c b/wiiu/slang/main.c index d20e5f47ef..025495feaa 100644 --- a/wiiu/slang/main.c +++ b/wiiu/slang/main.c @@ -134,6 +134,8 @@ int main(int argc, const char** argv) fclose(vs_out_fp); fclose(ps_out_fp); + free(slang_buffer); + return 0; } diff --git a/wiiu/slang/peglib.h b/wiiu/slang/peglib.h new file mode 100644 index 0000000000..20b5080e1b --- /dev/null +++ b/wiiu/slang/peglib.h @@ -0,0 +1,2775 @@ +// +// peglib.h +// +// Copyright (c) 2015-17 Yuji Hirose. All rights reserved. +// MIT License +// + +#ifndef CPPPEGLIB_PEGLIB_H +#define CPPPEGLIB_PEGLIB_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// guard for older versions of VC++ +#ifdef _MSC_VER +// VS2013 has no constexpr +#if (_MSC_VER == 1800) +#define PEGLIB_NO_CONSTEXPR_SUPPORT +#elif (_MSC_VER >= 1800) +// good to go +#else (_MSC_VER < 1800) +#error "Requires C+11 support" +#endif +#endif + +// define if the compiler doesn't support unicode characters reliably in the +// source code +//#define PEGLIB_NO_UNICODE_CHARS + +namespace peg { + +#if __clang__ == 1 && __clang_major__ == 5 && __clang_minor__ == 0 && __clang_patchlevel__ == 0 +static void* enabler = nullptr; // workaround for Clang 5.0.0 +#else +extern void* enabler; +#endif + +/*----------------------------------------------------------------------------- + * any + *---------------------------------------------------------------------------*/ + +class any +{ +public: + any() : content_(nullptr) {} + + any(const any& rhs) : content_(rhs.clone()) {} + + any(any&& rhs) : content_(rhs.content_) { + rhs.content_ = nullptr; + } + + template + any(const T& value) : content_(new holder(value)) {} + + any& operator=(const any& rhs) { + if (this != &rhs) { + if (content_) { + delete content_; + } + content_ = rhs.clone(); + } + return *this; + } + + any& operator=(any&& rhs) { + if (this != &rhs) { + if (content_) { + delete content_; + } + content_ = rhs.content_; + rhs.content_ = nullptr; + } + return *this; + } + + ~any() { + delete content_; + } + + bool is_undefined() const { + return content_ == nullptr; + } + + template < + typename T, + typename std::enable_if::value>::type*& = enabler + > + T& get() { + if (!content_) { + throw std::bad_cast(); + } + auto p = dynamic_cast*>(content_); + assert(p); + if (!p) { + throw std::bad_cast(); + } + return p->value_; + } + + template < + typename T, + typename std::enable_if::value>::type*& = enabler + > + T& get() { + return *this; + } + + template < + typename T, + typename std::enable_if::value>::type*& = enabler + > + const T& get() const { + assert(content_); + auto p = dynamic_cast*>(content_); + assert(p); + if (!p) { + throw std::bad_cast(); + } + return p->value_; + } + + template < + typename T, + typename std::enable_if::value>::type*& = enabler + > + const any& get() const { + return *this; + } + +private: + struct placeholder { + virtual ~placeholder() {} + virtual placeholder* clone() const = 0; + }; + + template + struct holder : placeholder { + holder(const T& value) : value_(value) {} + placeholder* clone() const override { + return new holder(value_); + } + T value_; + }; + + placeholder* clone() const { + return content_ ? content_->clone() : nullptr; + } + + placeholder* content_; +}; + +/*----------------------------------------------------------------------------- + * scope_exit + *---------------------------------------------------------------------------*/ + +// This is based on "http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189". + +template +struct scope_exit +{ + explicit scope_exit(EF&& f) + : exit_function(std::move(f)) + , execute_on_destruction{true} {} + + scope_exit(scope_exit&& rhs) + : exit_function(std::move(rhs.exit_function)) + , execute_on_destruction{rhs.execute_on_destruction} { + rhs.release(); + } + + ~scope_exit() { + if (execute_on_destruction) { + this->exit_function(); + } + } + + void release() { + this->execute_on_destruction = false; + } + +private: + scope_exit(const scope_exit&) = delete; + void operator=(const scope_exit&) = delete; + scope_exit& operator=(scope_exit&&) = delete; + + EF exit_function; + bool execute_on_destruction; +}; + +template +auto make_scope_exit(EF&& exit_function) -> scope_exit { + return scope_exit::type>(std::forward(exit_function)); +} + +/*----------------------------------------------------------------------------- + * PEG + *---------------------------------------------------------------------------*/ + +/* +* Line information utility function +*/ +inline std::pair line_info(const char* start, const char* cur) { + auto p = start; + auto col_ptr = p; + auto no = 1; + + while (p < cur) { + if (*p == '\n') { + no++; + col_ptr = p + 1; + } + p++; + } + + auto col = p - col_ptr + 1; + + return std::make_pair(no, col); +} + +/* +* Semantic values +*/ +struct SemanticValues : protected std::vector +{ + // Input text + const char* path; + const char* ss; + + // Matched string + const char* c_str() const { return s_; } + size_t length() const { return n_; } + + std::string str() const { + return std::string(s_, n_); + } + + // Line number and column at which the matched string is + std::pair line_info() const { + return peg::line_info(ss, s_); + } + + // Choice number (0 based index) + size_t choice() const { return choice_; } + + // Tokens + std::vector> tokens; + + std::string token(size_t id = 0) const { + if (!tokens.empty()) { + assert(id < tokens.size()); + const auto& tok = tokens[id]; + return std::string(tok.first, tok.second); + } + return std::string(s_, n_); + } + + // Transform the semantic value vector to another vector + template + auto transform(size_t beg = 0, size_t end = static_cast(-1)) const -> vector { + return this->transform(beg, end, [](const any& v) { return v.get(); }); + } + + SemanticValues() : s_(nullptr), n_(0), choice_(0) {} + + using std::vector::iterator; + using std::vector::const_iterator; + using std::vector::size; + using std::vector::empty; + using std::vector::assign; + using std::vector::begin; + using std::vector::end; + using std::vector::rbegin; + using std::vector::rend; + using std::vector::operator[]; + using std::vector::at; + using std::vector::resize; + using std::vector::front; + using std::vector::back; + using std::vector::push_back; + using std::vector::pop_back; + using std::vector::insert; + using std::vector::erase; + using std::vector::clear; + using std::vector::swap; + using std::vector::emplace; + using std::vector::emplace_back; + +private: + friend class Context; + friend class PrioritizedChoice; + friend class Holder; + + const char* s_; + size_t n_; + size_t choice_; + + template + auto transform(F f) const -> vector::type> { + vector::type> r; + for (const auto& v: *this) { + r.emplace_back(f(v)); + } + return r; + } + + template + auto transform(size_t beg, size_t end, F f) const -> vector::type> { + vector::type> r; + end = (std::min)(end, size()); + for (size_t i = beg; i < end; i++) { + r.emplace_back(f((*this)[i])); + } + return r; + } +}; + +/* + * Semantic action + */ +template < + typename R, typename F, + typename std::enable_if::value>::type*& = enabler, + typename... Args> +any call(F fn, Args&&... args) { + fn(std::forward(args)...); + return any(); +} + +template < + typename R, typename F, + typename std::enable_if::type, any>::value>::type*& = enabler, + typename... Args> +any call(F fn, Args&&... args) { + return fn(std::forward(args)...); +} + +template < + typename R, typename F, + typename std::enable_if< + !std::is_void::value && + !std::is_same::type, any>::value>::type*& = enabler, + typename... Args> +any call(F fn, Args&&... args) { + return any(fn(std::forward(args)...)); +} + +class Action +{ +public: + Action() = default; + + Action(const Action& rhs) : fn_(rhs.fn_) {} + + template ::value && !std::is_same::value>::type*& = enabler> + Action(F fn) : fn_(make_adaptor(fn, &F::operator())) {} + + template ::value>::type*& = enabler> + Action(F fn) : fn_(make_adaptor(fn, fn)) {} + + template ::value>::type*& = enabler> + Action(F /*fn*/) {} + + template ::value && !std::is_same::value>::type*& = enabler> + void operator=(F fn) { + fn_ = make_adaptor(fn, &F::operator()); + } + + template ::value>::type*& = enabler> + void operator=(F fn) { + fn_ = make_adaptor(fn, fn); + } + + template ::value>::type*& = enabler> + void operator=(F /*fn*/) {} + + Action& operator=(const Action& rhs) = default; + + operator bool() const { + return bool(fn_); + } + + any operator()(const SemanticValues& sv, any& dt) const { + return fn_(sv, dt); + } + +private: + template + struct TypeAdaptor { + TypeAdaptor(std::function fn) + : fn_(fn) {} + any operator()(const SemanticValues& sv, any& /*dt*/) { + return call(fn_, sv); + } + std::function fn_; + }; + + template + struct TypeAdaptor_c { + TypeAdaptor_c(std::function fn) + : fn_(fn) {} + any operator()(const SemanticValues& sv, any& dt) { + return call(fn_, sv, dt); + } + std::function fn_; + }; + + typedef std::function Fty; + + template + Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv) const) { + return TypeAdaptor(fn); + } + + template + Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv)) { + return TypeAdaptor(fn); + } + + template + Fty make_adaptor(F fn, R (* /*mf*/)(const SemanticValues& sv)) { + return TypeAdaptor(fn); + } + + template + Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv, any& dt) const) { + return TypeAdaptor_c(fn); + } + + template + Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv, any& dt)) { + return TypeAdaptor_c(fn); + } + + template + Fty make_adaptor(F fn, R(* /*mf*/)(const SemanticValues& sv, any& dt)) { + return TypeAdaptor_c(fn); + } + + Fty fn_; +}; + +/* + * Semantic predicate + */ +// Note: 'parse_error' exception class should be be used in sematic action handlers to reject the rule. +struct parse_error { + parse_error() = default; + parse_error(const char* s) : s_(s) {} + const char* what() const { return s_.empty() ? nullptr : s_.c_str(); } +private: + std::string s_; +}; + +/* + * Match action + */ +typedef std::function MatchAction; + +/* + * Result + */ +inline bool success(size_t len) { + return len != static_cast(-1); +} + +inline bool fail(size_t len) { + return len == static_cast(-1); +} + +/* + * Context + */ +class Ope; +class Context; +class Definition; + +typedef std::function Tracer; + +class Context +{ +public: + const char* path; + const char* s; + const size_t l; + + const char* error_pos; + const char* message_pos; + std::string message; // TODO: should be `int`. + + std::vector> value_stack; + size_t value_stack_size; + + size_t nest_level; + + bool in_token; + + std::shared_ptr whitespaceOpe; + bool in_whitespace; + + const size_t def_count; + const bool enablePackratParsing; + std::vector cache_registered; + std::vector cache_success; + + std::map, std::tuple> cache_values; + + std::function tracer; + + Context( + const char* a_path, + const char* a_s, + size_t a_l, + size_t a_def_count, + std::shared_ptr a_whitespaceOpe, + bool a_enablePackratParsing, + Tracer a_tracer) + : path(a_path) + , s(a_s) + , l(a_l) + , error_pos(nullptr) + , message_pos(nullptr) + , value_stack_size(0) + , nest_level(0) + , in_token(false) + , whitespaceOpe(a_whitespaceOpe) + , in_whitespace(false) + , def_count(a_def_count) + , enablePackratParsing(a_enablePackratParsing) + , cache_registered(enablePackratParsing ? def_count * (l + 1) : 0) + , cache_success(enablePackratParsing ? def_count * (l + 1) : 0) + , tracer(a_tracer) + { + } + + template + void packrat(const char* a_s, size_t def_id, size_t& len, any& val, T fn) { + if (!enablePackratParsing) { + fn(val); + return; + } + + auto col = a_s - s; + auto idx = def_count * static_cast(col) + def_id; + + if (cache_registered[idx]) { + if (cache_success[idx]) { + auto key = std::make_pair(col, def_id); + std::tie(len, val) = cache_values[key]; + return; + } else { + len = static_cast(-1); + return; + } + } else { + fn(val); + cache_registered[idx] = true; + cache_success[idx] = success(len); + if (success(len)) { + auto key = std::make_pair(col, def_id); + cache_values[key] = std::make_pair(len, val); + } + return; + } + } + + SemanticValues& push() { + assert(value_stack_size <= value_stack.size()); + if (value_stack_size == value_stack.size()) { + value_stack.emplace_back(std::make_shared()); + } + auto& sv = *value_stack[value_stack_size++]; + if (!sv.empty()) { + sv.clear(); + } + sv.path = path; + sv.ss = s; + sv.s_ = nullptr; + sv.n_ = 0; + sv.tokens.clear(); + return sv; + } + + void pop() { + value_stack_size--; + } + + void set_error_pos(const char* a_s) { + if (error_pos < a_s) error_pos = a_s; + } + + void trace(const char* name, const char* a_s, size_t n, SemanticValues& sv, any& dt) const { + if (tracer) tracer(name, a_s, n, sv, *this, dt); + } +}; + +/* + * Parser operators + */ +class Ope +{ +public: + struct Visitor; + + virtual ~Ope() {} + virtual size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const = 0; + virtual void accept(Visitor& v) = 0; +}; + +class Sequence : public Ope +{ +public: + Sequence(const Sequence& rhs) : opes_(rhs.opes_) {} + +#if defined(_MSC_VER) && _MSC_VER < 1900 // Less than Visual Studio 2015 + // NOTE: Compiler Error C2797 on Visual Studio 2013 + // "The C++ compiler in Visual Studio does not implement list + // initialization inside either a member initializer list or a non-static + // data member initializer. Before Visual Studio 2013 Update 3, this was + // silently converted to a function call, which could lead to bad code + // generation. Visual Studio 2013 Update 3 reports this as an error." + template + Sequence(const Args& ...args) { + opes_ = std::vector>{ static_cast>(args)... }; + } +#else + template + Sequence(const Args& ...args) : opes_{ static_cast>(args)... } {} +#endif + + Sequence(const std::vector>& opes) : opes_(opes) {} + Sequence(std::vector>&& opes) : opes_(opes) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + c.trace("Sequence", s, n, sv, dt); + size_t i = 0; + for (const auto& ope : opes_) { + c.nest_level++; + auto se = make_scope_exit([&]() { c.nest_level--; }); + const auto& rule = *ope; + auto len = rule.parse(s + i, n - i, sv, c, dt); + if (fail(len)) { + return static_cast(-1); + } + i += len; + } + return i; + } + + void accept(Visitor& v) override; + + std::vector> opes_; +}; + +class PrioritizedChoice : public Ope +{ +public: +#if defined(_MSC_VER) && _MSC_VER < 1900 // Less than Visual Studio 2015 + // NOTE: Compiler Error C2797 on Visual Studio 2013 + // "The C++ compiler in Visual Studio does not implement list + // initialization inside either a member initializer list or a non-static + // data member initializer. Before Visual Studio 2013 Update 3, this was + // silently converted to a function call, which could lead to bad code + // generation. Visual Studio 2013 Update 3 reports this as an error." + template + PrioritizedChoice(const Args& ...args) { + opes_ = std::vector>{ static_cast>(args)... }; + } +#else + template + PrioritizedChoice(const Args& ...args) : opes_{ static_cast>(args)... } {} +#endif + + PrioritizedChoice(const std::vector>& opes) : opes_(opes) {} + PrioritizedChoice(std::vector>&& opes) : opes_(opes) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + c.trace("PrioritizedChoice", s, n, sv, dt); + size_t id = 0; + for (const auto& ope : opes_) { + c.nest_level++; + auto& chldsv = c.push(); + auto se = make_scope_exit([&]() { + c.nest_level--; + c.pop(); + }); + const auto& rule = *ope; + auto len = rule.parse(s, n, chldsv, c, dt); + if (success(len)) { + if (!chldsv.empty()) { + sv.insert(sv.end(), chldsv.begin(), chldsv.end()); + } + sv.s_ = chldsv.c_str(); + sv.n_ = chldsv.length(); + sv.choice_ = id; + sv.tokens.insert(sv.tokens.end(), chldsv.tokens.begin(), chldsv.tokens.end()); + return len; + } + id++; + } + return static_cast(-1); + } + + void accept(Visitor& v) override; + + size_t size() const { return opes_.size(); } + + std::vector> opes_; +}; + +class ZeroOrMore : public Ope +{ +public: + ZeroOrMore(const std::shared_ptr& ope) : ope_(ope) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + c.trace("ZeroOrMore", s, n, sv, dt); + auto save_error_pos = c.error_pos; + size_t i = 0; + while (n - i > 0) { + c.nest_level++; + auto se = make_scope_exit([&]() { c.nest_level--; }); + auto save_sv_size = sv.size(); + auto save_tok_size = sv.tokens.size(); + const auto& rule = *ope_; + auto len = rule.parse(s + i, n - i, sv, c, dt); + if (fail(len)) { + if (sv.size() != save_sv_size) { + sv.erase(sv.begin() + static_cast(save_sv_size)); + } + if (sv.tokens.size() != save_tok_size) { + sv.tokens.erase(sv.tokens.begin() + static_cast(save_tok_size)); + } + c.error_pos = save_error_pos; + break; + } + i += len; + } + return i; + } + + void accept(Visitor& v) override; + + std::shared_ptr ope_; +}; + +class OneOrMore : public Ope +{ +public: + OneOrMore(const std::shared_ptr& ope) : ope_(ope) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + c.trace("OneOrMore", s, n, sv, dt); + size_t len = 0; + { + c.nest_level++; + auto se = make_scope_exit([&]() { c.nest_level--; }); + const auto& rule = *ope_; + len = rule.parse(s, n, sv, c, dt); + if (fail(len)) { + return static_cast(-1); + } + } + auto save_error_pos = c.error_pos; + auto i = len; + while (n - i > 0) { + c.nest_level++; + auto se = make_scope_exit([&]() { c.nest_level--; }); + auto save_sv_size = sv.size(); + auto save_tok_size = sv.tokens.size(); + const auto& rule = *ope_; + len = rule.parse(s + i, n - i, sv, c, dt); + if (fail(len)) { + if (sv.size() != save_sv_size) { + sv.erase(sv.begin() + static_cast(save_sv_size)); + } + if (sv.tokens.size() != save_tok_size) { + sv.tokens.erase(sv.tokens.begin() + static_cast(save_tok_size)); + } + c.error_pos = save_error_pos; + break; + } + i += len; + } + return i; + } + + void accept(Visitor& v) override; + + std::shared_ptr ope_; +}; + +class Option : public Ope +{ +public: + Option(const std::shared_ptr& ope) : ope_(ope) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + c.trace("Option", s, n, sv, dt); + auto save_error_pos = c.error_pos; + c.nest_level++; + auto save_sv_size = sv.size(); + auto save_tok_size = sv.tokens.size(); + auto se = make_scope_exit([&]() { c.nest_level--; }); + const auto& rule = *ope_; + auto len = rule.parse(s, n, sv, c, dt); + if (success(len)) { + return len; + } else { + if (sv.size() != save_sv_size) { + sv.erase(sv.begin() + static_cast(save_sv_size)); + } + if (sv.tokens.size() != save_tok_size) { + sv.tokens.erase(sv.tokens.begin() + static_cast(save_tok_size)); + } + c.error_pos = save_error_pos; + return 0; + } + } + + void accept(Visitor& v) override; + + std::shared_ptr ope_; +}; + +class AndPredicate : public Ope +{ +public: + AndPredicate(const std::shared_ptr& ope) : ope_(ope) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + c.trace("AndPredicate", s, n, sv, dt); + c.nest_level++; + auto& chldsv = c.push(); + auto se = make_scope_exit([&]() { + c.nest_level--; + c.pop(); + }); + const auto& rule = *ope_; + auto len = rule.parse(s, n, chldsv, c, dt); + if (success(len)) { + return 0; + } else { + return static_cast(-1); + } + } + + void accept(Visitor& v) override; + + std::shared_ptr ope_; +}; + +class NotPredicate : public Ope +{ +public: + NotPredicate(const std::shared_ptr& ope) : ope_(ope) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + c.trace("NotPredicate", s, n, sv, dt); + auto save_error_pos = c.error_pos; + c.nest_level++; + auto& chldsv = c.push(); + auto se = make_scope_exit([&]() { + c.nest_level--; + c.pop(); + }); + const auto& rule = *ope_; + auto len = rule.parse(s, n, chldsv, c, dt); + if (success(len)) { + c.set_error_pos(s); + return static_cast(-1); + } else { + c.error_pos = save_error_pos; + return 0; + } + } + + void accept(Visitor& v) override; + + std::shared_ptr ope_; +}; + +class LiteralString : public Ope +{ +public: + LiteralString(const std::string& s) : lit_(s) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override; + + void accept(Visitor& v) override; + + std::string lit_; +}; + +class CharacterClass : public Ope +{ +public: + CharacterClass(const std::string& chars) : chars_(chars) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + c.trace("CharacterClass", s, n, sv, dt); + // TODO: UTF8 support + if (n < 1) { + c.set_error_pos(s); + return static_cast(-1); + } + auto ch = s[0]; + auto i = 0u; + while (i < chars_.size()) { + if (i + 2 < chars_.size() && chars_[i + 1] == '-') { + if (chars_[i] <= ch && ch <= chars_[i + 2]) { + return 1; + } + i += 3; + } else { + if (chars_[i] == ch) { + return 1; + } + i += 1; + } + } + c.set_error_pos(s); + return static_cast(-1); + } + + void accept(Visitor& v) override; + + std::string chars_; +}; + +class Character : public Ope +{ +public: + Character(char ch) : ch_(ch) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + c.trace("Character", s, n, sv, dt); + // TODO: UTF8 support + if (n < 1 || s[0] != ch_) { + c.set_error_pos(s); + return static_cast(-1); + } + return 1; + } + + void accept(Visitor& v) override; + + char ch_; +}; + +class AnyCharacter : public Ope +{ +public: + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + c.trace("AnyCharacter", s, n, sv, dt); + // TODO: UTF8 support + if (n < 1) { + c.set_error_pos(s); + return static_cast(-1); + } + return 1; + } + + void accept(Visitor& v) override; +}; + +class Capture : public Ope +{ +public: + Capture(const std::shared_ptr& ope, MatchAction ma, size_t id, const std::string& name) + : ope_(ope), match_action_(ma), id_(id), name_(name) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + const auto& rule = *ope_; + auto len = rule.parse(s, n, sv, c, dt); + if (success(len) && match_action_) { + match_action_(s, len, id_, name_); + } + return len; + } + + void accept(Visitor& v) override; + + std::shared_ptr ope_; + +private: + MatchAction match_action_; + size_t id_; + std::string name_; +}; + +class TokenBoundary : public Ope +{ +public: + TokenBoundary(const std::shared_ptr& ope) : ope_(ope) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override; + + void accept(Visitor& v) override; + + std::shared_ptr ope_; +}; + +class Ignore : public Ope +{ +public: + Ignore(const std::shared_ptr& ope) : ope_(ope) {} + + size_t parse(const char* s, size_t n, SemanticValues& /*sv*/, Context& c, any& dt) const override { + const auto& rule = *ope_; + auto& chldsv = c.push(); + auto se = make_scope_exit([&]() { + c.pop(); + }); + return rule.parse(s, n, chldsv, c, dt); + } + + void accept(Visitor& v) override; + + std::shared_ptr ope_; +}; + +typedef std::function Parser; + +class WeakHolder : public Ope +{ +public: + WeakHolder(const std::shared_ptr& ope) : weak_(ope) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + auto ope = weak_.lock(); + assert(ope); + const auto& rule = *ope; + return rule.parse(s, n, sv, c, dt); + } + + void accept(Visitor& v) override; + + std::weak_ptr weak_; +}; + +class Holder : public Ope +{ +public: + Holder(Definition* outer) + : outer_(outer) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override; + + void accept(Visitor& v) override; + + any reduce(const SemanticValues& sv, any& dt) const; + + std::shared_ptr ope_; + Definition* outer_; + + friend class Definition; +}; + +class DefinitionReference : public Ope +{ +public: + DefinitionReference( + const std::unordered_map& grammar, const std::string& name, const char* s) + : grammar_(grammar) + , name_(name) + , s_(s) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override; + + void accept(Visitor& v) override; + + std::shared_ptr get_rule() const; + + const std::unordered_map& grammar_; + const std::string name_; + const char* s_; + +private: + mutable std::once_flag init_; + mutable std::shared_ptr rule_; +}; + +class Whitespace : public Ope +{ +public: + Whitespace(const std::shared_ptr& ope) : ope_(ope) {} + + size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { + if (c.in_whitespace) { + return 0; + } + c.in_whitespace = true; + auto se = make_scope_exit([&]() { c.in_whitespace = false; }); + const auto& rule = *ope_; + return rule.parse(s, n, sv, c, dt); + } + + void accept(Visitor& v) override; + + std::shared_ptr ope_; +}; + +/* + * Visitor + */ +struct Ope::Visitor +{ + virtual ~Visitor() {} + virtual void visit(Sequence& /*ope*/) {} + virtual void visit(PrioritizedChoice& /*ope*/) {} + virtual void visit(ZeroOrMore& /*ope*/) {} + virtual void visit(OneOrMore& /*ope*/) {} + virtual void visit(Option& /*ope*/) {} + virtual void visit(AndPredicate& /*ope*/) {} + virtual void visit(NotPredicate& /*ope*/) {} + virtual void visit(LiteralString& /*ope*/) {} + virtual void visit(CharacterClass& /*ope*/) {} + virtual void visit(Character& /*ope*/) {} + virtual void visit(AnyCharacter& /*ope*/) {} + virtual void visit(Capture& /*ope*/) {} + virtual void visit(TokenBoundary& /*ope*/) {} + virtual void visit(Ignore& /*ope*/) {} + virtual void visit(WeakHolder& /*ope*/) {} + virtual void visit(Holder& /*ope*/) {} + virtual void visit(DefinitionReference& /*ope*/) {} + virtual void visit(Whitespace& /*ope*/) {} +}; + +struct AssignIDToDefinition : public Ope::Visitor +{ + using Ope::Visitor::visit; + + void visit(Sequence& ope) override { + for (auto op: ope.opes_) { + op->accept(*this); + } + } + void visit(PrioritizedChoice& ope) override { + for (auto op: ope.opes_) { + op->accept(*this); + } + } + void visit(ZeroOrMore& ope) override { ope.ope_->accept(*this); } + void visit(OneOrMore& ope) override { ope.ope_->accept(*this); } + void visit(Option& ope) override { ope.ope_->accept(*this); } + void visit(AndPredicate& ope) override { ope.ope_->accept(*this); } + void visit(NotPredicate& ope) override { ope.ope_->accept(*this); } + void visit(Capture& ope) override { ope.ope_->accept(*this); } + void visit(TokenBoundary& ope) override { ope.ope_->accept(*this); } + void visit(Ignore& ope) override { ope.ope_->accept(*this); } + void visit(WeakHolder& ope) override { ope.weak_.lock()->accept(*this); } + void visit(Holder& ope) override; + void visit(DefinitionReference& ope) override { ope.get_rule()->accept(*this); } + + std::unordered_map ids; +}; + +struct IsToken : public Ope::Visitor +{ + IsToken() : has_token_boundary(false), has_rule(false) {} + + using Ope::Visitor::visit; + + void visit(Sequence& ope) override { + for (auto op: ope.opes_) { + op->accept(*this); + } + } + void visit(PrioritizedChoice& ope) override { + for (auto op: ope.opes_) { + op->accept(*this); + } + } + void visit(ZeroOrMore& ope) override { ope.ope_->accept(*this); } + void visit(OneOrMore& ope) override { ope.ope_->accept(*this); } + void visit(Option& ope) override { ope.ope_->accept(*this); } + void visit(Capture& ope) override { ope.ope_->accept(*this); } + void visit(TokenBoundary& /*ope*/) override { has_token_boundary = true; } + void visit(Ignore& ope) override { ope.ope_->accept(*this); } + void visit(WeakHolder& ope) override { ope.weak_.lock()->accept(*this); } + void visit(DefinitionReference& /*ope*/) override { has_rule = true; } + + bool is_token() const { + return has_token_boundary || !has_rule; + } + + bool has_token_boundary; + bool has_rule; +}; + +static const char* WHITESPACE_DEFINITION_NAME = "%whitespace"; + +/* + * Definition + */ +class Definition +{ +public: + struct Result { + bool ret; + size_t len; + const char* error_pos; + const char* message_pos; + const std::string message; + }; + + Definition() + : ignoreSemanticValue(false) + , enablePackratParsing(false) + , is_token(false) + , has_token_boundary(false) + , holder_(std::make_shared(this)) {} + + Definition(const Definition& rhs) + : name(rhs.name) + , ignoreSemanticValue(false) + , enablePackratParsing(false) + , is_token(false) + , has_token_boundary(false) + , holder_(rhs.holder_) + { + holder_->outer_ = this; + } + + Definition(Definition&& rhs) + : name(std::move(rhs.name)) + , ignoreSemanticValue(rhs.ignoreSemanticValue) + , whitespaceOpe(rhs.whitespaceOpe) + , enablePackratParsing(rhs.enablePackratParsing) + , is_token(rhs.is_token) + , has_token_boundary(rhs.has_token_boundary) + , holder_(std::move(rhs.holder_)) + { + holder_->outer_ = this; + } + + Definition(const std::shared_ptr& ope) + : ignoreSemanticValue(false) + , enablePackratParsing(false) + , is_token(false) + , has_token_boundary(false) + , holder_(std::make_shared(this)) + { + *this <= ope; + } + + operator std::shared_ptr() { + return std::make_shared(holder_); + } + + Definition& operator<=(const std::shared_ptr& ope) { + IsToken isToken; + ope->accept(isToken); + is_token = isToken.is_token(); + has_token_boundary = isToken.has_token_boundary; + + holder_->ope_ = ope; + + return *this; + } + + Result parse(const char* s, size_t n, const char* path = nullptr) const { + SemanticValues sv; + any dt; + return parse_core(s, n, sv, dt, path); + } + + Result parse(const char* s, const char* path = nullptr) const { + auto n = strlen(s); + return parse(s, n, path); + } + + Result parse(const char* s, size_t n, any& dt, const char* path = nullptr) const { + SemanticValues sv; + return parse_core(s, n, sv, dt, path); + } + + Result parse(const char* s, any& dt, const char* path = nullptr) const { + auto n = strlen(s); + return parse(s, n, dt, path); + } + + template + Result parse_and_get_value(const char* s, size_t n, T& val, const char* path = nullptr) const { + SemanticValues sv; + any dt; + auto r = parse_core(s, n, sv, dt, path); + if (r.ret && !sv.empty() && !sv.front().is_undefined()) { + val = sv[0].get(); + } + return r; + } + + template + Result parse_and_get_value(const char* s, T& val, const char* path = nullptr) const { + auto n = strlen(s); + return parse_and_get_value(s, n, val, path); + } + + template + Result parse_and_get_value(const char* s, size_t n, any& dt, T& val, const char* path = nullptr) const { + SemanticValues sv; + auto r = parse_core(s, n, sv, dt, path); + if (r.ret && !sv.empty() && !sv.front().is_undefined()) { + val = sv[0].get(); + } + return r; + } + + template + Result parse_and_get_value(const char* s, any& dt, T& val, const char* path = nullptr) const { + auto n = strlen(s); + return parse_and_get_value(s, n, dt, val, path); + } + + Definition& operator=(Action a) { + action = a; + return *this; + } + + template + Definition& operator,(T fn) { + operator=(fn); + return *this; + } + + Definition& operator~() { + ignoreSemanticValue = true; + return *this; + } + + void accept(Ope::Visitor& v) { + holder_->accept(v); + } + + std::shared_ptr get_core_operator() { + return holder_->ope_; + } + + std::string name; + size_t id; + Action action; + std::function enter; + std::function leave; + std::function error_message; + bool ignoreSemanticValue; + std::shared_ptr whitespaceOpe; + bool enablePackratParsing; + bool is_token; + bool has_token_boundary; + Tracer tracer; + +private: + friend class DefinitionReference; + + Definition& operator=(const Definition& rhs); + Definition& operator=(Definition&& rhs); + + Result parse_core(const char* s, size_t n, SemanticValues& sv, any& dt, const char* path) const { + AssignIDToDefinition assignId; + holder_->accept(assignId); + + std::shared_ptr ope = holder_; + if (whitespaceOpe) { + ope = std::make_shared(whitespaceOpe, ope); + } + + Context cxt(path, s, n, assignId.ids.size(), whitespaceOpe, enablePackratParsing, tracer); + auto len = ope->parse(s, n, sv, cxt, dt); + return Result{ success(len), len, cxt.error_pos, cxt.message_pos, cxt.message }; + } + + std::shared_ptr holder_; +}; + +/* + * Implementations + */ + +inline size_t LiteralString::parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const { + c.trace("LiteralString", s, n, sv, dt); + + size_t i = 0; + for (; i < lit_.size(); i++) { + if (i >= n || s[i] != lit_[i]) { + c.set_error_pos(s); + return static_cast(-1); + } + } + + // Skip whiltespace + if (!c.in_token) { + if (c.whitespaceOpe) { + auto len = c.whitespaceOpe->parse(s + i, n - i, sv, c, dt); + if (fail(len)) { + return static_cast(-1); + } + i += len; + } + } + + return i; +} + +inline size_t TokenBoundary::parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const { + c.in_token = true; + auto se = make_scope_exit([&]() { c.in_token = false; }); + const auto& rule = *ope_; + auto len = rule.parse(s, n, sv, c, dt); + if (success(len)) { + sv.tokens.push_back(std::make_pair(s, len)); + + if (c.whitespaceOpe) { + auto l = c.whitespaceOpe->parse(s + len, n - len, sv, c, dt); + if (fail(l)) { + return static_cast(-1); + } + len += l; + } + } + return len; +} + +inline size_t Holder::parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const { + if (!ope_) { + throw std::logic_error("Uninitialized definition ope was used..."); + } + + c.trace(outer_->name.c_str(), s, n, sv, dt); + c.nest_level++; + auto se = make_scope_exit([&]() { c.nest_level--; }); + + size_t len; + any val; + + c.packrat(s, outer_->id, len, val, [&](any& a_val) { + auto& chldsv = c.push(); + + if (outer_->enter) { + outer_->enter(dt); + } + + auto se2 = make_scope_exit([&]() { + c.pop(); + + if (outer_->leave) { + outer_->leave(dt); + } + }); + + const auto& rule = *ope_; + len = rule.parse(s, n, chldsv, c, dt); + + // Invoke action + if (success(len)) { + chldsv.s_ = s; + chldsv.n_ = len; + + try { + a_val = reduce(chldsv, dt); + } catch (const parse_error& e) { + if (e.what()) { + if (c.message_pos < s) { + c.message_pos = s; + c.message = e.what(); + } + } + len = static_cast(-1); + } + } + }); + + if (success(len)) { + if (!outer_->ignoreSemanticValue) { + sv.emplace_back(val); + } + } else { + if (outer_->error_message) { + if (c.message_pos < s) { + c.message_pos = s; + c.message = outer_->error_message(); + } + } + } + + return len; +} + +inline any Holder::reduce(const SemanticValues& sv, any& dt) const { + if (outer_->action) { + return outer_->action(sv, dt); + } else if (sv.empty()) { + return any(); + } else { + return sv.front(); + } +} + +inline size_t DefinitionReference::parse( + const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const { + const auto& rule = *get_rule(); + return rule.parse(s, n, sv, c, dt); +} + +inline std::shared_ptr DefinitionReference::get_rule() const { + if (!rule_) { + std::call_once(init_, [this]() { + rule_ = grammar_.at(name_).holder_; + }); + } + assert(rule_); + return rule_; +} + +inline void Sequence::accept(Visitor& v) { v.visit(*this); } +inline void PrioritizedChoice::accept(Visitor& v) { v.visit(*this); } +inline void ZeroOrMore::accept(Visitor& v) { v.visit(*this); } +inline void OneOrMore::accept(Visitor& v) { v.visit(*this); } +inline void Option::accept(Visitor& v) { v.visit(*this); } +inline void AndPredicate::accept(Visitor& v) { v.visit(*this); } +inline void NotPredicate::accept(Visitor& v) { v.visit(*this); } +inline void LiteralString::accept(Visitor& v) { v.visit(*this); } +inline void CharacterClass::accept(Visitor& v) { v.visit(*this); } +inline void Character::accept(Visitor& v) { v.visit(*this); } +inline void AnyCharacter::accept(Visitor& v) { v.visit(*this); } +inline void Capture::accept(Visitor& v) { v.visit(*this); } +inline void TokenBoundary::accept(Visitor& v) { v.visit(*this); } +inline void Ignore::accept(Visitor& v) { v.visit(*this); } +inline void WeakHolder::accept(Visitor& v) { v.visit(*this); } +inline void Holder::accept(Visitor& v) { v.visit(*this); } +inline void DefinitionReference::accept(Visitor& v) { v.visit(*this); } +inline void Whitespace::accept(Visitor& v) { v.visit(*this); } + +inline void AssignIDToDefinition::visit(Holder& ope) { + auto p = static_cast(ope.outer_); + if (ids.count(p)) { + return; + } + auto id = ids.size(); + ids[p] = id; + ope.outer_->id = id; + ope.ope_->accept(*this); +} + +/* + * Factories + */ +template +std::shared_ptr seq(Args&& ...args) { + return std::make_shared(static_cast>(args)...); +} + +template +std::shared_ptr cho(Args&& ...args) { + return std::make_shared(static_cast>(args)...); +} + +inline std::shared_ptr zom(const std::shared_ptr& ope) { + return std::make_shared(ope); +} + +inline std::shared_ptr oom(const std::shared_ptr& ope) { + return std::make_shared(ope); +} + +inline std::shared_ptr opt(const std::shared_ptr& ope) { + return std::make_shared