(3DS) Sanitise/Improve display mode selection

This commit is contained in:
jdgleaver 2019-04-15 17:05:55 +01:00
parent 3d7eb19abd
commit 54e1711f9a
30 changed files with 332 additions and 115 deletions

View file

@ -32,6 +32,11 @@
#include "network/netplay/netplay.h"
#endif
/* Required for 3DS display mode setting */
#if defined(_3DS)
#include "gfx/common/ctr_common.h"
#endif
#if defined(HW_RVL)
#define MAX_GAMMA_SETTING 30
#elif defined(GEKKO)
@ -518,9 +523,11 @@ static const float crt_refresh_rate = 60/1.001;
* Used for setups where one manually rotates the monitor. */
static const bool allow_rotate = true;
#ifdef _3DS
#if defined(_3DS)
/* Enable bottom LCD screen */
static const bool video_3ds_lcd_bottom = true;
/* Sets video display mode (3D, 2D, etc.) */
static const unsigned video_3ds_display_mode = CTR_VIDEO_MODE_3D;
#endif
/* AUDIO */

View file

@ -1783,6 +1783,10 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
SETTING_UINT("libnx_overclock", &settings->uints.libnx_overclock, true, SWITCH_DEFAULT_CPU_PROFILE, false);
#endif
#ifdef _3DS
SETTING_UINT("video_3ds_display_mode", &settings->uints.video_3ds_display_mode, true, video_3ds_display_mode, false);
#endif
#ifdef HAVE_MENU
SETTING_UINT("playlist_show_inline_core_name", &settings->uints.playlist_show_inline_core_name, true, playlist_show_inline_core_name, false);
SETTING_UINT("playlist_sublabel_runtime_type", &settings->uints.playlist_sublabel_runtime_type, true, playlist_sublabel_runtime_type, false);

View file

@ -430,6 +430,7 @@ typedef struct settings
unsigned video_stream_quality;
unsigned video_record_scale_factor;
unsigned video_stream_scale_factor;
unsigned video_3ds_display_mode;
unsigned menu_timedate_style;
unsigned menu_thumbnails;

View file

@ -133,6 +133,7 @@ static void frontend_ctr_deinit(void* data)
Handle lcd_handle;
u32 parallax_layer_reg_state;
u8 not_2DS;
u8 device_model = 0xFF;
extern PrintConsole* currentConsole;
@ -167,8 +168,16 @@ static void frontend_ctr_deinit(void* data)
svcCloseHandle(lcd_handle);
}
parallax_layer_reg_state = (*(float*)0x1FF81080 == 0.0) ? 0x0 : 0x00010001;
GSPGPU_WriteHWRegs(0x202000, &parallax_layer_reg_state, 4);
/* Only O3DS and O3DSXL support running in 'dual-framebuffer'
* mode with the parallax barrier disabled
* (i.e. these are the only platforms that can use
* CTR_VIDEO_MODE_2D_400x240 and CTR_VIDEO_MODE_2D_800x240) */
CFGU_GetSystemModel(&device_model); /* (0 = O3DS, 1 = O3DSXL, 2 = N3DS, 3 = 2DS, 4 = N3DSXL, 5 = N2DSXL) */
if ((device_model == 0) || (device_model == 1))
{
parallax_layer_reg_state = (*(float*)0x1FF81080 == 0.0) ? 0x0 : 0x00010001;
GSPGPU_WriteHWRegs(0x202000, &parallax_layer_reg_state, 4);
}
mcuHwcExit();
ptmuExit();

View file

