diff --git a/Makefile.ctr b/Makefile.ctr new file mode 100644 index 0000000000..a2e23b0638 --- /dev/null +++ b/Makefile.ctr @@ -0,0 +1,137 @@ +TARGET := retroarch_3ds +OBJS := +OBJS += gfx/drivers/ctr_blit.o griffin/griffin.o +#NO_SMDH = 1 +DEBUG = 0 + + +CTRULIB = /home/lethalis/3ds/ctrulib/libctru +AEMSTRO = /home/lethalis/3ds/aemstro + +export PATH := $(DEVKITARM)/bin:$(PATH) + +INCDIRS := -I$(CTRULIB)/include +LIBDIRS := -L. -L$(CTRULIB)/lib + + +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard + +CFLAGS += -mword-relocations \ + -fomit-frame-pointer -ffast-math \ + $(ARCH) + +#CFLAGS += -Wall +CFLAGS += -DARM11 -D_3DS + +ifeq ($(DEBUG), 1) + CFLAGS += -O0 -g +else + CFLAGS += -O3 +endif +CFLAGS += -I. -Ideps/zlib -Ideps/7zip -Ilibretro-common/include + +CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE -DSINC_LOWEST_QUALITY +CFLAGS += -DHAVE_GRIFFIN=1 -DHAVE_FILTERS_BUILTIN -DHAVE_MENU -DHAVE_RGUI +CFLAGS += -DHAVE_ZLIB -DWANT_ZLIB +#-DHAVE_LIBRETRO_MANAGEMENT -DWANT_RPNG -DHAVE_BUILTIN_AUTOCONFIG -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP + + +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 + +ASFLAGS := -g $(ARCH) +LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +CFLAGS += -std=gnu99 -ffast-math + + +LIBS := -lretro_ctr -lctru -lm + + + +.PHONY: $(BUILD) clean all + +#--------------------------------------------------------------------------------- +all: $(TARGET) + +clean: + rm -f $(OBJS) + rm -f $(TARGET).3dsx + rm -f $(TARGET).elf + + +$(TARGET): $(TARGET).3dsx +$(TARGET).3dsx : $(TARGET).elf +$(TARGET).elf : $(OBJS) + +ifeq ($(strip $(APP_TITLE)),) +APP_TITLE := $(notdir $(TARGET)) +endif + +ifeq ($(strip $(APP_DESCRIPTION)),) +APP_DESCRIPTION := Built with devkitARM & libctru +endif + +ifeq ($(strip $(APP_AUTHOR)),) +APP_AUTHOR := Unspecified Author +endif + +ifeq ($(strip $(APP_ICON)),) +APP_ICON := $(CTRULIB)/default_icon.png +endif + +PREFIX := $(DEVKITARM)/bin/arm-none-eabi- + +CC := $(PREFIX)gcc +CXX := $(PREFIX)g++ +AS := $(PREFIX)as +AR := $(PREFIX)ar +OBJCOPY := $(PREFIX)objcopy +STRIP := $(PREFIX)strip +NM := $(PREFIX)nm +LD := $(CXX) + + +%.o: %.shader +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + python $(AEMSTRO)/aemstro_as.py $< $(notdir $<).shbin + bin2s $(notdir $<).shbin | $(PREFIX)as -o $@ + echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h + echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h + echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h + rm $(notdir $<).shbin + + +%.o: %.cpp + $(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS) + +%.o: %.c + $(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS) + +%.o: %.s + $(CC) -c -o $@ $< $(ASFLAGS) + +%.o: %.S + $(CC) -c -o $@ $< $(ASFLAGS) + +%.a: + $(AR) -rc $@ $^ + +%.vsh: + +#--------------------------------------------------------------------------------- +%.smdh: $(APP_ICON) $(MAKEFILE_LIST) + @echo building ... $(notdir $@) + smdhtool --create "$(APP_TITLE)" "$(APP_DESCRIPTION)" "$(APP_AUTHOR)" $(APP_ICON) $@ + +#--------------------------------------------------------------------------------- +%.3dsx: %.elf + @echo building ... $(notdir $@) + 3dsxtool $< $@ $(_3DSXFLAGS) + +#--------------------------------------------------------------------------------- +%.elf: + @echo linking $(notdir $@) + $(LD) $(LDFLAGS) $(OBJS) $(LIBDIRS) $(LIBS) -o $@ + $(NM) -CSn $@ > $(notdir $*.lst) + + diff --git a/audio/audio_driver.c b/audio/audio_driver.c index a8ba7357da..a1a26fb93f 100644 --- a/audio/audio_driver.c +++ b/audio/audio_driver.c @@ -79,6 +79,9 @@ static const audio_driver_t *audio_drivers[] = { #ifdef PSP &audio_psp1, #endif +#ifdef _3DS + &audio_ctr, +#endif &audio_null, NULL, }; diff --git a/audio/audio_driver.h b/audio/audio_driver.h index 14ac349feb..0d2365bf47 100644 --- a/audio/audio_driver.h +++ b/audio/audio_driver.h @@ -89,6 +89,7 @@ extern audio_driver_t audio_xenon360; extern audio_driver_t audio_ps3; extern audio_driver_t audio_gx; extern audio_driver_t audio_psp1; +extern audio_driver_t audio_ctr; extern audio_driver_t audio_rwebaudio; extern audio_driver_t audio_null; diff --git a/audio/drivers/ctr_audio.c b/audio/drivers/ctr_audio.c new file mode 100644 index 0000000000..9da928b0d1 --- /dev/null +++ b/audio/drivers/ctr_audio.c @@ -0,0 +1,89 @@ + +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * + * 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 "../../general.h" +#include "../../driver.h" + +static void *ctr_audio_init(const char *device, unsigned rate, unsigned latency) +{ + (void)device; + (void)rate; + (void)latency; + return (void*)-1; +} + +static void ctr_audio_free(void *data) +{ + (void)data; +} + +static ssize_t ctr_audio_write(void *data, const void *buf, size_t size) +{ + (void)data; + (void)buf; + + return size; +} + +static bool ctr_audio_stop(void *data) +{ + (void)data; + return true; +} + +static bool ctr_audio_alive(void *data) +{ + (void)data; + return true; +} + +static bool ctr_audio_start(void *data) +{ + (void)data; + return true; +} + +static void ctr_audio_set_nonblock_state(void *data, bool state) +{ + (void)data; + (void)state; +} + +static bool ctr_audio_use_float(void *data) +{ + (void)data; + return true; +} + +static size_t ctr_audio_write_avail(void *data) +{ + (void)data; + return 0; +} + +audio_driver_t audio_ctr = { + ctr_audio_init, + ctr_audio_write, + ctr_audio_stop, + ctr_audio_start, + ctr_audio_alive, + ctr_audio_set_nonblock_state, + ctr_audio_free, + ctr_audio_use_float, + "ctr", + ctr_audio_write_avail, + NULL +}; diff --git a/config.def.h b/config.def.h index d4b24a2439..f7d0c7d2df 100644 --- a/config.def.h +++ b/config.def.h @@ -36,8 +36,9 @@ enum VIDEO_WII, VIDEO_XENON360, VIDEO_XDK_D3D, - VIDEO_PSP1, + VIDEO_PSP1, VIDEO_VITA, + VIDEO_CTR, VIDEO_D3D9, VIDEO_VG, VIDEO_NULL, @@ -66,6 +67,7 @@ enum AUDIO_WII, AUDIO_RWEBAUDIO, AUDIO_PSP1, + AUDIO_CTR, AUDIO_NULL, AUDIO_RESAMPLER_CC, @@ -80,6 +82,7 @@ enum INPUT_DINPUT, INPUT_PS3, INPUT_PSP, + INPUT_CTR, INPUT_XENON360, INPUT_WII, INPUT_XINPUT, @@ -95,6 +98,7 @@ enum JOYPAD_GX, JOYPAD_XDK, JOYPAD_PSP, + JOYPAD_CTR, JOYPAD_DINPUT, JOYPAD_UDEV, JOYPAD_LINUXRAW, @@ -142,6 +146,8 @@ enum #define VIDEO_DEFAULT_DRIVER VIDEO_VITA #elif defined(PSP) #define VIDEO_DEFAULT_DRIVER VIDEO_PSP1 +#elif defined(_3DS) +#define VIDEO_DEFAULT_DRIVER VIDEO_CTR #elif defined(HAVE_XVIDEO) #define VIDEO_DEFAULT_DRIVER VIDEO_XVIDEO #elif defined(HAVE_SDL) @@ -162,6 +168,8 @@ enum #define AUDIO_DEFAULT_DRIVER AUDIO_WII #elif defined(PSP) #define AUDIO_DEFAULT_DRIVER AUDIO_PSP1 +#elif defined(_3DS) +#define AUDIO_DEFAULT_DRIVER AUDIO_CTR #elif defined(HAVE_ALSA) && defined(HAVE_VIDEOCORE) #define AUDIO_DEFAULT_DRIVER AUDIO_ALSATHREAD #elif defined(HAVE_ALSA) @@ -218,6 +226,8 @@ enum #define INPUT_DEFAULT_DRIVER INPUT_PS3 #elif (defined(SN_TARGET_PSP2) || defined(PSP)) #define INPUT_DEFAULT_DRIVER INPUT_PSP +#elif defined(_3DS) +#define INPUT_DEFAULT_DRIVER INPUT_CTR #elif defined(GEKKO) #define INPUT_DEFAULT_DRIVER INPUT_WII #elif defined(HAVE_UDEV) @@ -250,6 +260,8 @@ enum #define JOYPAD_DEFAULT_DRIVER JOYPAD_XDK #elif defined(PSP) #define JOYPAD_DEFAULT_DRIVER JOYPAD_PSP +#elif defined(_3DS) +#define JOYPAD_DEFAULT_DRIVER JOYPAD_CTR #elif defined(HAVE_DINPUT) #define JOYPAD_DEFAULT_DRIVER JOYPAD_DINPUT #elif defined(HAVE_UDEV) diff --git a/configuration.c b/configuration.c index c30fdfc6c1..7d4e4d79f8 100644 --- a/configuration.c +++ b/configuration.c @@ -113,6 +113,8 @@ const char *config_get_default_audio(void) return "gx"; case AUDIO_PSP1: return "psp1"; + case AUDIO_CTR: + return "ctr"; case AUDIO_RWEBAUDIO: return "rwebaudio"; default: @@ -170,6 +172,8 @@ const char *config_get_default_video(void) return "psp1"; case VIDEO_VITA: return "vita"; + case VIDEO_CTR: + return "ctr"; case VIDEO_XVIDEO: return "xvideo"; case VIDEO_SDL: @@ -212,6 +216,8 @@ const char *config_get_default_input(void) return "ps3"; case INPUT_PSP: return "psp"; + case INPUT_CTR: + return "ctr"; case INPUT_SDL: return "sdl"; case INPUT_SDL2: @@ -266,6 +272,8 @@ const char *config_get_default_joypad(void) return "xdk"; case JOYPAD_PSP: return "psp"; + case JOYPAD_CTR: + return "ctr"; case JOYPAD_DINPUT: return "dinput"; case JOYPAD_UDEV: diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c new file mode 100644 index 0000000000..9868a37394 --- /dev/null +++ b/frontend/drivers/platform_ctr.c @@ -0,0 +1,211 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2015 - Daniel De Matteis + * + * 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 <3ds.h> + +#include +#include +#include +#include + +#include +#include "../../general.h" + +#ifdef IS_SALAMANDER +#include "../../file_ext.h" +#endif + + +int __stacksize__ = 1*1024*1024; +//char elf_path[512]; + +const char* elf_path_cst = "sdmc:/retroarch/test.3dsx"; + + +void wait_for_input(void); +#define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0) + +static void frontend_ctr_get_environment_settings(int *argc, char *argv[], + void *args, void *params_data) +{ + (void)args; + +// return; +#ifndef IS_SALAMANDER +#if defined(HAVE_LOGGER) + logger_init(); +#elif defined(HAVE_FILE_LOGGER) + global_t *global = global_get_ptr(); + global->log_file = fopen("sdmc:/retroarch/retroarch-log.txt", "w"); +#endif +#endif + +// strlcpy(elf_path, argv[0], sizeof(elf_path)); + +// fill_pathname_basedir(g_defaults.port_dir, argv[0], sizeof(g_defaults.port_dir)); + fill_pathname_basedir(g_defaults.port_dir, elf_path_cst, sizeof(g_defaults.port_dir)); + RARCH_LOG("port dir: [%s]\n", g_defaults.port_dir); + + fill_pathname_join(g_defaults.assets_dir, g_defaults.port_dir, + "media", sizeof(g_defaults.assets_dir)); + fill_pathname_join(g_defaults.core_dir, g_defaults.port_dir, + "cores", sizeof(g_defaults.core_dir)); + fill_pathname_join(g_defaults.core_info_dir, g_defaults.port_dir, + "cores", sizeof(g_defaults.core_info_dir)); + fill_pathname_join(g_defaults.savestate_dir, g_defaults.core_dir, + "savestates", sizeof(g_defaults.savestate_dir)); + fill_pathname_join(g_defaults.sram_dir, g_defaults.core_dir, + "savefiles", sizeof(g_defaults.sram_dir)); + fill_pathname_join(g_defaults.system_dir, g_defaults.core_dir, + "system", sizeof(g_defaults.system_dir)); + fill_pathname_join(g_defaults.playlist_dir, g_defaults.core_dir, + "playlists", sizeof(g_defaults.playlist_dir)); + fill_pathname_join(g_defaults.config_path, g_defaults.port_dir, + "retroarch.cfg", sizeof(g_defaults.config_path)); + +#ifndef IS_SALAMANDER +// if (argv[1] && (argv[1][0] != '\0')) +// { +// static char path[PATH_MAX_LENGTH]; +// struct rarch_main_wrap *args = NULL; + +// *path = '\0'; +// args = (struct rarch_main_wrap*)params_data; + +// if (args) +// { +// strlcpy(path, argv[1], sizeof(path)); + +// args->touched = true; +// args->no_content = false; +// args->verbose = false; +// args->config_path = NULL; +// args->sram_path = NULL; +// args->state_path = NULL; +// args->content_path = path; +// args->libretro_path = NULL; + +// RARCH_LOG("argv[0]: %s\n", argv[0]); +// RARCH_LOG("argv[1]: %s\n", argv[1]); +// RARCH_LOG("argv[2]: %s\n", argv[2]); + +// RARCH_LOG("Auto-start game %s.\n", argv[1]); +// } +// } +#endif +} + +static void frontend_ctr_deinit(void *data) +{ + (void)data; +#ifndef IS_SALAMANDER + global_t *global = global_get_ptr(); + global->verbosity = true; + +#ifdef HAVE_FILE_LOGGER + if (global->log_file) + fclose(global->log_file); + global->log_file = NULL; +#endif + + gfxExit(); + // sdmcExit(); + // fsExit(); + // hidExit(); + // aptExit(); + // srvExit(); +#endif +} + +static void frontend_ctr_shutdown(bool unused) +{ + (void)unused; +} + +static int exit_callback(int arg1, int arg2, void *common) +{ + frontend_ctr_deinit(NULL); + frontend_ctr_shutdown(false); + return 0; +} + +#define PRINTFPOS(X,Y) "\x1b["#X";"#Y"H" +#define PRINTFPOS_STR(X,Y) "\x1b["X";"Y"H" +static void frontend_ctr_init(void *data) +{ +#ifndef IS_SALAMANDER + (void)data; + global_t *global = global_get_ptr(); + global->verbosity = true; + + gfxInitDefault(); + gfxSet3D(false); + consoleInit(GFX_BOTTOM, NULL); + +// consoleInit(GFX_BOTTOM, NULL); + +// gfxInitDefault(); +// gfxInit(GSP_RGBA8_OES,GSP_RGBA8_OES,false); + +// gfxSet3D(false); + +// consoleInit(GFX_BOTTOM, NULL); +// printf(PRINTFPOS(0,0)"3ds_test"); +// printf(PRINTFPOS(0,1)"Press Start to exit."); + +// gfxFlushBuffers(); +// gfxSwapBuffers(); +#endif + +} + + +static int frontend_ctr_get_rating(void) +{ + return 4; +} +bool select_pressed = false; +void wait_for_input() +{ + printf("Press Start.\n\n\n\n");fflush(stdout); + while(aptMainLoop()) + { + hidScanInput(); + u32 kDown = hidKeysDown(); + if (kDown & KEY_START) + break; + + if (kDown & KEY_SELECT) + select_pressed = true; + + svcSleepThread(1000000); + } +} + +const frontend_ctx_driver_t frontend_ctx_ctr = { + frontend_ctr_get_environment_settings, /* get_environment_settings */ + frontend_ctr_init, /* init */ + frontend_ctr_deinit, /* deinit */ + NULL, /* exitspawn */ + NULL, /* process_args */ + NULL, /* exec */ + NULL, /* set_fork */ + frontend_ctr_shutdown, /* shutdown */ + NULL, /* get_name */ + frontend_ctr_get_rating, /* get_rating */ + NULL, /* load_content */ + "ctr", +}; diff --git a/frontend/frontend_driver.c b/frontend/frontend_driver.c index 3f7f2602b6..1593d72dc1 100644 --- a/frontend/frontend_driver.c +++ b/frontend/frontend_driver.c @@ -42,6 +42,9 @@ static const frontend_ctx_driver_t *frontend_ctx_drivers[] = { #endif #if defined(PSP) &frontend_ctx_psp, +#endif +#if defined(_3DS) + &frontend_ctx_ctr, #endif &frontend_ctx_null, NULL diff --git a/frontend/frontend_driver.h b/frontend/frontend_driver.h index 60b8a3cfb0..6a82ff4f7b 100644 --- a/frontend/frontend_driver.h +++ b/frontend/frontend_driver.h @@ -59,6 +59,7 @@ extern const frontend_ctx_driver_t frontend_ctx_qnx; extern const frontend_ctx_driver_t frontend_ctx_apple; extern const frontend_ctx_driver_t frontend_ctx_android; extern const frontend_ctx_driver_t frontend_ctx_psp; +extern const frontend_ctx_driver_t frontend_ctx_ctr; extern const frontend_ctx_driver_t frontend_ctx_null; /** diff --git a/gfx/drivers/ctr_blit.shader b/gfx/drivers/ctr_blit.shader new file mode 100644 index 0000000000..f4f161e822 --- /dev/null +++ b/gfx/drivers/ctr_blit.shader @@ -0,0 +1,39 @@ +; setup constants + .const c20, 0.0, 1.0, 0.0, 1.0 + +; setup outmap + .out o0, result.position, 0xF + .out o1, result.color, 0xF + .out o2, result.texcoord0, 0x3 + +; setup uniform map (not required) + .uniform c0, c3, projection + + .vsh vmain, end_vmain + +;code + vmain: + mov r0, v0 (0x4) + mov r0, c20 (0x3) + dp4 o0, c0, r0 (0x0) + dp4 o0, c1, r0 (0x1) + dp4 o0, c2, r0 (0x2) + mov o0, c20 (0x3) + mov o1, c20 (0x5) + ;mov o2, v1 (0x6) + mul r0, c3, v1 (0x6) + add o2, c20, r0 (0x7) + flush + nop + end + end_vmain: + +;operand descriptors + .opdesc x___, xyzw, xyzw ; 0x0 + .opdesc _y__, xyzw, xyzw ; 0x1 + .opdesc __z_, xyzw, xyzw ; 0x2 + .opdesc ___w, xyzw, xyzw ; 0x3 + .opdesc xyz_, xyzw, xyzw ; 0x4 + .opdesc xyzw, wwww, wwww ; 0x5 + .opdesc xyzw, xyzw, xyzw ; 0x6 + .opdesc xyzw, xyzz, xyzw ; 0x7 diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c new file mode 100644 index 0000000000..8bb2f96994 --- /dev/null +++ b/gfx/drivers/ctr_gfx.c @@ -0,0 +1,533 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2015 - Daniel De Matteis + * + * 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 . + */ + +/* using code the from GPU example in crtulib */ + +#include <3ds.h> +#include +#include +#include +#include "ctr_blit_shader_shbin.h" + + +#include "../../general.h" +#include "../../driver.h" +#include "../video_viewport.h" +#include "../video_monitor.h" + +#include "retroarch.h" + +typedef struct ctr_video +{ + bool rgb32; + bool vsync; + bool smooth; + bool menu_texture_enable; + unsigned rotation; +} ctr_video_t; + +DVLB_s* dvlb; +shaderProgram_s shader; +u32* texData; +u32* texData2; + +//GPU framebuffer address +u32* gpuOut = (u32*)0x1F119400; +//GPU depth buffer address +u32* gpuDOut = (u32*)0x1F370800; + +typedef struct +{ + struct + { + float x, y, z; + } position; + float texcoord[2]; +} vertex_s; + + +u32 gpuCmdSize; +u32* gpuCmd; +u32* gpuCmdRight; + + +u32* texture_bin; + +#define tex_w 512 +#define tex_h 512 +#define gpu_tex_w 512 +#define gpu_tex_h 512 + +#define TEX_MAKE_SIZE(W,H) (((u32)(W))|((u32)(H)<<16)) +#define tex_size TEX_MAKE_SIZE(tex_w, tex_h) +#define gpu_tex_size TEX_MAKE_SIZE(gpu_tex_w, gpu_tex_h) + +#define texture_bin_size (tex_w * tex_h * sizeof(*texture_bin)) +#define gpu_texture_bin_size (gpu_tex_w * gpu_tex_h * 4) + +#define fbwidth 400 +#define fbheight 240 + +#define CTR_MATRIX(X0,Y0,Z0,W0,X1,Y1,Z1,W1,X2,Y2,Z2,W2,X3,Y3,Z3,W3) {W0,Z0,Y0,X0,W1,Z1,Y1,X1,W2,Z2,Y2,X2,W3,Z3,Y3,X3} + +float proj_m[16] = CTR_MATRIX + ( + 0.0, -2.0 / fbheight, 0.0, 1.0, + -2.0 / fbwidth, 0.0, 0.0, 1.0, + 0.0, 0.0, 1.0, 0.0, + 1.0 / gpu_tex_w, -1.0 / gpu_tex_h, 1.0, 1.0 + ); + + + + +const vertex_s modelVboData[] = +{ + {{ 40 + 0.0f, 0.0f, -1.0f}, {0.0f, 0.0f}}, + {{ 40 + 320, 0.0f, -1.0f}, {320, 0.0f}}, + {{ 40 + 320, tex_h, -1.0f}, {320, tex_h}}, + + {{ 40 + 0.0f, 0.0f, -1.0f}, {0.0f, 0.0f}}, + {{ 40 + 320, tex_h, -1.0f}, {320, tex_h}}, + {{ 40 + 0.0f, tex_h, -1.0f}, {0.0f, tex_h}} +}; + +void* vbo_buffer; + +//stolen from staplebutt +void GPU_SetDummyTexEnv(u8 num) +{ + GPU_SetTexEnv(num, + GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), + GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), + GPU_TEVOPERANDS(0, 0, 0), + GPU_TEVOPERANDS(0, 0, 0), + GPU_REPLACE, + GPU_REPLACE, + 0xFFFFFFFF); +} + +// topscreen +void renderFrame() +{ + GPU_SetViewport((u32*)osConvertVirtToPhys((u32)gpuDOut), + (u32*)osConvertVirtToPhys((u32)gpuOut), 0, 0, fbheight * 2, fbwidth); + + GPU_DepthMap(-1.0f, 0.0f); + GPU_SetFaceCulling(GPU_CULL_NONE); + GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); + GPU_SetStencilOp(GPU_KEEP, GPU_KEEP, GPU_KEEP); + GPU_SetBlendingColor(0, 0, 0, 0); + // GPU_SetDepthTestAndWriteMask(true, GPU_GREATER, GPU_WRITE_ALL); + GPU_SetDepthTestAndWriteMask(false, GPU_ALWAYS, GPU_WRITE_ALL); + // GPU_SetDepthTestAndWriteMask(true, GPU_ALWAYS, GPU_WRITE_ALL); + + GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0); + GPUCMD_AddWrite(GPUREG_0118, 0); + + GPU_SetAlphaBlending(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, + GPU_ONE_MINUS_SRC_ALPHA, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); + GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00); + + GPU_SetTextureEnable(GPU_TEXUNIT0); + + GPU_SetTexEnv(0, + GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), + GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), + GPU_TEVOPERANDS(0, 0, 0), + GPU_TEVOPERANDS(0, 0, 0), + GPU_MODULATE, GPU_MODULATE, + 0xFFFFFFFF); + GPU_SetDummyTexEnv(1); + GPU_SetDummyTexEnv(2); + GPU_SetDummyTexEnv(3); + GPU_SetDummyTexEnv(4); + GPU_SetDummyTexEnv(5); + + //texturing stuff + GPU_SetTexture(GPU_TEXUNIT0, (u32*)osConvertVirtToPhys((u32)texData), gpu_tex_w, gpu_tex_h, + GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR), + GPU_RGBA4); + + u32 bufferoffset = 0x00000000; + u64 bufferpermutations = 0x210; + u8 numattributes = 2; + GPU_SetAttributeBuffers(3, (u32*)osConvertVirtToPhys((u32)vbo_buffer), + GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT), + 0xFFC, 0x210, 1, &bufferoffset, &bufferpermutations, &numattributes); + + GPU_DrawArray(GPU_TRIANGLES, sizeof(modelVboData) / sizeof(vertex_s)); + + GPU_FinishDrawing(); +} + +void gpu_init_calls(void) +{ + GPU_Init(NULL); + gpuCmdSize = 0x40000; + gpuCmd = (u32*)linearAlloc(gpuCmdSize * 4); + gpuCmdRight = (u32*)linearAlloc(gpuCmdSize * 4); + GPU_Reset(NULL, gpuCmd, gpuCmdSize); + dvlb = DVLB_ParseFile((u32*)ctr_blit_shader_shbin, ctr_blit_shader_shbin_size); + shaderProgramInit(&shader); + shaderProgramSetVsh(&shader, &dvlb->DVLE[0]); + shaderProgramUse(&shader); + + // Flush the command buffer so that the shader upload gets executed + GPUCMD_Finalize(); + GPUCMD_FlushAndRun(NULL); + gspWaitForP3D(); + + //create texture + texData = (u32*)linearMemAlign(gpu_texture_bin_size, + 0x80); //textures need to be 0x80-byte aligned + + texData2 = (u32*)linearMemAlign(texture_bin_size, + 0x80); //textures need to be 0x80-byte aligned + + memcpy(texData2, texture_bin, texture_bin_size); + vbo_buffer = linearAlloc(sizeof(modelVboData)); + memcpy(vbo_buffer, (void*)modelVboData, sizeof(modelVboData)); +} + +#define PRINTFPOS(X,Y) "\x1b["#X";"#Y"H" +#define PRINTFPOS_STR(X,Y) "\x1b["X";"Y"H" + +static void* ctr_init(const video_info_t* video, + const input_driver_t** input, void** input_data) +{ + void* ctrinput = NULL; + global_t* global = global_get_ptr(); + ctr_video_t* ctr = (ctr_video_t*)calloc(1, sizeof(ctr_video_t)); + + if (!ctr) + return NULL; + + printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout); + +// gfxInitDefault(); +// gfxSet3D(false); + texture_bin = (typeof(texture_bin))malloc(texture_bin_size); + int i, j; + for (j = 0; j < tex_h; j++) + { + for (i = 0; i < tex_w; i++) + { + if ((i & 0x8) || (j & 0x8)) + texture_bin[i + j * tex_w] = 0x0000FFFF; + else + texture_bin[i + j * tex_w] = 0xFFFFFFFF; + + if (i > 64) + texture_bin[i + j * tex_w] = 0xFF0000FF; + + } + + } + + gpu_init_calls(); + + if (input && input_data) + { + ctrinput = input_ctr.init(); + *input = ctrinput ? &input_ctr : NULL; + *input_data = ctrinput; + } + + printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout); + return ctr; +} + +static bool ctr_frame(void* data, const void* frame, + unsigned width, unsigned height, unsigned pitch, const char* msg) +{ + ctr_video_t* ctr = (ctr_video_t*)data; + settings_t* settings = config_get_ptr(); + +// int i; + static int frames = 0; + + if (!width || !height) + { + gspWaitForEvent(GSPEVENT_VBlank0, true); + return true; + } + + if(!aptMainLoop()) + { + rarch_main_command(RARCH_CMD_QUIT); + return true; + } + + extern bool select_pressed; + if (select_pressed) + { + rarch_main_command(RARCH_CMD_QUIT); + return true; + } + + hidScanInput(); + u32 kDown = hidKeysDown(); + if (kDown & KEY_START) + { + rarch_main_command(RARCH_CMD_QUIT); + return true; + } + + + printf("frames: %i\r", frames++);fflush(stdout); +// gfxFlushBuffers(); +// gspWaitForEvent(GSPEVENT_VBlank0, true); + + u32 backgroundColor = 0x00000000; + +// hidScanInput(); +// u32 kDown = hidKeysDown(); + +// if (kDown & KEY_START) rarch_main_command(RARCH_CMD_QUIT); // break in order to return to hbmenu + + GPUCMD_SetBufferOffset(0); + GPU_SetFloatUniform(GPU_VERTEX_SHADER, + shaderInstanceGetUniformLocation(shader.vertexShader, "projection"), + (u32*)proj_m, 4); + + + + GSPGPU_FlushDataCache(NULL, (u8*)texData2, texture_bin_size); + GX_SetDisplayTransfer(NULL, (u32*)texData2, tex_size, (u32*)texData, gpu_tex_size, + 0x3302); // rgb32=0x0 rgb32=0x0 ??=0x0 linear2swizzeled=0x2 + gspWaitForPPF(); + + renderFrame(); + GPUCMD_Finalize(); + +// for (i = 0; i < 16; i++) +// printf(PRINTFPOS_STR("%i", "%i")"%f", i >> 2, 10 * (i & 0x3), proj_m[i]); + +// printf(PRINTFPOS(20, 10)"frames: %i", frames++); + + //draw the frame + GPUCMD_FlushAndRun(NULL); + gspWaitForP3D(); + + //clear the screen + GX_SetDisplayTransfer(NULL, (u32*)gpuOut, 0x019001E0, + (u32*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), 0x019001E0, 0x01001000); + gspWaitForPPF(); + + //clear the screen + GX_SetMemoryFill(NULL, (u32*)gpuOut, backgroundColor, (u32*)&gpuOut[0x2EE00], + 0x201, (u32*)gpuDOut, 0x00000000, (u32*)&gpuDOut[0x2EE00], 0x201); + gspWaitForPSC0(); + gfxSwapBuffersGpu(); + + gspWaitForEvent(GSPEVENT_VBlank0, true); + + + // gfxFlushBuffers(); + // gfxSwapBuffers(); + + return true; +} + +static void ctr_set_nonblock_state(void* data, bool toggle) +{ + ctr_video_t* ctr = (ctr_video_t*)data; + + if (ctr) + ctr->vsync = !toggle; +} + +static bool ctr_alive(void* data) +{ + (void)data; + return true; +} + +static bool ctr_focus(void* data) +{ + (void)data; + return true; +} + +static bool ctr_suppress_screensaver(void* data, bool enable) +{ + (void)data; + (void)enable; + return false; +} + +static bool ctr_has_windowed(void* data) +{ + (void)data; + return false; +} + +static void ctr_free(void* data) +{ + ctr_video_t* ctr = (ctr_video_t*)data; + + if (!ctr) + return; + + printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout); + shaderProgramFree(&shader); + DVLB_Free(dvlb); + linearFree(gpuCmd); + linearFree(gpuCmdRight); + linearFree(texData); + linearFree(texData2); + linearFree(vbo_buffer); + free(texture_bin); +// gfxExit(); + + free(ctr); +} + +static void ctr_set_texture_frame(void* data, const void* frame, bool rgb32, + unsigned width, unsigned height, float alpha) +{ + ctr_video_t* ctr = (ctr_video_t*)data; + + int i; + uint8_t* dst = (uint8_t*)texData2; + const uint8_t* src = frame; + for (i = 0; i < height; i++) + { + memcpy(dst, src, width*2); + dst += tex_w*2; + src += width*2; + } + + + +} + +static void ctr_set_texture_enable(void* data, bool state, bool full_screen) +{ + (void) full_screen; + + ctr_video_t* ctr = (ctr_video_t*)data; + + if (ctr) + ctr->menu_texture_enable = state; +} + + +static void ctr_set_rotation(void* data, unsigned rotation) +{ + ctr_video_t* ctr = (ctr_video_t*)data; + + if (!ctr) + return; + + ctr->rotation = rotation; +} +static void ctr_set_filtering(void* data, unsigned index, bool smooth) +{ + ctr_video_t* ctr = (ctr_video_t*)data; + + if (ctr) + ctr->smooth = smooth; +} + +static void ctr_set_aspect_ratio(void* data, unsigned aspectratio_index) +{ + (void)data; + (void)aspectratio_index; + return; +} + +static void ctr_apply_state_changes(void* data) +{ + (void)data; + return; +} + +static void ctr_viewport_info(void* data, struct video_viewport* vp) +{ + (void)data; + return; +} + +static const video_poke_interface_t ctr_poke_interface = +{ + NULL, + ctr_set_filtering, + NULL, /* get_video_output_size */ + NULL, /* get_video_output_prev */ + NULL, /* get_video_output_next */ +#ifdef HAVE_FBO + NULL, +#endif + NULL, + ctr_set_aspect_ratio, + ctr_apply_state_changes, +#ifdef HAVE_MENU + ctr_set_texture_frame, + ctr_set_texture_enable, +#endif + NULL, + NULL, + NULL +}; + +static void ctr_get_poke_interface(void* data, + const video_poke_interface_t** iface) +{ + (void)data; + *iface = &ctr_poke_interface; +} + +static bool ctr_read_viewport(void* data, uint8_t* buffer) +{ + (void)data; + (void)buffer; + return false; +} + +static bool ctr_set_shader(void* data, + enum rarch_shader_type type, const char* path) +{ + (void)data; + (void)type; + (void)path; + + return false; +} + +video_driver_t video_ctr = +{ + ctr_init, + ctr_frame, + ctr_set_nonblock_state, + ctr_alive, + ctr_focus, + ctr_suppress_screensaver, + ctr_has_windowed, + ctr_set_shader, + ctr_free, + "ctr", + + ctr_set_rotation, + ctr_viewport_info, + ctr_read_viewport, + NULL, /* read_frame_raw */ +#ifdef HAVE_OVERLAY + NULL, +#endif + ctr_get_poke_interface +}; diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 87a995a767..33cb25aa8d 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -40,6 +40,9 @@ static const video_driver_t *video_drivers[] = { #ifdef PSP &video_psp1, #endif +#ifdef _3DS + &video_ctr, +#endif #ifdef HAVE_SDL &video_sdl, #endif diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 5298fdce2e..374c156f88 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -184,6 +184,7 @@ typedef struct video_driver extern video_driver_t video_gl; extern video_driver_t video_psp1; extern video_driver_t video_vita; +extern video_driver_t video_ctr; extern video_driver_t video_d3d; extern video_driver_t video_gx; extern video_driver_t video_xenon360; diff --git a/griffin/griffin.c b/griffin/griffin.c index 5e588bd964..af39239486 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -235,10 +235,11 @@ VIDEO DRIVER #include "../gfx/drivers/gx_gfx.c" #elif defined(PSP) #include "../gfx/drivers/psp1_gfx.c" +#elif defined(_3DS) +#include "../gfx/drivers/ctr_gfx.c" #elif defined(XENON) #include "../gfx/drivers/xenon360_gfx.c" #endif - #include "../gfx/drivers/nullgfx.c" /*============================================================ @@ -308,6 +309,10 @@ INPUT #include "../input/drivers/psp_input.c" #include "../input/drivers_joypad/psp_input_joypad.c" #include "../input/autoconf/builtin_psp.c" +#elif defined(_3DS) +#include "../input/drivers/ctr_input.c" +#include "../input/drivers_joypad/ctr_input_joypad.c" +#include "../input/autoconf/builtin_ctr.c" #elif defined(GEKKO) #ifdef HAVE_LIBSICKSAXIS #include "../input/drivers_joypad/gx_input_sicksaxis.c" @@ -359,7 +364,7 @@ INPUT #include "../input/drivers_joypad/winxinput_joypad.c" #endif -#if defined(__linux__) && !defined(ANDROID) +#if defined(__linux__) && !defined(ANDROID) #include "../input/drivers/linuxraw_input.c" #include "../input/drivers_joypad/linuxraw_joypad.c" #endif @@ -463,6 +468,8 @@ AUDIO #include "../audio/drivers/rwebaudio.c" #elif defined(PSP) #include "../audio/drivers/psp1_audio.c" +#elif defined(_3DS) +#include "../audio/drivers/ctr_audio.c" #endif #ifdef HAVE_XAUDIO @@ -604,6 +611,8 @@ FRONTEND #include "../frontend/drivers/platform_xdk.c" #elif defined(PSP) #include "../frontend/drivers/platform_psp.c" +#elif defined(_3DS) +#include "../frontend/drivers/platform_ctr.c" #elif defined(__QNX__) #include "../frontend/drivers/platform_qnx.c" #elif defined(OSX) || defined(IOS) diff --git a/input/autoconf/builtin_ctr.c b/input/autoconf/builtin_ctr.c new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/input/autoconf/builtin_ctr.c @@ -0,0 +1 @@ + diff --git a/input/drivers/ctr_input.c b/input/drivers/ctr_input.c new file mode 100644 index 0000000000..a20b437d64 --- /dev/null +++ b/input/drivers/ctr_input.c @@ -0,0 +1,101 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2015 - Daniel De Matteis + * + * 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 "../../general.h" +#include "../../driver.h" + +static void *ctrinput_input_init(void) +{ + return (void*)-1; +} + +static void ctrinput_input_poll(void *data) +{ + (void)data; +} + +static int16_t ctrinput_input_state(void *data, + const struct retro_keybind **retro_keybinds, unsigned port, + unsigned device, unsigned idx, unsigned id) +{ + (void)data; + (void)retro_keybinds; + (void)port; + (void)device; + (void)idx; + (void)id; + + return 0; +} + +static bool ctrinput_input_key_pressed(void *data, int key) +{ + (void)data; + (void)key; + + return false; +} + +static void ctrinput_input_free_input(void *data) +{ + (void)data; +} + +static uint64_t ctrinput_get_capabilities(void *data) +{ + uint64_t caps = 0; + + caps |= (1 << RETRO_DEVICE_JOYPAD); + + return caps; +} + +static bool ctrinput_set_sensor_state(void *data, + unsigned port, enum retro_sensor_action action, unsigned event_rate) +{ + return false; +} + +static void ctrinput_grab_mouse(void *data, bool state) +{ + (void)data; + (void)state; +} + +static bool ctrinput_set_rumble(void *data, unsigned port, + enum retro_rumble_effect effect, uint16_t strength) +{ + (void)data; + (void)port; + (void)effect; + (void)strength; + + return false; +} + +input_driver_t input_ctr = { + ctrinput_input_init, + ctrinput_input_poll, + ctrinput_input_state, + ctrinput_input_key_pressed, + ctrinput_input_free_input, + ctrinput_set_sensor_state, + NULL, + ctrinput_get_capabilities, + "ctr", + ctrinput_grab_mouse, + ctrinput_set_rumble, +}; diff --git a/input/drivers_joypad/ctr_input_joypad.c b/input/drivers_joypad/ctr_input_joypad.c new file mode 100644 index 0000000000..1f67d99374 --- /dev/null +++ b/input/drivers_joypad/ctr_input_joypad.c @@ -0,0 +1,73 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2015 - Daniel De Matteis + * Copyright (C) 2013-2014 - CatalystG + * + * 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 "../input_joypad_driver.h" + +static const char *ctr_joypad_name(unsigned pad) +{ + return "ctr"; +} + +static bool ctr_joypad_init(void) +{ + return true; +} + +static bool ctr_joypad_button(unsigned port_num, uint16_t joykey) +{ + return false; +} + +static uint64_t ctr_joypad_get_buttons(unsigned port_num) +{ + return 0; +} + +static int16_t ctr_joypad_axis(unsigned port_num, uint32_t joyaxis) +{ + return 0; +} + +static void ctr_joypad_poll(void) +{ +} + +static bool ctr_joypad_query_pad(unsigned pad) +{ + return true; +} + + +static void ctr_joypad_destroy(void) +{ +} + +rarch_joypad_driver_t ctr_joypad = { + ctr_joypad_init, + ctr_joypad_query_pad, + ctr_joypad_destroy, + ctr_joypad_button, + ctr_joypad_get_buttons, + ctr_joypad_axis, + ctr_joypad_poll, + NULL, + ctr_joypad_name, + "ctr", +}; diff --git a/input/input_driver.c b/input/input_driver.c index 4a6134b720..f4cb50d15d 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -28,6 +28,9 @@ static const input_driver_t *input_drivers[] = { #if defined(SN_TARGET_PSP2) || defined(PSP) &input_psp, #endif +#if defined(_3DS) + &input_ctr, +#endif #if defined(HAVE_SDL) || defined(HAVE_SDL2) &input_sdl, #endif diff --git a/input/input_driver.h b/input/input_driver.h index 535def4b50..033ceec141 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -84,6 +84,7 @@ extern input_driver_t input_x; extern input_driver_t input_wayland; extern input_driver_t input_ps3; extern input_driver_t input_psp; +extern input_driver_t input_ctr; extern input_driver_t input_xenon360; extern input_driver_t input_gx; extern input_driver_t input_xinput; diff --git a/input/input_joypad_driver.c b/input/input_joypad_driver.c index eb012703e4..03029fb0e2 100644 --- a/input/input_joypad_driver.c +++ b/input/input_joypad_driver.c @@ -38,6 +38,9 @@ static rarch_joypad_driver_t *joypad_drivers[] = { #ifdef PSP &psp_joypad, #endif +#ifdef _3DS + &ctr_joypad, +#endif #ifdef HAVE_DINPUT &dinput_joypad, #endif diff --git a/input/input_joypad_driver.h b/input/input_joypad_driver.h index b46e48386c..fb99d6f64b 100644 --- a/input/input_joypad_driver.h +++ b/input/input_joypad_driver.h @@ -52,6 +52,7 @@ extern rarch_joypad_driver_t winxinput_joypad; extern rarch_joypad_driver_t sdl_joypad; extern rarch_joypad_driver_t ps3_joypad; extern rarch_joypad_driver_t psp_joypad; +extern rarch_joypad_driver_t ctr_joypad; extern rarch_joypad_driver_t xdk_joypad; extern rarch_joypad_driver_t gx_joypad; extern rarch_joypad_driver_t apple_hid_joypad; diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index 61f835dd40..5d0337a9e8 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -31,6 +31,8 @@ #include #elif defined(PSP) #include +#elif defined(_3DS) +#include <3ds.h> #else #include #endif @@ -87,6 +89,8 @@ static INLINE void rarch_sleep(unsigned msec) sys_timer_usleep(1000 * msec); #elif defined(PSP) sceKernelDelayThread(1000 * msec); +#elif defined(_3DS) + svcSleepThread(1000000 * (s64)msec); #elif defined(_WIN32) Sleep(msec); #elif defined(XENON) diff --git a/libretro-common/include/rthreads/rthreads.h b/libretro-common/include/rthreads/rthreads.h index 57bdffb81d..0a5b9b63b8 100644 --- a/libretro-common/include/rthreads/rthreads.h +++ b/libretro-common/include/rthreads/rthreads.h @@ -179,6 +179,8 @@ void scond_signal(scond_t *cond); #elif defined(PSP) #include #include +#elif defined(_3DS) +#include <3ds.h> #elif defined(_WIN32) && !defined(_XBOX) #include #elif defined(_XBOX) #include @@ -198,6 +200,8 @@ static INLINE void retro_sleep(unsigned msec) sys_timer_usleep(1000 * msec); #elif defined(PSP) sceKernelDelayThread(1000 * msec); +#elif defined(_3DS) + svcSleepThread(1000000 * (s64)msec); #elif defined(_WIN32) Sleep(msec); #elif defined(XENON) diff --git a/menu/menu_entries.c b/menu/menu_entries.c index 915c93cc06..08ed0dd7b5 100644 --- a/menu/menu_entries.c +++ b/menu/menu_entries.c @@ -300,6 +300,9 @@ static void menu_entries_parse_drive_list(file_list_t *list) "ef0:/", "", MENU_FILE_DIRECTORY, 0); menu_list_push(list, "host0:/", "", MENU_FILE_DIRECTORY, 0); +#elif defined(_3DS) + menu_list_push(list, + "sdmc:/", "", MENU_FILE_DIRECTORY, 0); #elif defined(IOS) menu_list_push(list, "/var/mobile/Documents/", "", MENU_FILE_DIRECTORY, 0); diff --git a/performance.c b/performance.c index 8030dcefb9..7a5deda5cc 100644 --- a/performance.c +++ b/performance.c @@ -195,6 +195,8 @@ retro_perf_tick_t rarch_get_perf_counter(void) time_ticks = __mftb(); #elif defined(PSP) sceRtcGetCurrentTick(&time_ticks); +#elif defined(_3DS) + time_ticks = osGetTime(); #elif defined(__mips__) struct timeval tv; gettimeofday(&tv,NULL); @@ -254,6 +256,8 @@ retro_time_t rarch_get_time_usec(void) struct timeval tv; gettimeofday(&tv,NULL); return (1000000 * tv.tv_sec + tv.tv_usec); +#elif defined(_3DS) + return osGetTime(); #else #error "Your platform does not have a timer function implemented in rarch_get_time_usec(). Cannot continue." #endif @@ -357,6 +361,8 @@ unsigned rarch_get_cpu_cores(void) return 1; #elif defined(PSP) return 1; +#elif defined(_3DS) + return 1; #elif defined(_SC_NPROCESSORS_ONLN) /* Linux, most UNIX-likes. */ long ret = sysconf(_SC_NPROCESSORS_ONLN);