This commit is contained in:
Lectem 2015-04-21 20:48:33 +00:00
commit 24de64fa22
12 changed files with 914 additions and 1 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@
Thumbs.db Thumbs.db
build/ build/
lib/ lib/
docs/

29
.travis.yml Normal file
View File

@ -0,0 +1,29 @@
language: c
before_install:
- wget http://sourceforge.net/projects/devkitpro/files/Automated%20Installer/devkitARMupdate.pl
- export DEVKITPRO=/home/travis/devkitPro
- export DEVKITARM=${DEVKITPRO}/devkitARM
- sudo add-apt-repository --yes ppa:libreoffice/ppa
- sudo apt-get update -qq
install:
- sudo perl devkitARMupdate.pl
env:
global:
- secure: "Hayg1mC1ejZWoTC3vl4sv8TNCLGMYC4kxjzectUBQLPve0abgekTUm7wAkYoBo9CecbVnDqMH4sUazR46uZmtji/xeXVc1++9m/r1A7kubsJJsEMi1e5VYaKkpDc+/FycClaSyojwiv69EjtAaHhAld7qmu+zN/pJZNTbmX071Y="
script:
- cd libctru
- make
- cd ..
after_success:
- #Build the doxygen files and upload to GH pages
- git config --global user.email "travis@travis-ci.org"
- git config --global user.name "TravisCI-DocBuilder"
- #export doc only once, in gcc job
- sh exportdoc.sh

View File