@ -42,11 +42,12 @@ typedef struct
typedef enum
{
CTR_VIDEO_MODE_NORMAL,
CTR_VIDEO_MODE_800x240,
CTR_VIDEO_MODE_400x240,
CTR_VIDEO_MODE_3D
}ctr_video_mode_enum;
CTR_VIDEO_MODE_3D = 0,
CTR_VIDEO_MODE_2D,
CTR_VIDEO_MODE_2D_400x240,
CTR_VIDEO_MODE_2D_800x240,
CTR_VIDEO_MODE_LAST
} ctr_video_mode_enum;
typedef struct ctr_video
{
@ -95,8 +96,9 @@ typedef struct ctr_video
unsigned rotation;
bool keep_aspect;
bool should_resize;
bool lcd_buttom_on;
bool msg_rendering_enabled;
bool supports_parallax_disable;
bool enable_3d;
void* empty_framebuffer;

View file

@ -53,46 +53,59 @@
* when reinitialising... */
static bool ctr_bottom_screen_enabled = true;
static INLINE void ctr_check_3D_slider(ctr_video_t* ctr)
static INLINE void ctr_check_3D_slider(ctr_video_t* ctr, ctr_video_mode_enum video_mode)
{
float slider_val = *(float*)0x1FF81080;
ctr_video_mode_enum old_mode = ctr->video_mode;
if (slider_val == 0.0)
ctr->video_mode = CTR_VIDEO_MODE_NORMAL;
else if (slider_val < 0.2)
ctr->video_mode = CTR_VIDEO_MODE_800x240;
else if (slider_val < 0.5)
ctr->video_mode = CTR_VIDEO_MODE_400x240;
else
ctr->video_mode = CTR_VIDEO_MODE_3D;
if (ctr->video_mode)
if (slider_val == 0.0f)
{
switch (ctr->video_mode)
{
case CTR_VIDEO_MODE_800x240:
case CTR_VIDEO_MODE_400x240:
ctr_set_parallax_layer(false);
break;
case CTR_VIDEO_MODE_3D:
{
s16 offset = (slider_val - 0.6) * 10.0;
ctr->frame_coords[1] = ctr->frame_coords[0];
ctr->frame_coords[2] = ctr->frame_coords[0];
ctr->video_mode = CTR_VIDEO_MODE_2D;
ctr->enable_3d = false;
return;
}
ctr->frame_coords[1].x0 -= offset;
ctr->frame_coords[1].x1 -= offset;
ctr->frame_coords[2].x0 += offset;
ctr->frame_coords[2].x1 += offset;
switch (video_mode)
{
case CTR_VIDEO_MODE_3D:
{
s16 offset = slider_val * 10.0f;
GSPGPU_FlushDataCache(ctr->frame_coords, 3 * sizeof(ctr_vertex_t));
ctr->video_mode = CTR_VIDEO_MODE_3D;
ctr->frame_coords[1] = ctr->frame_coords[0];
ctr->frame_coords[2] = ctr->frame_coords[0];
ctr->frame_coords[1].x0 -= offset;
ctr->frame_coords[1].x1 -= offset;
ctr->frame_coords[2].x0 += offset;
ctr->frame_coords[2].x1 += offset;
GSPGPU_FlushDataCache(ctr->frame_coords, 3 * sizeof(ctr_vertex_t));
if (ctr->supports_parallax_disable)
ctr_set_parallax_layer(true);
break;
}
default:
break;
}
ctr->enable_3d = true;
}
break;
case CTR_VIDEO_MODE_2D_400x240:
case CTR_VIDEO_MODE_2D_800x240:
if (ctr->supports_parallax_disable)
{
ctr->video_mode = video_mode;
ctr_set_parallax_layer(false);
ctr->enable_3d = true;
}
else
{
ctr->video_mode = CTR_VIDEO_MODE_2D;
ctr->enable_3d = false;
}
break;
case CTR_VIDEO_MODE_2D:
default:
ctr->video_mode = CTR_VIDEO_MODE_2D;
ctr->enable_3d = false;
break;
}
}
@ -128,13 +141,12 @@ static INLINE void ctr_set_screen_coords(ctr_video_t * ctr)
}
}
static void ctr_update_viewport(ctr_video_t* ctr, video_frame_info_t *video_info)
static void ctr_update_viewport(ctr_video_t* ctr, settings_t *settings, video_frame_info_t *video_info)
{
int x = 0;
int y = 0;
float width = ctr->vp.full_width;
float height = ctr->vp.full_height;
settings_t *settings = config_get_ptr();
float desired_aspect = video_driver_get_aspect_ratio();
if(ctr->rotation & 0x1)
@ -248,7 +260,7 @@ static void ctr_lcd_aptHook(APT_HookType hook, void* param)
ctr->p3d_event_pending = false;
}
if((hook == APTHOOK_ONSUSPEND) && (ctr->video_mode == CTR_VIDEO_MODE_400x240))
if((hook == APTHOOK_ONSUSPEND) && (ctr->video_mode == CTR_VIDEO_MODE_2D_400x240))
{
memcpy(gfxTopRightFramebuffers[ctr->current_buffer_top],
gfxTopLeftFramebuffers[ctr->current_buffer_top],
@ -256,7 +268,7 @@ static void ctr_lcd_aptHook(APT_HookType hook, void* param)
GSPGPU_FlushDataCache(gfxTopRightFramebuffers[ctr->current_buffer_top], 400 * 240 * 3);
}
if ((hook == APTHOOK_ONSUSPEND))
if ((hook == APTHOOK_ONSUSPEND) && ctr->supports_parallax_disable)
ctr_set_parallax_layer(*(float*)0x1FF81080 != 0.0);
if((hook == APTHOOK_ONSUSPEND) || (hook == APTHOOK_ONRESTORE))
@ -317,9 +329,10 @@ static void* ctr_init(const video_info_t* video,
const input_driver_t** input, void** input_data)
{
float refresh_rate;
void* ctrinput = NULL;
u8 device_model = 0xFF;
void* ctrinput = NULL;
settings_t *settings = config_get_ptr();
ctr_video_t* ctr = (ctr_video_t*)linearAlloc(sizeof(ctr_video_t));
ctr_video_t* ctr = (ctr_video_t*)linearAlloc(sizeof(ctr_video_t));
if (!ctr)
return NULL;
@ -455,9 +468,15 @@ static void* ctr_init(const video_info_t* video,
ctr->should_resize = true;
ctr->smooth = video->smooth;
ctr->vsync = video->vsync;
ctr->lcd_buttom_on = true; /* Unused */
ctr->current_buffer_top = 0;
/* Only O3DS and O3DSXL support running in 'dual-framebuffer'
* mode with the parallax barrier disabled
* (i.e. these are the only platforms that can use
* CTR_VIDEO_MODE_2D_400x240 and CTR_VIDEO_MODE_2D_800x240) */
CFGU_GetSystemModel(&device_model); /* (0 = O3DS, 1 = O3DSXL, 2 = N3DS, 3 = 2DS, 4 = N3DSXL, 5 = N2DSXL) */
ctr->supports_parallax_disable = (device_model == 0) || (device_model == 1);
ctr->empty_framebuffer = linearAlloc(320 * 240 * 2);
memset(ctr->empty_framebuffer, 0, 320 * 240 * 2);
@ -500,6 +519,7 @@ static bool ctr_frame(void* data, const void* frame,
extern u8* gfxSharedMemory;
extern u8 gfxThreadID;
uint32_t state_tmp = 0;
settings_t *settings = config_get_ptr();
ctr_video_t *ctr = (ctr_video_t*)data;
static float fps = 0.0;
static int total_frames = 0;
@ -507,7 +527,7 @@ static bool ctr_frame(void* data, const void* frame,
extern bool select_pressed;
if (!width || !height)
if (!width || !height || !settings)
{
gspWaitForEvent(GSPGPU_EVENT_VBlank0, true);
return true;
@ -542,7 +562,6 @@ static bool ctr_frame(void* data, const void* frame,
gspWaitForEvent(GSPGPU_EVENT_PPF, false);
ctr->ppf_event_pending = false;
}
frames++;
#ifndef HAVE_THREADS
if(task_queue_find(&ctr_tasks_finder_data))
{
@ -564,68 +583,74 @@ static bool ctr_frame(void* data, const void* frame,
ctr->vsync_event_pending = true;
currentTick = svcGetSystemTick();
diff = currentTick - lastTick;
if(diff > CTR_CPU_TICKS_PER_SECOND)
/* Internal counters/statistics
* > This is only required if the bottom screen is enabled */
if (ctr_bottom_screen_enabled)
{
fps = (float)frames * ((float) CTR_CPU_TICKS_PER_SECOND / (float) diff);
lastTick = currentTick;
frames = 0;
}
frames++;
currentTick = svcGetSystemTick();
diff = currentTick - lastTick;
if(diff > CTR_CPU_TICKS_PER_SECOND)
{
fps = (float)frames * ((float) CTR_CPU_TICKS_PER_SECOND / (float) diff);
lastTick = currentTick;
frames = 0;
}
#ifdef CTR_INSPECT_MEMORY_USAGE
uint32_t ctr_get_stack_usage(void);
void ctr_linear_get_stats(void);
extern u32 __linear_heap_size;
extern u32 __heap_size;
uint32_t ctr_get_stack_usage(void);
void ctr_linear_get_stats(void);
extern u32 __linear_heap_size;
extern u32 __heap_size;
MemInfo mem_info;
PageInfo page_info;
u32 query_addr = 0x08000000;
printf(PRINTFPOS(0,0));
while (query_addr < 0x40000000)
{
svcQueryMemory(&mem_info, &page_info, query_addr);
printf("0x%08X --> 0x%08X (0x%08X) \n", mem_info.base_addr, mem_info.base_addr + mem_info.size, mem_info.size);
query_addr = mem_info.base_addr + mem_info.size;
if(query_addr == 0x1F000000)
query_addr = 0x30000000;
}
MemInfo mem_info;
PageInfo page_info;
u32 query_addr = 0x08000000;
printf(PRINTFPOS(0,0));
while (query_addr < 0x40000000)
{
svcQueryMemory(&mem_info, &page_info, query_addr);
printf("0x%08X --> 0x%08X (0x%08X) \n", mem_info.base_addr, mem_info.base_addr + mem_info.size, mem_info.size);
query_addr = mem_info.base_addr + mem_info.size;
if(query_addr == 0x1F000000)
query_addr = 0x30000000;
}
#if 0
static u32* dummy_pointer;
if(total_frames == 500)
dummy_pointer = malloc(0x2000000);
if(total_frames == 1000)
free(dummy_pointer);
static u32* dummy_pointer;
if(total_frames == 500)
dummy_pointer = malloc(0x2000000);
if(total_frames == 1000)
free(dummy_pointer);
#endif
printf("========================================");
printf("0x%08X 0x%08X 0x%08X\n", __heap_size, gpuCmdBufOffset, (__linear_heap_size - linearSpaceFree()));
printf("fps: %8.4f frames: %i (%X)\n", fps, total_frames++, (__linear_heap_size - linearSpaceFree()));
printf("========================================");
u32 app_memory = *((u32*)0x1FF80040);
u64 mem_used;
svcGetSystemInfo(&mem_used, 0, 1);
printf("total mem : 0x%08X \n", app_memory);
printf("used: 0x%08X free: 0x%08X \n", (u32)mem_used, app_memory - (u32)mem_used);
static u32 stack_usage = 0;
extern u32 __stack_bottom;
if(!(total_frames & 0x3F))
stack_usage = ctr_get_stack_usage();
printf("stack total:0x%08X used: 0x%08X\n", 0x10000000 - __stack_bottom, stack_usage);
printf("========================================");
printf("0x%08X 0x%08X 0x%08X\n", __heap_size, gpuCmdBufOffset, (__linear_heap_size - linearSpaceFree()));
printf("fps: %8.4f frames: %i (%X)\n", fps, total_frames++, (__linear_heap_size - linearSpaceFree()));
printf("========================================");
u32 app_memory = *((u32*)0x1FF80040);
u64 mem_used;
svcGetSystemInfo(&mem_used, 0, 1);
printf("total mem : 0x%08X \n", app_memory);
printf("used: 0x%08X free: 0x%08X \n", (u32)mem_used, app_memory - (u32)mem_used);
static u32 stack_usage = 0;
extern u32 __stack_bottom;
if(!(total_frames & 0x3F))
stack_usage = ctr_get_stack_usage();
printf("stack total:0x%08X used: 0x%08X\n", 0x10000000 - __stack_bottom, stack_usage);
printf("========================================");
ctr_linear_get_stats();
printf("========================================");
printf("========================================");
ctr_linear_get_stats();
printf("========================================");
#else
printf(PRINTFPOS(29,0)"fps: %8.4f frames: %i\r", fps, total_frames++);
printf(PRINTFPOS(29,0)"fps: %8.4f frames: %i\r", fps, total_frames++);
#endif
fflush(stdout);
fflush(stdout);
}
if (ctr->should_resize)
ctr_update_viewport(ctr, video_info);
ctr_update_viewport(ctr, settings, video_info);
ctrGuSetMemoryFill(true, (u32*)ctr->drawbuffers.top.left, 0x00000000,
(u32*)ctr->drawbuffers.top.left + 2 * CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT,
@ -658,7 +683,7 @@ static bool ctr_frame(void* data, const void* frame,
else
{
int i;
uint8_t *dst = (uint8_t*)ctr->texture_linear;
uint8_t *dst = (uint8_t*)ctr->texture_linear;
const uint8_t *src = frame;
for (i = 0; i < height; i++)
@ -689,7 +714,7 @@ static bool ctr_frame(void* data, const void* frame,
GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE),
ctr->rgb32 ? GPU_RGBA8: GPU_RGB565);
ctr_check_3D_slider(ctr);
ctr_check_3D_slider(ctr, (ctr_video_mode_enum)settings->uints.video_3ds_display_mode);
/* ARGB --> RGBA */
if (ctr->rgb32)
@ -720,7 +745,7 @@ static bool ctr_frame(void* data, const void* frame,
GPU_SetViewport(NULL,
VIRT_TO_PHYS(ctr->drawbuffers.top.left),
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
ctr->video_mode == CTR_VIDEO_MODE_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH);
ctr->video_mode == CTR_VIDEO_MODE_2D_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH);
if (ctr->video_mode == CTR_VIDEO_MODE_3D)
{
@ -769,7 +794,7 @@ static bool ctr_frame(void* data, const void* frame,
GPU_SetViewport(NULL,
VIRT_TO_PHYS(ctr->drawbuffers.top.left),
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
ctr->video_mode == CTR_VIDEO_MODE_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH);
ctr->video_mode == CTR_VIDEO_MODE_2D_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH);
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
if (ctr->video_mode == CTR_VIDEO_MODE_3D)
@ -813,16 +838,16 @@ static bool ctr_frame(void* data, const void* frame,
ctrGuDisplayTransfer(true, ctr->drawbuffers.top.left,
240,
ctr->video_mode == CTR_VIDEO_MODE_800x240 ? 800 : 400,
ctr->video_mode == CTR_VIDEO_MODE_2D_800x240 ? 800 : 400,
CTRGU_RGBA8,
gfxTopLeftFramebuffers[ctr->current_buffer_top], 240,CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE);
gfxTopLeftFramebuffers[ctr->current_buffer_top], 240, CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE);
if ((ctr->video_mode == CTR_VIDEO_MODE_400x240) || (ctr->video_mode == CTR_VIDEO_MODE_3D))
if ((ctr->video_mode == CTR_VIDEO_MODE_2D_400x240) || (ctr->video_mode == CTR_VIDEO_MODE_3D))
ctrGuDisplayTransfer(true, ctr->drawbuffers.top.right,
240,
400,
CTRGU_RGBA8,
gfxTopRightFramebuffers[ctr->current_buffer_top], 240,CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE);
gfxTopRightFramebuffers[ctr->current_buffer_top], 240, CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE);
/* Swap buffers : */
@ -831,7 +856,7 @@ static bool ctr_frame(void* data, const void* frame,
topFramebufferInfo.
framebuf0_vaddr = (u32*)gfxTopLeftFramebuffers[ctr->current_buffer_top];
if(ctr->video_mode == CTR_VIDEO_MODE_800x240)
if(ctr->video_mode == CTR_VIDEO_MODE_2D_800x240)
{
topFramebufferInfo.
framebuf1_vaddr = (u32*)(gfxTopLeftFramebuffers[ctr->current_buffer_top] + 240 * 3);
@ -840,13 +865,19 @@ static bool ctr_frame(void* data, const void* frame,
}
else
{
topFramebufferInfo.
framebuf1_vaddr = (u32*)gfxTopRightFramebuffers[ctr->current_buffer_top];
if (ctr->enable_3d)
topFramebufferInfo.
framebuf1_vaddr = (u32*)gfxTopRightFramebuffers[ctr->current_buffer_top];
else
topFramebufferInfo.
framebuf1_vaddr = topFramebufferInfo.framebuf0_vaddr;
topFramebufferInfo.
framebuf_widthbytesize = 240 * 3;
}
topFramebufferInfo.format = (1<<8)|(1<<5)|GSP_BGR8_OES;
u8 bit5 = (ctr->enable_3d != 0);
topFramebufferInfo.format = (1<<8)|((1^bit5)<<6)|((bit5)<<5)|GSP_BGR8_OES;
topFramebufferInfo.
framebuf_dispselect = ctr->current_buffer_top;
topFramebufferInfo.unk = 0x00000000;

View file

@ -265,7 +265,7 @@ static void ctr_font_render_line(
GPU_SetViewport(NULL,
VIRT_TO_PHYS(ctr->drawbuffers.top.left),
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
ctr->video_mode == CTR_VIDEO_MODE_800x240
ctr->video_mode == CTR_VIDEO_MODE_2D_800x240
? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH);
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, v - ctr->vertex_cache.current);

View file

@ -1767,8 +1767,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"裁剪过扫描部分(需重启)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"禁用桌面元素")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"3DS底部屏幕")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"视频驱动")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -1583,8 +1583,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"Crop Overscan (Reload)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"禁用桌面元素")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"3DS底部屏幕")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"視訊驅動")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -1656,8 +1656,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"Bildränder (Overscan) zuschneiden (Neustart erforderlich)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Deaktiviere Desktop-Gestaltung")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"3DS-Bildschirm unten")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Videotreiber")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -3046,10 +3046,12 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Disable Desktop Composition"
)
#if defined(_3DS)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"Κάτω οθόνη 3DS"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Οδηγός Βίντεο"

View file

@ -1493,8 +1493,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"Crop Overscan (Reload)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Disable Desktop Composition")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"3DS Fundo Ekrano")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Video Driver")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -3114,10 +3114,12 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Desactivar composición de escritorio"
)
#if defined(_3DS)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"Pantalla inferior 3DS"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Controlador de video"

View file

@ -1610,8 +1610,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"Tronquer l'overscan (Reload)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Désactiver le compositeur de bureau")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"Écran inférieur 3DS")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Pilote vidéo")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -1628,8 +1628,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"Crop Overscan (Ricarica)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Disattiva composizione del Desktop")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"3DS Bottom Screen")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Driver Video")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -1802,8 +1802,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"オーバースキャンをクロップ(再起動が必要)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"デスクトップコンポジションを無効")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"3DSボトム画面")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"ビデオのドライバ")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -1580,8 +1580,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"오버스캔 잘라내기(재시작)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"데스크탑 구성요소 사용안함")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"3DS 하단 화면")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"비디오 드라이버")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -1797,8 +1797,12 @@ MSG_HASH(MENU_ENUM_LABEL_NO_IMAGES_AVAILABLE,
"no_images")
MSG_HASH(MENU_ENUM_LABEL_NO_FAVORITES_AVAILABLE,
"no_favorites")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VIDEO_3DS_LCD_BOTTOM,
"video_3ds_lcd_bottom")
MSG_HASH(MENU_ENUM_LABEL_VIDEO_3DS_DISPLAY_MODE,
"video_3ds_display_mode")
#endif
MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT,
"playlist_use_old_format")
MSG_HASH(MENU_ENUM_LABEL_MENU_SOUND_OK,

View file

@ -1495,8 +1495,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"Overscan Afsnijden (Herladen Vereist)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Desktop Compositie Deactiveren")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"3DS onderste scherm")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Video Driver")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -1732,8 +1732,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"Przytnij Overscan (Przeładuj)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Wyłącz kompozycję pulpitu")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"Dolny ekran 3DS")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Sterownik wideo")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -3254,10 +3254,12 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Desativar Composição da Área de Trabalho"
)
#if defined(_3DS)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"Tela Inferior 3DS"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Driver de Vídeo"

