Merge branch 'master' into gpu_revamp

This commit is contained in:
smea 2014-12-31 13:35:40 -08:00
commit 1b80b69e73
9 changed files with 413 additions and 40 deletions

View File

@ -0,0 +1,175 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
TOPDIR ?= $(CURDIR)
include $(DEVKITARM)/3ds_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
#
# NO_SMDH: if set to anything, no SMDH file is generated.
# APP_TITLE is the name of the app stored in the SMDH file (Optional)
# APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional)
# APP_AUTHOR is the author of the app stored in the SMDH file (Optional)
# ICON is the filename of the icon (.png), relative to the project folder.
# If not set, it attempts to use one of the following (in this order):
# - <Project name>.png
# - icon.png
# - <libctru folder>/default_icon.png
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
DATA := data
INCLUDES := include
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=softfp
CFLAGS := -g -Wall -O2 -mword-relocations \
-fomit-frame-pointer -ffast-math \
$(ARCH)
CFLAGS += $(INCLUDE) -DARM11 -D_3DS
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := -lctru -lm
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(CTRULIB)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
ifeq ($(strip $(ICON)),)
icons := $(wildcard *.png)
ifneq (,$(findstring $(TARGET).png,$(icons)))
export APP_ICON := $(TOPDIR)/$(TARGET).png
else
ifneq (,$(findstring icon.png,$(icons)))
export APP_ICON := $(TOPDIR)/icon.png
endif
endif
else
export APP_ICON := $(TOPDIR)/$(ICON)
endif
ifeq ($(strip $(NO_SMDH)),)
export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh
endif
.PHONY: $(BUILD) clean all
#---------------------------------------------------------------------------------
all: $(BUILD)
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
ifeq ($(strip $(NO_SMDH)),)
$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh
else
$(OUTPUT).3dsx : $(OUTPUT).elf
endif
$(OUTPUT).elf : $(OFILES)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
# WARNING: This is not the right way to do this! TODO: Do it right!
#---------------------------------------------------------------------------------
%.vsh.o : %.vsh
#---------------------------------------------------------------------------------
@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
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@ -0,0 +1,4 @@
get_system_language
=======
This is an example on how to get the system language on the 3DS.

View File

@ -0,0 +1,46 @@
#include <stdio.h>
#include <string.h>
#include <3ds.h>
int main(int argc, char** argv)
{
// Initialize services
gfxInit();
initCfgu();
u8 language = 0;
Result res;
// Init console for text output
consoleInit(GFX_BOTTOM, NULL);
// Read the language field from the config savegame.
res = CFGU_GetSystemLanguage(&language);
// Print return value and language code
printf(" Result: 0x%x\n", (int)res);
printf("Language code: %d", (int)language);
// Main loop
while (aptMainLoop())
{
hidScanInput();
u32 kDown = hidKeysDown();
if (kDown & KEY_START)
break; // break in order to return to hbmenu
// Flush and swap framebuffers
gfxFlushBuffers();
gfxSwapBuffers();
gspWaitForVBlank();
}
// Exit services
exitCfgu();
gfxExit();
return 0;
}

View File

@ -3,8 +3,12 @@
Result initCfgu(void); Result initCfgu(void);
Result exitCfgu(void); Result exitCfgu(void);
Result CFGU_SecureInfoGetRegion(u8* region);
Result CFGU_GenHashConsoleUnique(u32 appIDSalt, u64* hash);
Result CFGU_GetRegionCanadaUSA(u8* value); Result CFGU_GetRegionCanadaUSA(u8* value);
Result CFGU_GetSystemModel(u8* model); Result CFGU_GetSystemModel(u8* model);
Result CFGU_GetModelNintendo2DS(u8* value); Result CFGU_GetModelNintendo2DS(u8* value);
Result CFGU_GetCountryCodeString(u16 code, u16* string); Result CFGU_GetCountryCodeString(u16 code, u16* string);
Result CFGU_GetCountryCodeID(u16 string, u16* code); Result CFGU_GetCountryCodeID(u16 string, u16* code);
Result CFGU_GetConfigInfoBlk2(u32 size, u32 blkID, u8* outData);
Result CFGU_GetSystemLanguage(u8* language);

View File

@ -181,7 +181,7 @@ Result sdmcExit(void)
RemoveDevice("sdmc"); RemoveDevice("sdmc");
sdmcInitialised = false; sdmcInitialised = false;
return rc; return rc;
} }
@ -527,7 +527,48 @@ sdmc_stat(struct _reent *r,
const char *file, const char *file,
struct stat *st) struct stat *st)
{ {
r->_errno = ENOSYS; Handle fd;
Result rc;
const char *pathptr = NULL;
pathptr = sdmc_fixpath(file);
if(pathptr==NULL)
{
r->_errno=EINVAL;
return -1;
}
if( (rc = FSUSER_OpenFile(NULL, &fd, sdmcArchive, FS_makePath(PATH_CHAR, pathptr),
FS_OPEN_READ, FS_ATTRIBUTE_NONE))==0)
{
u64 tmpsize = 0;
rc = FSFILE_GetSize(fd, &tmpsize);
FSFILE_Close(fd);
if(rc==0)
{
memset(st, 0, sizeof(struct stat));
st->st_size = (off_t)tmpsize;
st->st_nlink = 1;
st->st_uid = 1;
st->st_gid = 2;
st->st_mode = S_IFREG | S_IWUSR | S_IWGRP | S_IWOTH | S_IRUSR | S_IRGRP | S_IROTH;
return 0;
}
}
if( (rc = FSUSER_OpenDirectory(NULL, &fd, sdmcArchive, FS_makePath(PATH_CHAR, pathptr))) == 0 )
{
memset(st, 0, sizeof(struct stat));
st->st_nlink = 1;
st->st_uid = 1;
st->st_gid = 2;
st->st_mode = S_IFDIR | S_IWUSR | S_IWGRP | S_IWOTH | S_IRUSR | S_IRGRP | S_IROTH;
return 0;
}
r->_errno = EBADF;
return -1; return -1;
} }