@ -1,4 +1,4 @@
ctrulib ctrulib[![Build Status](https://travis-ci.org/Lectem/ctrulib.svg?branch=master)](https://travis-ci.org/Lectem/ctrulib)
======= =======
CTR User Library CTR User Library

View File

@ -0,0 +1,170 @@
#---------------------------------------------------------------------------------
.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=hard
CFLAGS := -g -Wall -Wfatal-errors -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
.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)),)
.PHONY: all
all : $(OUTPUT).3dsx $(OUTPUT).smdh
endif
$(OUTPUT).3dsx : $(OUTPUT).elf
$(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 $<)
picasso ../$(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 @@
Hello Triangle
A simple GPU demo to display a white triangle.
Requires the [picasso](https://github.com/fincs/picasso) shader assembler.

View File

@ -0,0 +1,32 @@
; Really simple & stupid PICA200 shader
; Taken from picasso example
; Uniforms
.fvec projection[4]
; Constants
.constf myconst(0.0, 1.0, -1.0, 0.0)
.alias ones myconst.yyyy ; (1.0,1.0,1.0,1.0)
; Outputs : here only position and color
.out outpos position
.out outclr color
; Inputs : here we have only vertices
.alias inpos v0
.proc main
; r0 = (inpos.x, inpos.y, inpos.z, 1.0)
mov r0.xyz, inpos
mov r0.w, ones
; outpos = projection * r1
dp4 outpos.x, projection[0], r0
dp4 outpos.y, projection[1], r0
dp4 outpos.z, projection[2], r0
dp4 outpos.w, projection[3], r0
; Set vertex color to white rgba => (1.0,1.0,1.0,1.0)
mov outclr, ones
end
.end

View File

@ -0,0 +1,31 @@
//
// Created by Lectem on 22/03/2015.
//
#include "3dutils.h"
void SetUniformMatrix(u32 startreg, float* m) {
float param[16];
param[0x0]=m[3]; //w
param[0x1]=m[2]; //z
param[0x2]=m[1]; //y
param[0x3]=m[0]; //x
param[0x4]=m[7];
param[0x5]=m[6];
param[0x6]=m[5];
param[0x7]=m[4];
param[0x8]=m[11];
param[0x9]=m[10];
param[0xa]=m[9];
param[0xb]=m[8];
param[0xc]=m[15];
param[0xd]=m[14];
param[0xe]=m[13];
param[0xf]=m[12];
GPU_SetFloatUniform(GPU_VERTEX_SHADER, startreg, (u32*)param, 4);
}

View File

@ -0,0 +1,10 @@
//
// Created by Lectem on 22/03/2015.
//
#ifndef _2DGPU_3DUTILS_H_
#define _2DGPU_3DUTILS_H_
#include <3ds.h>
void SetUniformMatrix(u32 startreg, float* m);
#endif //_2DGPU_3DUTILS_H_

View File

@ -0,0 +1,266 @@
/**
* Hello Triangle example, made by Lectem
*
* Draws a white triangle using the 3DS GPU.
* This example should give you enough hints and links on how to use the GPU for basic non-textured rendering.
* Another version of this example will be made with colors.
*
* Thanks to smea, fincs, neobrain, xerpi and all those who helped me understand how the 3DS GPU works
*/
#include <3ds.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "shader_vsh_shbin.h"
#include "3dutils.h"
#include "mmath.h"
/**
* Crappy assert stuff that lets you go back to hbmenu by pressing start.
*/
#define STRINGIZE(x) STRINGIZE2(x)
#define STRINGIZE2(x) #x
#define LINE_STRING STRINGIZE(__LINE__)
#define my_assert(e) ((e) ? (void)0 : _my_assert("assert failed at " __FILE__ ":" LINE_STRING " (" #e ")\n"))
void _my_assert(char * text)
{
printf("%s\n",text);
do{
hidScanInput();
if(keysDown()&KEY_START)break;
gfxFlushBuffers();
gfxSwapBuffers();
gspWaitForVBlank();
}while(aptMainLoop());
//should stop the program and clean up our mess
}
typedef struct {
float x, y, z;
} vector_3f;
typedef struct {
float r, g, b, a;
} vector_4f;
typedef struct {
vector_3f position;
vector_4f color;
} vertex_pos_col;
#define GPU_CMD_SIZE 0x40000
//GPU framebuffer address
u32* gpuFBuffer =(u32*)0x1F119400;
//GPU depth buffer address
u32* gpuDBuffer =(u32*)0x1F370800;
//GPU command buffers
u32* gpuCmd = NULL;
//shader structure
DVLB_s* shader_dvlb; //the header
shaderProgram_s shader; //the program
Result projUniformRegister =-1;
Result modelviewUniformRegister =-1;
#define RGBA8(r,g,b,a) ((((r)&0xFF)<<24) | (((g)&0xFF)<<16) | (((b)&0xFF)<<8) | (((a)&0xFF)<<0))
//The color used to clear the screen
u32 clearColor=RGBA8(0x68, 0xB0, 0xD8, 0xFF);
//The projection matrix
static float ortho_matrix[4*4];
void GPU_SetDummyTexEnv(u8 num);
void gpuUIEndFrame();
void gpuUIInit()
{
GPU_Init(NULL);//initialize GPU
gfxSet3D(false);//We will not be using the 3D mode in this example
Result res=0;
/**
* Load our vertex shader and its uniforms
* Check http://3dbrew.org/wiki/SHBIN for more informations about the shader binaries
*/
shader_dvlb = DVLB_ParseFile((u32 *)shader_vsh_shbin, shader_vsh_shbin_size);//load our vertex shader binary
my_assert(shader_dvlb != NULL);
shaderProgramInit(&shader);
res = shaderProgramSetVsh(&shader, &shader_dvlb->DVLE[0]);
my_assert(res >=0); // check for errors
//In this example we are only rendering in "2D mode", so we don't need one command buffer per eye
gpuCmd=(u32*)linearAlloc(GPU_CMD_SIZE * (sizeof *gpuCmd) ); //Don't forget that commands size is 4 (hence the sizeof)
my_assert(gpuCmd != NULL);
//Reset the gpu
//This actually needs a command buffer to work, and will then use it as default
GPU_Reset(NULL, gpuCmd, GPU_CMD_SIZE);
projUniformRegister = shaderInstanceGetUniformLocation(shader.vertexShader, "projection");
my_assert(projUniformRegister != -1); // make sure we did get the uniform
shaderProgramUse(&shader); // Select the shader to use
initOrthographicMatrix(ortho_matrix, 0.0f, 400.0f, 0.0f, 240.0f, 0.0f, 1.0f); // A basic projection for 2D drawings
SetUniformMatrix(projUniformRegister, ortho_matrix); // Upload the matrix to the GPU
//Flush buffers and setup the environment for the next frame
gpuUIEndFrame();
}
void gpuUIExit()
{
//do things properly
linearFree(gpuCmd);
shaderProgramFree(&shader);
DVLB_Free(shader_dvlb);
GPU_Reset(NULL, gpuCmd, GPU_CMD_SIZE); // Not really needed, but safer for the next applications ?
}
void gpuUIEndFrame()
{
//Ask the GPU to draw everything (execute the commands)
GPU_FinishDrawing();
GPUCMD_Finalize();
GPUCMD_FlushAndRun(NULL);
gspWaitForP3D();//Wait for the gpu 3d processing to be done
//Copy the GPU output buffer to the screen framebuffer
//See http://3dbrew.org/wiki/GPU#Transfer_Engine for more details about the transfer engine
GX_SetDisplayTransfer(NULL, gpuFBuffer, 0x019001E0, (u32*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), 0x019001E0, 0x01001000);
gspWaitForPPF();
//Clear the screen
GX_SetMemoryFill(NULL, gpuFBuffer, clearColor, &gpuFBuffer[0x2EE00],
0x201, gpuDBuffer, 0x00000000, &gpuDBuffer[0x2EE00], 0x201);
gspWaitForPSC0();
gfxSwapBuffersGpu();
//Wait for the screen to be updated
gspWaitForVBlank();
//Get ready to start a new frame
GPUCMD_SetBufferOffset(0);
//Viewport (http://3dbrew.org/wiki/GPU_Commands#Command_0x0041)
GPU_SetViewport((u32 *)osConvertVirtToPhys((u32)gpuDBuffer),
(u32 *)osConvertVirtToPhys((u32)gpuFBuffer),
0, 0,
//Our screen is 400*240, but the GPU actually renders to 400*480 and then downscales it SetDisplayTransfer bit 24 is set
//This is the case here (See http://3dbrew.org/wiki/GPU#0x1EF00C10 for more details)
240*2, 400);
GPU_DepthMap(-1.0f, 0.0f); //Be careful, standard OpenGL clipping is [-1;1], but it is [-1;0] on the pica200
// Note : this is corrected by our projection matrix !
//Sets the texture environment parameters not to modify our pixels at fragment stage
//See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight
GPU_SetTexEnv(
0,
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVOPERANDS(0,0,0),
GPU_TEVOPERANDS(0,0,0),
GPU_REPLACE, GPU_REPLACE,
0xFFFFFFFF
);
GPU_SetDummyTexEnv(1);
GPU_SetDummyTexEnv(2);
GPU_SetDummyTexEnv(3);
GPU_SetDummyTexEnv(4);
GPU_SetDummyTexEnv(5);
}
//Our data
static const vector_3f triangle_mesh[] =
{
{240.0f+60.0f, 120.0f, 0.5f},
{240.0f-60.0f, 120.0f+60.0f, 0.5f},
{240.0f-60.0f, 120.0f-60.0f, 0.5f}
};
static void* triangle_data = NULL;
int main(int argc, char** argv)
{
srvInit();
aptInit();
hidInit(NULL);
gfxInitDefault();
consoleInit(GFX_BOTTOM, NULL);
gpuUIInit();
printf("hello triangle !\n");
triangle_data = linearAlloc(sizeof(triangle_mesh)); //allocate our vbo on the linear heap
memcpy(triangle_data, triangle_mesh, sizeof(triangle_mesh)); //Copy our data
do{
hidScanInput();
if(keysDown()&KEY_START)break; //Stop the program when Start is pressed
//Setup the buffers data
GPU_SetAttributeBuffers(
1, // number of attributes
(u32 *) osConvertVirtToPhys((u32) triangle_data),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT),//We only have vertices
0xFFFE,//Attribute mask, in our case 0b1110 since we use only the first one
0x0,//Attribute permutations (here it is the identity)
1, //number of buffers
(u32[]) {0x0}, // buffer offsets (placeholders)
(u64[]) {0x0}, // attribute permutations for each buffer (identity again)
(u8[]) {1} // number of attributes for each buffer
);
//Display the buffers data
GPU_DrawArray(GPU_TRIANGLES, sizeof(triangle_mesh) / sizeof(triangle_mesh[0]));
gpuUIEndFrame();
}while(aptMainLoop());
gpuUIExit();
gfxExit();
hidExit();
aptExit();
srvExit();
return 0;
}
void GPU_SetDummyTexEnv(u8 num)
{
//Don't touch the colors of the previous stages
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);
}