View file

@ -1572,8 +1572,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"Cortar sobreexploração (recarregar)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Desativar composição do ambiente de trabalho")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"Tela Inferior 3DS")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Controlador de vídeo")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -1609,8 +1609,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"Обрезка обрезки (перезагрузка)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Отключить компоновку рабочего стола")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"Нижний экран 3DS")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Видеодрайвер")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -3482,10 +3482,40 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Disable Desktop Composition"
)
#if defined(_3DS)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"3DS Bottom Screen"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_3DS_LCD_BOTTOM,
"Enable display of status information on bottom screen. Disable to increase battery life and improve performance."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_3DS_DISPLAY_MODE,
"3DS Display Mode"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_3DS_DISPLAY_MODE,
"Selects between 3D and 2D display modes. In '3D' mode, pixels are square and a depth effect is applied when viewing the Quick Menu. '2D' mode provides the best performance."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_3D,
"3D"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D,
"2D"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_400x240,
"2D (Pixel Grid Effect)"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_800x240,
"2D (High Resolution)"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Video"

View file

@ -1603,8 +1603,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN,
"Crop Overscan (Reload)")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION,
"Disable Desktop Composition")
#if defined(_3DS)
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM,
"Màn hình dưới 3DS")
#endif
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER,
"Video Driver")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,