View File

@ -8,85 +8,138 @@ static Handle CFGU_handle = 0;
Result initCfgu() Result initCfgu()
{ {
return srvGetServiceHandle(&CFGU_handle, "cfg:u"); return srvGetServiceHandle(&CFGU_handle, "cfg:u");
} }
Result exitCfgu() Result exitCfgu()
{ {
Result ret = svcCloseHandle(CFGU_handle); Result ret = svcCloseHandle(CFGU_handle);
CFGU_handle = 0; CFGU_handle = 0;
return ret; return ret;
}
Result CFGU_SecureInfoGetRegion(u8* region)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00020000;
if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret;
*region = (u8)cmdbuf[2];
return (Result)cmdbuf[1];
}
Result CFGU_GenHashConsoleUnique(u32 appIDSalt, u64* hash)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00030000;
cmdbuf[1] = appIDSalt;
if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret;
*hash = (u64)cmdbuf[2];
*hash |= ((u64)cmdbuf[3])<<32;
return (Result)cmdbuf[1];
} }
Result CFGU_GetRegionCanadaUSA(u8* value) Result CFGU_GetRegionCanadaUSA(u8* value)
{ {
Result ret = 0; Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00040000; cmdbuf[0] = 0x00040000;
if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret; if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret;
*value = (u8)cmdbuf[2]; *value = (u8)cmdbuf[2];
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
} }
Result CFGU_GetSystemModel(u8* model) Result CFGU_GetSystemModel(u8* model)
{ {
Result ret = 0; Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00050000; cmdbuf[0] = 0x00050000;
if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret; if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret;
*model = (u8)cmdbuf[2]; *model = (u8)cmdbuf[2];
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
} }
Result CFGU_GetModelNintendo2DS(u8* value) Result CFGU_GetModelNintendo2DS(u8* value)
{ {
Result ret = 0; Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00060000; cmdbuf[0] = 0x00060000;
if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret; if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret;
*value = (u8)cmdbuf[2]; *value = (u8)cmdbuf[2];
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
} }
Result CFGU_GetCountryCodeString(u16 code, u16* string) Result CFGU_GetCountryCodeString(u16 code, u16* string)
{ {
Result ret = 0; Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00090040; cmdbuf[0] = 0x00090040;
cmdbuf[1] = (u32)code; cmdbuf[1] = (u32)code;
if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret; if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret;
*string = (u16)cmdbuf[2]; *string = (u16)cmdbuf[2];
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
} }
Result CFGU_GetCountryCodeID(u16 string, u16* code) Result CFGU_GetCountryCodeID(u16 string, u16* code)
{ {
Result ret = 0; Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000A0040; cmdbuf[0] = 0x000A0040;
cmdbuf[1] = (u32)string; cmdbuf[1] = (u32)string;
if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret; if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret;
*code = (u16)cmdbuf[2]; *code = (u16)cmdbuf[2];
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
}
// See here for block IDs:
// http://3dbrew.org/wiki/Config_Savegame#Configuration_blocks
Result CFGU_GetConfigInfoBlk2(u32 size, u32 blkID, u8* outData)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00010082;
cmdbuf[1] = size;
cmdbuf[2] = blkID;
cmdbuf[3] = (size<<4)|12;
cmdbuf[4] = (u32)outData;
if((ret = svcSendSyncRequest(CFGU_handle))!=0)return ret;
return (Result)cmdbuf[1];
}
Result CFGU_GetSystemLanguage(u8* language)
{
return CFGU_GetConfigInfoBlk2(1, 0xA0002, language);
} }

View File

@ -11,7 +11,7 @@ void __appExit();
void __libc_fini_array(void); void __libc_fini_array(void);
void __attribute__((weak)) __attribute__((noreturn)) __ctru_exit(int rc) void __attribute__((weak)) __attribute__((noreturn)) __libctru_exit(int rc)
{ {
u32 tmp=0; u32 tmp=0;

View File

@ -18,7 +18,7 @@ void __libc_init_array(void);
void __ctru_exit(int rc); void __ctru_exit(int rc);
void __attribute__((weak)) initSystem(void (*retAddr)(void)) void __attribute__((weak)) __libctru_init(void (*retAddr)(void))
{ {
// Register newlib exit() syscall // Register newlib exit() syscall

View File

@ -0,0 +1,50 @@
.arm
.align 2
.global initSystem
.type initSystem, %function
initSystem:
ldr r2, =saved_stack
str sp, [r2]
str lr, [r2,#4]
bl __libctru_init
ldr r2, =fake_heap_start
ldr sp, [r2]
ldr r3, =__stacksize__
ldr r3, [r3]
add sp, sp, r3
add sp, sp, #7
bics sp, sp, #7
str sp, [r2]
ldr r2, =saved_stack
ldr lr, [r2,#4]
bx lr
.global __ctru_exit
.type __ctru_exit, %function
__ctru_exit:
ldr r2, =saved_stack
ldr sp, [r2]
b __libctru_exit
.data
.align 2
__stacksize__:
.word 32 * 1024
.weak __stacksize__
.bss
.align 2
saved_stack:
.space 8