View File

@ -0,0 +1,203 @@
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <3ds.h>
#include "mmath.h"
void loadIdentity44(float* m)
{
if(!m)return;
memset(m, 0x00, 16*4);
m[0]=m[5]=m[10]=m[15]=1.0f;
}
void multMatrix44(float* m1, float* m2, float* m) //4x4
{
int i, j;
for(i=0;i<4;i++)for(j=0;j<4;j++)m[i+j*4]=(m1[0+j*4]*m2[i+0*4])+(m1[1+j*4]*m2[i+1*4])+(m1[2+j*4]*m2[i+2*4])+(m1[3+j*4]*m2[i+3*4]);
}
void translateMatrix(float* tm, float x, float y, float z)
{
float rm[16], m[16];
loadIdentity44(rm);
rm[3]=x;
rm[7]=y;
rm[11]=z;
multMatrix44(tm,rm,m);
memcpy(tm,m,16*sizeof(float));
}
// 00 01 02 03
// 04 05 06 07
// 08 09 10 11
// 12 13 14 15
void rotateMatrixX(float* tm, float x, bool r)
{
float rm[16], m[16];
memset(rm, 0x00, 16*4);
rm[0]=1.0f;
rm[5]=cos(x);
rm[6]=sin(x);
rm[9]=-sin(x);
rm[10]=cos(x);
rm[15]=1.0f;
if(!r)multMatrix44(tm,rm,m);
else multMatrix44(rm,tm,m);
memcpy(tm,m,16*sizeof(float));
}
void rotateMatrixY(float* tm, float x, bool r)
{
float rm[16], m[16];
memset(rm, 0x00, 16*4);
rm[0]=cos(x);
rm[2]=sin(x);
rm[5]=1.0f;
rm[8]=-sin(x);
rm[10]=cos(x);
rm[15]=1.0f;
if(!r)multMatrix44(tm,rm,m);
else multMatrix44(rm,tm,m);
memcpy(tm,m,16*sizeof(float));
}
void rotateMatrixZ(float* tm, float x, bool r)
{
float rm[16], m[16];
memset(rm, 0x00, 16*4);
rm[0]=cos(x);
rm[1]=sin(x);
rm[4]=-sin(x);
rm[5]=cos(x);
rm[10]=1.0f;
rm[15]=1.0f;
if(!r)multMatrix44(tm,rm,m);
else multMatrix44(rm,tm,m);
memcpy(tm,m,16*sizeof(float));
}
void scaleMatrix(float* tm, float x, float y, float z)
{
tm[0]*=x; tm[4]*=x; tm[8]*=x; tm[12]*=x;
tm[1]*=y; tm[5]*=y; tm[9]*=y; tm[13]*=y;
tm[2]*=z; tm[6]*=z; tm[10]*=z; tm[14]*=z;
}
void initProjectionMatrix(float* m, float fovy, float aspect, float near, float far)
{
float top = near*tan(fovy/2);
float right = (top*aspect);
float mp[4*4];
mp[0x0] = near/right;
mp[0x1] = 0.0f;
mp[0x2] = 0.0f;
mp[0x3] = 0.0f;
mp[0x4] = 0.0f;
mp[0x5] = near/top;
mp[0x6] = 0.0f;
mp[0x7] = 0.0f;
mp[0x8] = 0.0f;
mp[0x9] = 0.0f;
mp[0xA] = -(far+near)/(far-near);
mp[0xB] = -2.0f*(far*near)/(far-near);
mp[0xC] = 0.0f;
mp[0xD] = 0.0f;
mp[0xE] = -1.0f;
mp[0xF] = 0.0f;
float mp2[4*4];
loadIdentity44(mp2);
mp2[0xA]=0.5;
mp2[0xB]=-0.5;
multMatrix44(mp2, mp, m);
}
void initOrthographicMatrix(float *m, float left, float right, float bottom, float top, float near, float far)
{
/* ______________________
| |
| |
| |
| |
| |
|______________________| ^
| x
<-----
y
*/
//Mirror
//right = 400-right;
//left = 400-left;
//top = 240-top;
//bottom = 240-bottom;
float mp[4*4];
mp[0x0] = 2.0f/(right-left);
mp[0x1] = 0.0f;
mp[0x2] = 0.0f;
mp[0x3] = -(right+left)/(right-left);
mp[0x4] = 0.0f;
mp[0x5] = 2.0f/(top-bottom);
mp[0x6] = 0.0f;
mp[0x7] = -(top+bottom)/(top-bottom);
mp[0x8] = 0.0f;
mp[0x9] = 0.0f;
mp[0xA] = -2.0f/(far-near);
mp[0xB] = (far+near)/(far-near);
mp[0xC] = 0.0f;
mp[0xD] = 0.0f;
mp[0xE] = 0.0f;
mp[0xF] = 1.0f;
float mp2[4*4];
loadIdentity44(mp2);
mp2[0xA] = 0.5;
mp2[0xB] = -0.5;
//Convert Z [-1, 1] to [-1, 0] (PICA shiz)
multMatrix44(mp2, mp, m);
//rotateMatrixZ(m, M_PI/2, false);
}
vect3Df_s getMatrixColumn(float* m, u8 i)
{
if(!m || i>=4)return vect3Df(0,0,0);
return vect3Df(m[0+i*4],m[1+i*4],m[2+i*4]);
}
vect3Df_s getMatrixRow(float* m, u8 i)
{
if(!m || i>=4)return vect3Df(0,0,0);
return vect3Df(m[i+0*4],m[i+1*4],m[i+2*4]);
}
vect4Df_s getMatrixColumn4(float* m, u8 i)
{
if(!m || i>=4)return vect4Df(0,0,0,0);
return vect4Df(m[0+i*4],m[1+i*4],m[2+i*4],m[3+i*4]);
}
vect4Df_s getMatrixRow4(float* m, u8 i)
{
if(!m || i>=4)return vect4Df(0,0,0,0);
return vect4Df(m[i+0*4],m[i+1*4],m[i+2*4],m[i+3*4]);
}