View file

@ -520,6 +520,11 @@ default_sublabel_macro(action_bind_sublabel_switch_gpu_profile, MENU
default_sublabel_macro(action_bind_sublabel_switch_backlight_control, MENU_ENUM_SUBLABEL_SWITCH_BACKLIGHT_CONTROL)
#endif
#if defined(_3DS)
default_sublabel_macro(action_bind_sublabel_video_3ds_lcd_bottom, MENU_ENUM_SUBLABEL_VIDEO_3DS_LCD_BOTTOM)
default_sublabel_macro(action_bind_sublabel_video_3ds_display_mode, MENU_ENUM_SUBLABEL_VIDEO_3DS_DISPLAY_MODE)
#endif
default_sublabel_macro(action_bind_sublabel_playlist_show_sublabels, MENU_ENUM_SUBLABEL_PLAYLIST_SHOW_SUBLABELS)
default_sublabel_macro(action_bind_sublabel_menu_rgui_border_filler_enable, MENU_ENUM_SUBLABEL_MENU_RGUI_BORDER_FILLER_ENABLE)
default_sublabel_macro(action_bind_sublabel_menu_rgui_border_filler_thickness_enable, MENU_ENUM_SUBLABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE)
@ -2398,6 +2403,14 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_SWITCH_BACKLIGHT_CONTROL:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_switch_backlight_control);
break;
#endif
#if defined(_3DS)
case MENU_ENUM_LABEL_VIDEO_3DS_LCD_BOTTOM:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_3ds_lcd_bottom);
break;
case MENU_ENUM_LABEL_VIDEO_3DS_DISPLAY_MODE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_3ds_display_mode);
break;
#endif
case MENU_ENUM_LABEL_CHEAT_APPLY_AFTER_LOAD:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_apply_after_load);