View File

@ -0,0 +1,152 @@
#ifndef MATH_H
#define MATH_H
#ifdef __cplusplus
extern "C" {
#endif
#include <3ds/types.h>
#include <math.h>
#pragma GCC diagnostic ignored "-Wnarrowing"
typedef float mtx44[4][4];
typedef float mtx33[3][3];
typedef struct
{
s32 x, y, z;
}vect3Di_s;
static inline vect3Di_s vect3Di(s32 x, s32 y, s32 z)
{
return (vect3Di_s){x,y,z};
}
static inline vect3Di_s vaddi(vect3Di_s u, vect3Di_s v)
{
return (vect3Di_s){u.x+v.x,u.y+v.y,u.z+v.z};
}
static inline vect3Di_s vsubi(vect3Di_s u, vect3Di_s v)
{
return (vect3Di_s){u.x-v.x,u.y-v.y,u.z-v.z};
}
static inline vect3Di_s vmuli(vect3Di_s v, s32 f)
{
return (vect3Di_s){v.x*f,v.y*f,v.z*f};
}
typedef struct
{
float x, y, z;
}vect3Df_s;
static inline vect3Df_s vect3Df(float x, float y, float z)
{
return (vect3Df_s){x,y,z};
}
static inline vect3Df_s vaddf(vect3Df_s u, vect3Df_s v)
{
return (vect3Df_s){u.x+v.x,u.y+v.y,u.z+v.z};
}
static inline vect3Df_s vsubf(vect3Df_s u, vect3Df_s v)
{
return (vect3Df_s){u.x-v.x,u.y-v.y,u.z-v.z};
}
static inline vect3Df_s vmulf(vect3Df_s v, float f)
{
return (vect3Df_s){v.x*f,v.y*f,v.z*f};
}
static inline vect3Df_s vscalef(vect3Df_s v1, vect3Df_s v2)
{
return (vect3Df_s){v1.x*v2.x,v1.y*v2.y,v1.z*v2.z};
}
static inline float vmagf(vect3Df_s v)
{
return sqrtf(v.x*v.x+v.y*v.y+v.z*v.z);
}
static inline float vdistf(vect3Df_s v1, vect3Df_s v2)
{
return sqrtf((v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y)+(v1.z-v2.z)*(v1.z-v2.z));
}
static inline vect3Df_s vnormf(vect3Df_s v)
{
const float l=sqrtf(v.x*v.x+v.y*v.y+v.z*v.z);
return (vect3Df_s){v.x/l,v.y/l,v.z/l};
}
typedef struct
{
float x, y, z, w;
}vect4Df_s;
static inline vect4Df_s vect4Df(float x, float y, float z, float w)
{
return (vect4Df_s){x,y,z,w};
}
static inline vect4Df_s vaddf4(vect4Df_s u, vect4Df_s v)
{
return (vect4Df_s){u.x+v.x,u.y+v.y,u.z+v.z,u.w+v.w};
}
static inline vect4Df_s vsubf4(vect4Df_s u, vect4Df_s v)
{
return (vect4Df_s){u.x-v.x,u.y-v.y,u.z-v.z,u.w-v.w};
}
static inline vect4Df_s vmulf4(vect4Df_s v, float f)
{
return (vect4Df_s){v.x*f,v.y*f,v.z*f,v.w*f};
}
static inline float vdotf4(vect4Df_s v1, vect4Df_s v2)
{
return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z+v1.w*v2.w;
}
static inline vect4Df_s vnormf4(vect4Df_s v)
{
const float l=sqrtf(v.x*v.x+v.y*v.y+v.z*v.z+v.w*v.w);
return (vect4Df_s){v.x/l,v.y/l,v.z/l,v.w/l};
}
//interstuff
static inline vect3Di_s vf2i(vect3Df_s v)
{
return (vect3Di_s){floorf(v.x),floorf(v.y),floorf(v.z)};
}
static inline vect3Df_s vi2f(vect3Di_s v)
{
return (vect3Df_s){(float)v.x,(float)v.y,(float)v.z};
}
void loadIdentity44(float* m);
void multMatrix44(float* m1, float* m2, float* m);
void translateMatrix(float* tm, float x, float y, float z);
void rotateMatrixX(float* tm, float x, bool r);
void rotateMatrixY(float* tm, float x, bool r);
void rotateMatrixZ(float* tm, float x, bool r);
void scaleMatrix(float* tm, float x, float y, float z);
void initProjectionMatrix(float* m, float fovy, float aspect, float near, float far);
void initOrthographicMatrix(float *m, float left, float right, float bottom, float top, float near, float far);
vect3Df_s getMatrixColumn(float* m, u8 i);
vect3Df_s getMatrixRow(float* m, u8 i);
vect4Df_s getMatrixColumn4(float* m, u8 i);
vect4Df_s getMatrixRow4(float* m, u8 i);
#ifdef __cplusplus
}
#endif
#endif

15
exportdoc.sh Normal file
View File

@ -0,0 +1,15 @@
#!/bin/sh
if [ "$TRAVIS_REPO_SLUG" = "Lectem/ctrulib" ] && [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_BRANCH" = "master" ]; then
sudo apt-get install -qq doxygen
git clone --branch=gh-pages --single-branch --depth 1 https://${GH_TOKEN}@github.com/Lectem/ctrulib docs
cd docs
git rm -rf ./*
cd ..
doxygen libctru/Doxyfile
cd docs
mv ./html/* .
git add --all
git commit -m"Doc generated from Travis build #$TRAVIS_BUILD_NUMBER"
git push -f origin gh-pages
fi