View file

@ -134,7 +134,7 @@ static void menu_display_ctr_draw(menu_display_ctx_draw_t *draw,
GPU_SetViewport(NULL,
VIRT_TO_PHYS(ctr->drawbuffers.top.left),
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
ctr->video_mode == CTR_VIDEO_MODE_800x240 ?
ctr->video_mode == CTR_VIDEO_MODE_2D_800x240 ?
CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH);
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);

View file

@ -6542,7 +6542,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist
MENU_ENUM_LABEL_UI_COMPANION_TOGGLE,
PARSE_ONLY_BOOL, false);
#endif
#ifdef _3DS
#if defined(_3DS)
menu_displaylist_parse_settings_enum(info->list,
MENU_ENUM_LABEL_VIDEO_3DS_DISPLAY_MODE,
PARSE_ONLY_UINT, false);
menu_displaylist_parse_settings_enum(info->list,
MENU_ENUM_LABEL_VIDEO_3DS_LCD_BOTTOM,
PARSE_ONLY_BOOL, false);

View file

@ -95,6 +95,12 @@
#include "../network/netplay/netplay.h"
#endif
/* Required for 3DS display mode setting */
#if defined(_3DS)
#include "gfx/common/ctr_common.h"
#include <3ds/services/cfgu.h>
#endif
enum settings_list_type
{
SETTINGS_LIST_NONE = 0,
@ -1424,6 +1430,44 @@ static void setting_get_string_representation_uint_playlist_inline_core_display_
}
}
#if defined(_3DS)
static void setting_get_string_representation_uint_video_3ds_display_mode(
rarch_setting_t *setting,
char *s, size_t len)
{
if (!setting)
return;
switch (*setting->value.target.unsigned_integer)
{
case CTR_VIDEO_MODE_3D:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_3D),
len);
break;
case CTR_VIDEO_MODE_2D:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D),
len);
break;
case CTR_VIDEO_MODE_2D_400x240:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_400x240),
len);
break;
case CTR_VIDEO_MODE_2D_800x240:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_800x240),
len);
break;
}
}
#endif
static int setting_action_left_analog_dpad_mode(rarch_setting_t *setting, bool wraparound)
{
unsigned port = 0;
@ -9807,7 +9851,35 @@ static bool setting_append_list(
settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED);
#endif
#ifdef _3DS
#if defined(_3DS)
{
u8 device_model = 0xFF;
/* Only O3DS and O3DSXL support running in 'dual-framebuffer'
* mode with the parallax barrier disabled
* (i.e. these are the only platforms that can use
* CTR_VIDEO_MODE_2D_400x240 and CTR_VIDEO_MODE_2D_800x240) */
CFGU_GetSystemModel(&device_model); /* (0 = O3DS, 1 = O3DSXL, 2 = N3DS, 3 = 2DS, 4 = N3DSXL, 5 = N2DSXL) */
CONFIG_UINT(
list, list_info,
&settings->uints.video_3ds_display_mode,
MENU_ENUM_LABEL_VIDEO_3DS_DISPLAY_MODE,
MENU_ENUM_LABEL_VALUE_VIDEO_3DS_DISPLAY_MODE,
video_3ds_display_mode,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
(*list)[list_info->index - 1].get_string_representation =
&setting_get_string_representation_uint_video_3ds_display_mode;
menu_settings_list_current_add_range(list, list_info, 0,
CTR_VIDEO_MODE_LAST - (((device_model == 0) || (device_model == 1)) ? 1 : 3),
1, true, true);
}
CONFIG_BOOL(
list, list_info,
&settings->bools.video_3ds_lcd_bottom,

View file

@ -955,7 +955,16 @@ enum msg_hash_enums
MENU_LABEL(UI_COMPANION_TOGGLE),
MENU_LABEL(DESKTOP_MENU_ENABLE),
MENU_LABEL(UI_MENUBAR_ENABLE),
#if defined(_3DS)
MENU_LABEL(VIDEO_3DS_LCD_BOTTOM),
MENU_LABEL(VIDEO_3DS_DISPLAY_MODE),
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_3D,
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D,
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_400x240,
MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_800x240,
#endif
MENU_ENUM_LABEL_FILE_CONFIG,
MENU_ENUM_LABEL_FILE_BROWSER_COMPRESSED_ARCHIVE,