├── README.md ├── .gitignore ├── light ├── test1.map ├── Makefile └── source │ ├── light_lightmap.h │ ├── light_room_io.h │ ├── types.h │ ├── light_main.c │ ├── light_rectangle.h │ ├── light_room.h │ ├── light_lightmap.c │ ├── light_room_io.c │ ├── light_room.c │ ├── light_math.h │ └── light_math.c ├── content ├── cube.md2 ├── door.md2 ├── door.png ├── font.png ├── grid.md2 ├── grid.png ├── logo.png ├── out1.map ├── out2.map ├── out3.map ├── out4.map ├── out5.map ├── out6.map ├── out7.map ├── out8.map ├── test1.map ├── button1.md2 ├── button1.png ├── button1b.png ├── button2.md2 ├── button2.png ├── button2b.png ├── default.map ├── default.png ├── elevator.md2 ├── floor3.png ├── floor7.png ├── floor8.png ├── glados.md2 ├── glados.png ├── platform.md2 ├── ratman.md2 ├── ratman.png ├── sludge.png ├── test1.ini ├── companion.png ├── crosshair.png ├── door_close.raw ├── door_open.raw ├── energyball.md2 ├── energyball.png ├── gladoslair.png ├── menu_logo.png ├── portalgun.md2 ├── portalgun.png ├── ballcatcher.md2 ├── balllauncher.md2 ├── balllauncher.png ├── cubedispenser.md2 ├── cubedispenser.png ├── elevatorframe.md2 ├── elevatorroom.map ├── emancipation.raw ├── gladoslairv2.md2 ├── portal_enter1.raw ├── portal_enter2.raw ├── portal_exit1.raw ├── portal_exit2.raw ├── rotate_logo.png ├── storagecube.png ├── turret_deploy.raw ├── turret_fire.raw ├── portalgun_blue.png ├── portalgun_blue.raw ├── turret_retract.raw ├── balllauncheractive.png ├── portalgun_orange.png ├── portalgun_orange.raw ├── materials.ini └── slices.ini ├── include ├── menu │ ├── menu.h │ └── cameratransition.h ├── game │ ├── controls.h │ ├── sfx.h │ ├── pointphysics.h │ ├── sludge.h │ ├── room_io.h │ ├── bigbutton.h │ ├── door.h │ ├── activator.h │ ├── cubes.h │ ├── camera.h │ ├── platform.h │ ├── walldoor.h │ ├── timedbutton.h │ ├── material.h │ ├── light.h │ ├── elevator.h │ ├── energyball.h │ ├── emancipation.h │ ├── player.h │ ├── portal.h │ └── room.h ├── gfx │ ├── text.h │ ├── texture.h │ ├── gs.h │ └── md2.h ├── utils │ ├── filesystem.h │ ├── math.h │ └── dictionary.h └── physics │ ├── physics.h │ ├── physicsThread.h │ ├── AAR.h │ ├── request.h │ ├── PIC.h │ └── OBB.h ├── put3ds.bat ├── source ├── gfx │ ├── _gs.s │ ├── text.c │ └── texture.c ├── utils │ ├── xmem.c │ ├── filesystem.c │ └── math.c ├── game │ ├── activator.c │ ├── sfx.c │ ├── light.c │ ├── controls.c │ ├── elevator.c │ ├── door.c │ ├── camera.c │ ├── bigbutton.c │ ├── platform.c │ ├── timedbutton.c │ ├── sludge.c │ ├── walldoor.c │ ├── cubes.c │ └── material.c ├── physics │ ├── physics.c │ ├── physicsThread.c │ └── request.c └── menu │ └── cameratransition.c ├── portal3DS.sublime-project ├── tools ├── fontconv.py ├── texconv.py └── norm.py └── data ├── passthrough.vsh ├── logo.vsh ├── portal.vsh ├── room.vsh ├── emancipation.vsh └── text.vsh /README.md: -------------------------------------------------------------------------------- 1 | portal3DS 2 | ========= 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.o 3 | *.3dsx 4 | *.smdh 5 | *.elf 6 | -------------------------------------------------------------------------------- /light/test1.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/light/test1.map -------------------------------------------------------------------------------- /content/cube.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/cube.md2 -------------------------------------------------------------------------------- /content/door.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/door.md2 -------------------------------------------------------------------------------- /content/door.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/door.png -------------------------------------------------------------------------------- /content/font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/font.png -------------------------------------------------------------------------------- /content/grid.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/grid.md2 -------------------------------------------------------------------------------- /content/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/grid.png -------------------------------------------------------------------------------- /content/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/logo.png -------------------------------------------------------------------------------- /content/out1.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/out1.map -------------------------------------------------------------------------------- /content/out2.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/out2.map -------------------------------------------------------------------------------- /content/out3.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/out3.map -------------------------------------------------------------------------------- /content/out4.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/out4.map -------------------------------------------------------------------------------- /content/out5.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/out5.map -------------------------------------------------------------------------------- /content/out6.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/out6.map -------------------------------------------------------------------------------- /content/out7.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/out7.map -------------------------------------------------------------------------------- /content/out8.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/out8.map -------------------------------------------------------------------------------- /content/test1.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/test1.map -------------------------------------------------------------------------------- /content/button1.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/button1.md2 -------------------------------------------------------------------------------- /content/button1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/button1.png -------------------------------------------------------------------------------- /content/button1b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/button1b.png -------------------------------------------------------------------------------- /content/button2.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/button2.md2 -------------------------------------------------------------------------------- /content/button2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/button2.png -------------------------------------------------------------------------------- /content/button2b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/button2b.png -------------------------------------------------------------------------------- /content/default.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/default.map -------------------------------------------------------------------------------- /content/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/default.png -------------------------------------------------------------------------------- /content/elevator.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/elevator.md2 -------------------------------------------------------------------------------- /content/floor3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/floor3.png -------------------------------------------------------------------------------- /content/floor7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/floor7.png -------------------------------------------------------------------------------- /content/floor8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/floor8.png -------------------------------------------------------------------------------- /content/glados.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/glados.md2 -------------------------------------------------------------------------------- /content/glados.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/glados.png -------------------------------------------------------------------------------- /content/platform.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/platform.md2 -------------------------------------------------------------------------------- /content/ratman.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/ratman.md2 -------------------------------------------------------------------------------- /content/ratman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/ratman.png -------------------------------------------------------------------------------- /content/sludge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/sludge.png -------------------------------------------------------------------------------- /content/test1.ini: -------------------------------------------------------------------------------- 1 | [info] 2 | next=test2.map 3 | title=Test chamber 01 4 | author=smea 5 | -------------------------------------------------------------------------------- /include/menu/menu.h: -------------------------------------------------------------------------------- 1 | #ifndef MENU_H 2 | #define MENU_H 3 | 4 | 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /content/companion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/companion.png -------------------------------------------------------------------------------- /content/crosshair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/crosshair.png -------------------------------------------------------------------------------- /content/door_close.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/door_close.raw -------------------------------------------------------------------------------- /content/door_open.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/door_open.raw -------------------------------------------------------------------------------- /content/energyball.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/energyball.md2 -------------------------------------------------------------------------------- /content/energyball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/energyball.png -------------------------------------------------------------------------------- /content/gladoslair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/gladoslair.png -------------------------------------------------------------------------------- /content/menu_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/menu_logo.png -------------------------------------------------------------------------------- /content/portalgun.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/portalgun.md2 -------------------------------------------------------------------------------- /content/portalgun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/portalgun.png -------------------------------------------------------------------------------- /content/ballcatcher.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/ballcatcher.md2 -------------------------------------------------------------------------------- /content/balllauncher.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/balllauncher.md2 -------------------------------------------------------------------------------- /content/balllauncher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/balllauncher.png -------------------------------------------------------------------------------- /content/cubedispenser.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/cubedispenser.md2 -------------------------------------------------------------------------------- /content/cubedispenser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/cubedispenser.png -------------------------------------------------------------------------------- /content/elevatorframe.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/elevatorframe.md2 -------------------------------------------------------------------------------- /content/elevatorroom.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/elevatorroom.map -------------------------------------------------------------------------------- /content/emancipation.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/emancipation.raw -------------------------------------------------------------------------------- /content/gladoslairv2.md2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/gladoslairv2.md2 -------------------------------------------------------------------------------- /content/portal_enter1.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/portal_enter1.raw -------------------------------------------------------------------------------- /content/portal_enter2.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/portal_enter2.raw -------------------------------------------------------------------------------- /content/portal_exit1.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/portal_exit1.raw -------------------------------------------------------------------------------- /content/portal_exit2.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/portal_exit2.raw -------------------------------------------------------------------------------- /content/rotate_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/rotate_logo.png -------------------------------------------------------------------------------- /content/storagecube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/storagecube.png -------------------------------------------------------------------------------- /content/turret_deploy.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/turret_deploy.raw -------------------------------------------------------------------------------- /content/turret_fire.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/turret_fire.raw -------------------------------------------------------------------------------- /content/portalgun_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/portalgun_blue.png -------------------------------------------------------------------------------- /content/portalgun_blue.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/portalgun_blue.raw -------------------------------------------------------------------------------- /content/turret_retract.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/turret_retract.raw -------------------------------------------------------------------------------- /content/balllauncheractive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/balllauncheractive.png -------------------------------------------------------------------------------- /content/portalgun_orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/portalgun_orange.png -------------------------------------------------------------------------------- /content/portalgun_orange.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smealum/portal3DS/HEAD/content/portalgun_orange.raw -------------------------------------------------------------------------------- /content/materials.ini: -------------------------------------------------------------------------------- 1 | [material0] 2 | bottom=1 3 | side=0 4 | top=2 5 | 6 | [material1] 7 | bottom=4 8 | side=3 9 | top=3 10 | -------------------------------------------------------------------------------- /put3ds.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | WinSCP.com /command "option batch abort" "option confirm off" "open 3ds" "put %~dp0%1.3dsx /3ds/%1/boot.3dsx" "exit" 3 | -------------------------------------------------------------------------------- /include/game/controls.h: -------------------------------------------------------------------------------- 1 | #ifndef CONTROLS_H 2 | #define CONTROLS_H 3 | 4 | #include "game/player.h" 5 | 6 | void initControls(); 7 | void exitControls(); 8 | void updateControls(player_s* p); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /include/gfx/text.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXT_H 2 | #define TEXT_H 3 | 4 | void textInit(); 5 | void textExit(); 6 | void textStartDrawing(); 7 | char* textMakeString(const char* s); 8 | void textFreeString(char* s); 9 | void textDrawString(float x, float y, const char* s); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /source/gfx/_gs.s: -------------------------------------------------------------------------------- 1 | .section ".text" 2 | .arm 3 | .align 4 4 | .global _vboMemcpy50 5 | 6 | # r0 : dst 7 | # r1 : src 8 | # fixed size 0x50 9 | _vboMemcpy50: 10 | push {r4-r11} 11 | ldmia r1!, {r2-r12} 12 | stmia r0!, {r2-r12} 13 | ldmia r1!, {r2-r12} 14 | stmia r0!, {r2-r12} 15 | pop {r4-r11} 16 | bx lr 17 | -------------------------------------------------------------------------------- /include/utils/filesystem.h: -------------------------------------------------------------------------------- 1 | #ifndef FILESYSTEM_H 2 | #define FILESYSTEM_H 3 | 4 | #include <3ds.h> 5 | 6 | void filesystemInit(int argc, char** argv); 7 | void filesystemExit(); 8 | 9 | FILE* openFile(const char* fn, const char* mode); 10 | void* bufferizeFile(char* filename, u32* size, bool binary, bool linear); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /light/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all clean 2 | 3 | all: light.exe 4 | 5 | clean: 6 | @rm build/* 7 | @rm light.exe 8 | 9 | light.exe: build/light_main.o build/light_room.o build/light_room_io.o build/light_math.o build/light_lightmap.o build/light_rectangle.o 10 | gcc -o $@ $^ 11 | 12 | build/%.o: source/%.c 13 | gcc -c -o $@ -Wall $^ 14 | -------------------------------------------------------------------------------- /content/slices.ini: -------------------------------------------------------------------------------- 1 | [slice0] 2 | texture=default.png 3 | align=0 4 | factorx=1 5 | factory=2 6 | 7 | [slice1] 8 | texture=floor3.png 9 | align=0 10 | factor=1 11 | 12 | [slice2] 13 | texture=floor8.png 14 | align=0 15 | factor=1 16 | 17 | [slice3] 18 | texture=floor7.png 19 | align=0 20 | factorx=2 21 | factory=2 22 | 23 | [slice4] 24 | texture=floor7.png 25 | align=0 26 | factor=1 27 | -------------------------------------------------------------------------------- /light/source/light_lightmap.h: -------------------------------------------------------------------------------- 1 | #ifndef LIGHTMAP_H 2 | #define LIGHTMAP_H 3 | 4 | #include "light_room.h" 5 | 6 | typedef struct 7 | { 8 | vect3Di_s lmPos, lmSize; 9 | bool rot; 10 | }lightMapCoordinates_s; 11 | 12 | typedef struct 13 | { 14 | vect3Di_s lmSize; 15 | u8* buffer; 16 | lightMapCoordinates_s* coords; 17 | int num; 18 | }lightMapData_s; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /portal3DS.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "follow_symlinks": true, 6 | "path": "source" 7 | }, 8 | { 9 | "follow_symlinks": true, 10 | "path": "include" 11 | }, 12 | { 13 | "follow_symlinks": true, 14 | "path": "C:\\devkitPro\\ctrulib\\libctru\\source" 15 | }, 16 | { 17 | "follow_symlinks": true, 18 | "path": "C:\\devkitPro\\ctrulib\\libctru\\include" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /include/game/sfx.h: -------------------------------------------------------------------------------- 1 | #ifndef SFX_H 2 | #define SFX_H 3 | 4 | #define NUMSFX (32) 5 | 6 | typedef struct 7 | { 8 | u8* data; 9 | u32 size; 10 | u32 format; 11 | bool used; 12 | }SFX_s; 13 | 14 | void initSound(void); 15 | void exitSound(void); 16 | void initSFX(SFX_s* s); 17 | void loadSFX(SFX_s* s, char* filename, u32 format); 18 | SFX_s* createSFX(char* filename, u32 format); 19 | void playSFX(SFX_s* s); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/game/pointphysics.h: -------------------------------------------------------------------------------- 1 | #ifndef POINTPHYSICS_H 2 | #define POINTPHYSICS_H 3 | 4 | #include "utils/math.h" 5 | #include "game/room.h" 6 | 7 | typedef struct 8 | { 9 | vect3Df_s position, speed; 10 | float radius, sqRadius; 11 | bool contact; 12 | }physicalPoint_s; 13 | 14 | void initPhysicalPoint(physicalPoint_s* pp, vect3Df_s position, float radius); 15 | void updatePhysicalPoint(physicalPoint_s* pp); 16 | void collideObjectRoom(physicalPoint_s* pp, room_s* r); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/game/sludge.h: -------------------------------------------------------------------------------- 1 | #ifndef SLUDGE_H 2 | #define SLUDGE_H 3 | 4 | #include "utils/math.h" 5 | #include "game/room.h" 6 | #include "game/player.h" 7 | #include "physics/physics.h" 8 | 9 | #define SLUDGEMARGIN (TILESIZE) 10 | 11 | void initSludge(void); 12 | void exitSludge(void); 13 | void generateSludgeGeometry(void); 14 | void addSludgeRectangle(rectangle_s* rec); 15 | void drawSludge(room_s* r); 16 | void updateSludge(player_s* p); 17 | 18 | bool collideBoxSludge(OBB_s* o); 19 | bool collideAABBSludge(vect3Df_s p, vect3Df_s s); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/physics/physics.h: -------------------------------------------------------------------------------- 1 | #ifndef PHYSICS_H 2 | #define PHYSICS_H 3 | 4 | #include "physics/OBB.h" 5 | #include "physics/AAR.h" 6 | 7 | void initPhysics(); 8 | void exitPhysics(); 9 | 10 | void physicsCreateObb(OBB_s** out, vect3Df_s position, vect3Df_s size, md2_instance_t* model, float mass, float angle); 11 | void physicsResetObb(OBB_s* target, vect3Df_s position, vect3Df_s size, md2_instance_t* model, float mass, float angle); 12 | void physicsCreateAar(AAR_s** out, vect3Df_s position, vect3Df_s size, vect3Df_s normal); 13 | void physicsGenerateGrid(); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /light/source/light_room_io.h: -------------------------------------------------------------------------------- 1 | #ifndef ROOM_IO_H 2 | #define ROOM_IO_H 3 | 4 | #include "light_room.h" 5 | 6 | #define MAPHEADER_SIZE (256) 7 | 8 | #define MAP_READ_LIGHT (1<<0) 9 | #define MAP_READ_ENTITIES (1<<1) 10 | #define MAP_READ_INFO (1<<7) 11 | 12 | typedef struct 13 | { 14 | u32 dataSize; 15 | u32 dataPosition; 16 | u32 rectanglesPosition; 17 | u32 entityPosition; 18 | u32 lightPosition; 19 | u32 sludgePosition; 20 | 21 | u8 reserved[MAPHEADER_SIZE-6*4]; //for future use 22 | }mapHeader_s; 23 | 24 | void readRoom(char* filename, room_s* r, u8 flags); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/game/room_io.h: -------------------------------------------------------------------------------- 1 | #ifndef ROOM_IO_H 2 | #define ROOM_IO_H 3 | 4 | #include <3ds.h> 5 | #include "room.h" 6 | 7 | #define MAPHEADER_SIZE (256) 8 | 9 | #define MAP_READ_LIGHT (1<<0) 10 | #define MAP_READ_ENTITIES (1<<1) 11 | #define MAP_READ_INFO (1<<7) 12 | 13 | typedef struct 14 | { 15 | u32 dataSize; 16 | u32 dataPosition; 17 | u32 rectanglesPosition; 18 | u32 entityPosition; 19 | u32 lightPosition; 20 | u32 sludgePosition; 21 | 22 | u8 reserved[MAPHEADER_SIZE-6*4]; //for future use 23 | }mapHeader_s; 24 | 25 | void readRoom(char* filename, room_s* r, u8 flags); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /tools/fontconv.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import math 3 | import os 4 | import sys 5 | from PIL import Image 6 | 7 | srcfn=sys.argv[1] 8 | dstname=sys.argv[2] 9 | 10 | im = Image.open(srcfn) 11 | imout = Image.new("RGBA", (8,1024)) 12 | 13 | w, h = im.size 14 | 15 | for k in range(96): 16 | mx=7 17 | my=0 18 | for j in range(16): 19 | for i in range(16): 20 | if im.getpixel((k*16+i,j))[3]!=0: 21 | mx=min(mx,i) 22 | my=min(my,j) 23 | for j in range(8): 24 | for i in range(8): 25 | # pixel = im.getpixel((k*16+mx+i,j+my)) 26 | pixel = im.getpixel((k*16+mx+i,j)) 27 | imout.putpixel((i,k*8+j), pixel) 28 | 29 | imout.save(dstname) 30 | -------------------------------------------------------------------------------- /include/menu/cameratransition.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERATRANSITION_H 2 | #define CAMERATRANSITION_H 3 | 4 | #include "game/camera.h" 5 | 6 | typedef struct 7 | { 8 | vect3Df_s position, angle; 9 | }cameraState_s; 10 | 11 | typedef struct 12 | { 13 | cameraState_s *start, *finish; 14 | int progress, length; 15 | }cameraTransition_s; 16 | 17 | extern cameraState_s cameraStates[]; 18 | extern cameraTransition_s testTransition; 19 | 20 | void applyCameraState(camera_s* c, cameraState_s* cs); 21 | 22 | cameraTransition_s startCameraTransition(cameraState_s* s, cameraState_s* f, int length); 23 | void updateCameraTransition(camera_s* c, cameraTransition_s* ct); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/game/bigbutton.h: -------------------------------------------------------------------------------- 1 | #ifndef BIGBUTTON_H 2 | #define BIGBUTTON_H 3 | 4 | #include "utils/math.h" 5 | #include "game/room.h" 6 | #include "gfx/md2.h" 7 | #include "game/activator.h" 8 | #include "physics/physics.h" 9 | 10 | #define NUMBIGBUTTONS (16) 11 | 12 | typedef struct 13 | { 14 | room_s* room; 15 | rectangle_s* surface; 16 | activator_s activator; 17 | md2_instance_t modelInstance; 18 | vect3Df_s position; 19 | bool active; 20 | bool used; 21 | u8 id; 22 | }bigButton_s; 23 | 24 | void initBigButtons(void); 25 | void freeBigButtons(void); 26 | bigButton_s* createBigButton(room_s* r, vect3Di_s position); 27 | void drawBigButtons(void); 28 | void updateBigButtons(void); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/physics/physicsThread.h: -------------------------------------------------------------------------------- 1 | #ifndef PHYSICSTHREAD_H 2 | #define PHYSICSTHREAD_H 3 | 4 | #include <3ds.h> 5 | #include "physics/request.h" 6 | 7 | #define PHYSICSTHREAD_STACKSIZE (0x4000) 8 | #define PHYSICSTHREAD_TMPBUFSIZE (4096*20) 9 | 10 | typedef struct physicsThread_s 11 | { 12 | Handle thread; 13 | Handle requestMutex; 14 | bool exit; 15 | requestQueue_s privateList; //only accessible from producer 16 | requestQueue_s requestList; //accessible by anyone, given they've locked requestMutex 17 | u64 stack[PHYSICSTHREAD_STACKSIZE/8]; 18 | u64 tmpBuffer[PHYSICSTHREAD_TMPBUFSIZE/8]; 19 | }physicsThread_s; 20 | 21 | void initPhysicsThread(physicsThread_s* p); 22 | void exitPhysicsThread(physicsThread_s* p); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /source/utils/xmem.c: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | 5 | extern u8 __end__[]; // end of static code and data 6 | extern u8* fake_heap_start; 7 | extern u8* fake_heap_end; 8 | 9 | u8 *getHeapStart() { 10 | return __end__; 11 | } 12 | 13 | u8 *getHeapEnd() { 14 | return (u8 *)sbrk(0); 15 | } 16 | 17 | u8 *getHeapLimit() { 18 | return fake_heap_end; 19 | } 20 | 21 | size_t latestUsed, latestFree; 22 | 23 | size_t getMemUsed() { 24 | struct mallinfo mi = mallinfo(); 25 | latestUsed=mi.uordblks; 26 | return latestUsed; 27 | } 28 | 29 | size_t getMemFree() { 30 | struct mallinfo mi = mallinfo(); 31 | latestFree=mi.fordblks + (getHeapLimit() - getHeapEnd()); 32 | return latestFree; 33 | } 34 | -------------------------------------------------------------------------------- /include/game/door.h: -------------------------------------------------------------------------------- 1 | #ifndef DOOR_H 2 | #define DOOR_H 3 | 4 | #include "gfx/md2.h" 5 | #include "utils/math.h" 6 | #include "game/room.h" 7 | #include "game/activator.h" 8 | #include "game/sfx.h" 9 | 10 | #define NUMDOORS (16) 11 | 12 | typedef struct 13 | { 14 | activatableObject_s ao; 15 | vect3Df_s position; 16 | md2_instance_t modelInstance; 17 | rectangle_s* rectangle[2]; 18 | bool orientation; 19 | bool used; 20 | u8 id; 21 | }door_s; 22 | 23 | extern SFX_s* doorOpenSFX; 24 | extern SFX_s* doorCloseSFX; 25 | 26 | void initDoors(void); 27 | void exitDoors(void); 28 | door_s* createDoor(room_s* r, vect3Di_s position, bool orientation); 29 | void updateDoors(void); 30 | void drawDoors(void); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /include/game/activator.h: -------------------------------------------------------------------------------- 1 | #ifndef ACTIVATOR_H 2 | #define ACTIVATOR_H 3 | 4 | #define NUMACTIVATORSLOTS (4) 5 | 6 | typedef enum 7 | { 8 | DISPENSER_TARGET, 9 | PLATFORM_TARGET, 10 | DOOR_TARGET, 11 | WALLDOOR_TARGET, 12 | NOT_TARGET 13 | }activatorTarget_t; 14 | 15 | typedef struct 16 | { 17 | bool active, oldActive; 18 | }activatableObject_s; 19 | 20 | typedef struct 21 | { 22 | activatableObject_s* slot[NUMACTIVATORSLOTS]; 23 | u8 numSlots; 24 | }activator_s; 25 | 26 | void initActivator(activator_s* a); 27 | void initActivatableObject(activatableObject_s* ao); 28 | void useActivator(activator_s* a); 29 | void unuseActivator(activator_s* a); 30 | void addActivatorTarget(activator_s* a, activatableObject_s* target, activatorTarget_t type); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /include/gfx/texture.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXTURE_H 2 | #define TEXTURE_H 3 | 4 | #include <3ds.h> 5 | 6 | #define TEXTURES_NUM (256) 7 | 8 | typedef struct 9 | { 10 | char* filename; 11 | u32 width, height; 12 | u32 param; 13 | u32* data; 14 | u8 mipmap; 15 | GPU_TEXCOLOR format; 16 | bool used; 17 | }texture_s; 18 | 19 | 20 | void textureInit(); 21 | void textureExit(); 22 | 23 | texture_s* textureCreate(const char* fn, u32 param, int mipmap); 24 | texture_s* textureCreateBuffer(u32* buffer, int width, int height, u32 param, int mipmap); 25 | int textureLoadBuffer(texture_s* t, u32* buffer, int width, int height, u32 param, int mipmap); 26 | int textureLoad(texture_s* t, const char* fn, u32 param, int mipmap); 27 | void textureBind(texture_s* t, GPU_TEXUNIT unit); 28 | void textureFree(texture_s* t); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/game/cubes.h: -------------------------------------------------------------------------------- 1 | #ifndef CUBES_H 2 | #define CUBES_H 3 | 4 | #include "utils/math.h" 5 | #include "game/room.h" 6 | #include "gfx/md2.h" 7 | #include "game/activator.h" 8 | #include "physics/physics.h" 9 | 10 | #define NUMCUBEDISPENSERS (8) 11 | 12 | typedef struct 13 | { 14 | activatableObject_s ao; 15 | vect3Df_s position; 16 | md2_instance_t modelInstance; 17 | bool companion; 18 | rectangle_s* openingRectangle; 19 | OBB_s* currentCube; 20 | bool used; 21 | u8 id; 22 | }cubeDispenser_s; 23 | 24 | void initCubes(void); 25 | void exitCubes(void); 26 | void drawCubeDispensers(void); 27 | void updateCubeDispensers(void); 28 | void resetDispenserCube(OBB_s* o); 29 | void resetCubeDispenserCube(cubeDispenser_s* cd); 30 | cubeDispenser_s* createCubeDispenser(room_s* r, vect3Di_s pos, bool companion); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /tools/texconv.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import math 3 | import os 4 | import sys 5 | from PIL import Image 6 | 7 | tileOrder=[0,1,8,9,2,3,10,11,16,17,24,25,18,19,26,27,4,5,12,13,6,7,14,15,20,21,28,29,22,23,30,31,32,33,40,41,34,35,42,43,48,49,56,57,50,51,58,59,36,37,44,45,38,39,46,47,52,53,60,61,54,55,62,63] 8 | def parseTile(im, l, x, y): 9 | global tileOrder 10 | for k in range(8*8): 11 | i=tileOrder[k]%8 12 | j=int((tileOrder[k]-i)/8) 13 | pixel=im.getpixel((x+i,y+j)) 14 | l.append(((pixel[0]&0xFF)<<24)|((pixel[1]&0xFF)<<16)|((pixel[2]&0xFF)<<8)|(pixel[3]&0xFF)) 15 | 16 | srcfn=sys.argv[1] 17 | dstname=sys.argv[2] 18 | 19 | im = Image.open(srcfn) 20 | 21 | w, h = im.size 22 | 23 | # dstname=srcfn+".bin" 24 | 25 | l=[] 26 | for j in range(0,h,8): 27 | for i in range(0,w,8): 28 | parseTile(im, l, i, j) 29 | 30 | dst=open(dstname,"wb") 31 | for k in l: 32 | dst.write(struct.pack("I", k)) 33 | dst.close() 34 | -------------------------------------------------------------------------------- /include/game/camera.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERA_H 2 | #define CAMERA_H 3 | 4 | #include <3ds.h> 5 | #include "utils/math.h" 6 | 7 | typedef struct 8 | { 9 | mtx44 projection; 10 | mtx44 orientation; 11 | mtx44 modelview; //modelview = orientation*translate(position) 12 | vect3Df_s position; 13 | vect4Df_s frustumPlane[6]; 14 | }camera_s; 15 | 16 | void initCamera(camera_s* c); 17 | void updateCamera(camera_s* c); 18 | void useCamera(camera_s* c); 19 | 20 | void moveCamera(camera_s* c, vect3Df_s v); 21 | void rotateCamera(camera_s* c, vect3Df_s a); 22 | void setCameraPosition(camera_s* c, vect3Df_s v); 23 | 24 | bool pointInCameraFrustum(camera_s* c, vect3Df_s pt); 25 | bool aabbInCameraFrustum(camera_s* c, vect3Df_s o, vect3Df_s s, int planes); 26 | 27 | vect4Df_s projectPointCamera(camera_s* c, vect3Df_s p); 28 | vect3Df_s moveCameraVector(camera_s* c, vect3Df_s v, bool free); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /light/source/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | types.h _ Various system types. 3 | */ 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define U64_MAX UINT64_MAX 12 | 13 | typedef enum 14 | { 15 | mediatype_NAND, 16 | mediatype_SDMC, 17 | mediatype_GAMECARD, 18 | } mediatypes_enum; 19 | 20 | typedef uint8_t u8; 21 | typedef uint16_t u16; 22 | typedef uint32_t u32; 23 | typedef uint64_t u64; 24 | 25 | typedef int8_t s8; 26 | typedef int16_t s16; 27 | typedef int32_t s32; 28 | typedef int64_t s64; 29 | 30 | typedef volatile u8 vu8; 31 | typedef volatile u16 vu16; 32 | typedef volatile u32 vu32; 33 | typedef volatile u64 vu64; 34 | 35 | typedef volatile s8 vs8; 36 | typedef volatile s16 vs16; 37 | typedef volatile s32 vs32; 38 | typedef volatile s64 vs64; 39 | 40 | typedef u32 Handle; 41 | typedef s32 Result; 42 | typedef void (*ThreadFunc)(u32); 43 | 44 | #define BIT(n) (1U<<(n)) 45 | -------------------------------------------------------------------------------- /include/game/platform.h: -------------------------------------------------------------------------------- 1 | #ifndef PLATFORM_H 2 | #define PLATFORM_H 3 | 4 | #include "utils/math.h" 5 | #include "game/room.h" 6 | #include "gfx/md2.h" 7 | #include "game/activator.h" 8 | #include "game/player.h" 9 | #include "physics/physics.h" 10 | 11 | #define NUMPLATFORMS (8) 12 | #define PLATFORMSIZE (TILESIZE*3) //half 13 | 14 | typedef struct 15 | { 16 | activatableObject_s ao; 17 | vect3Df_s position, velocity; 18 | vect3Df_s origin, destination; 19 | AAR_s* aar; 20 | bool direction; //true=orig->dest 21 | bool touched, oldTouched; 22 | bool backandforth; 23 | bool used; 24 | u8 id; 25 | }platform_s; 26 | 27 | extern platform_s platform[NUMPLATFORMS]; 28 | 29 | void initPlatforms(void); 30 | void exitPlatforms(void); 31 | void drawPlatforms(void); 32 | void updatePlatforms(player_s* p); 33 | platform_s* createPlatform(room_s* r, vect3Di_s orig, vect3Di_s dest, bool BAF); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/game/walldoor.h: -------------------------------------------------------------------------------- 1 | #ifndef WALLDOOR_H 2 | #define WALLDOOR_H 3 | 4 | #include "gfx/md2.h" 5 | #include "utils/math.h" 6 | #include "game/room.h" 7 | #include "game/portal.h" 8 | #include "game/player.h" 9 | #include "game/elevator.h" 10 | #include "game/activator.h" 11 | 12 | typedef struct 13 | { 14 | activatableObject_s ao; 15 | vect3Df_s position; 16 | vect3Di_s gridPosition; 17 | u8 orientation; 18 | // rectangle_s* walls; 19 | md2_instance_t modelInstance; 20 | material_s* frameMaterial; 21 | rectangle_s* rectangle; 22 | elevator_s elevator; 23 | bool used; 24 | }wallDoor_s; 25 | 26 | extern wallDoor_s entryWallDoor; 27 | extern wallDoor_s exitWallDoor; 28 | 29 | void initWallDoors(void); 30 | void freeWallDoors(void); 31 | void updateWallDoors(player_s* pl); 32 | void setupWallDoor(room_s* r, wallDoor_s* wd, vect3Di_s position, u8 orientation); 33 | void drawWallDoors(void); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/game/timedbutton.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMEDBUTTON_H 2 | #define TIMEDBUTTON_H 3 | 4 | #include "utils/math.h" 5 | #include "gfx/md2.h" 6 | #include "game/room.h" 7 | #include "game/activator.h" 8 | #include "game/pointphysics.h" 9 | #include "physics/physics.h" 10 | 11 | #define NUMTIMEDBUTTONS (16) 12 | 13 | typedef struct 14 | { 15 | room_s* room; 16 | activator_s activator; 17 | md2_instance_t modelInstance; 18 | vect3Df_s position; 19 | float angle; 20 | u16 active; 21 | bool used; 22 | u8 id; 23 | }timedButton_s; 24 | 25 | void initTimedButtons(void); 26 | void exitTimedButtons(void); 27 | void activateTimedButton(timedButton_s* tb); 28 | timedButton_s* collideRayTimedButtons(vect3Df_s o, vect3Df_s v, float l); 29 | timedButton_s* createTimedButton(room_s* r, vect3Di_s position, float angle); 30 | bool checkObjectTimedButtonsCollision(physicalPoint_s* o, room_s* r); 31 | void drawTimedButtons(void); 32 | void updateTimedButtons(void); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/game/material.h: -------------------------------------------------------------------------------- 1 | #ifndef MATERIAL_H 2 | #define MATERIAL_H 3 | 4 | #include <3ds.h> 5 | #include "gfx/texture.h" 6 | 7 | #define NUMMATERIALS 256 8 | #define NUMMATERIALSLICES 256 9 | 10 | typedef struct 11 | { 12 | texture_s* img; 13 | u16 id; 14 | s16 factorX; 15 | s16 factorY; 16 | bool align; 17 | bool used; 18 | }materialSlice_s; 19 | 20 | typedef struct 21 | { 22 | materialSlice_s* top; 23 | materialSlice_s* side; 24 | materialSlice_s* bottom; 25 | u16 id; 26 | bool used; 27 | }material_s; 28 | 29 | static inline u16 getMaterialID(material_s* m){if(m)return m->id;return 0;} 30 | 31 | void initMaterials(void); 32 | material_s* createMaterial(); 33 | materialSlice_s* createMaterialSlice(); 34 | void loadMaterialSlice(materialSlice_s* ms, char* filename); 35 | void loadMaterialSlices(char* filename); 36 | void loadMaterials(char* filename); 37 | 38 | material_s* getMaterial(u16 i); 39 | 40 | char** getMaterialList(int* m, int** cl); 41 | void freeMaterialList(char** l); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /include/game/light.h: -------------------------------------------------------------------------------- 1 | #ifndef LIGHTING_H 2 | #define LIGHTING_H 3 | 4 | #include "utils/math.h" 5 | #include "gfx/texture.h" 6 | 7 | typedef enum 8 | { 9 | LIGHTMAP_DATA, 10 | VERTEXLIGHT_DATA 11 | }lightingData_t; 12 | 13 | typedef struct 14 | { 15 | vect3Di_s lmPos, lmSize; 16 | bool rot; 17 | }lightMapCoordinates_s; 18 | 19 | typedef struct 20 | { 21 | vect3Di_s lmSize; 22 | u8* buffer; 23 | lightMapCoordinates_s* coords; 24 | int num; 25 | texture_s* texture; 26 | }lightMapData_s; 27 | 28 | typedef struct 29 | { 30 | u8 width, height; 31 | u8* values; 32 | }vertexLightingData_s; 33 | 34 | typedef struct 35 | { 36 | lightingData_t type; 37 | union{ 38 | lightMapData_s lightMap; 39 | vertexLightingData_s* vertexLighting; 40 | }data; 41 | u16 size; 42 | }lightingData_s; 43 | 44 | void initLightData(lightingData_s* ld); 45 | void freeLightData(lightingData_s* ld); 46 | 47 | void initLightDataLM(lightingData_s* ld, u16 n); 48 | void initLightDataVL(lightingData_s* ld, u16 n); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /include/physics/AAR.h: -------------------------------------------------------------------------------- 1 | #ifndef AAR_H //axis aligned rectangle ! 2 | #define AAR_H 3 | 4 | #include "utils/math.h" 5 | #include "physics/OBB.h" 6 | 7 | #define NUMAARSEGMENTS (4) 8 | 9 | #define ORIGNODESIZE (4096) 10 | #define NODESIZE (nodeSize) 11 | 12 | typedef struct 13 | { 14 | vect3Df_s position, size, normal; 15 | bool touched; 16 | bool used; 17 | }AAR_s; 18 | // 4*3 + 4*3 + 4*3 + 1 = 37 19 | // 2*2 + 1 + 3*1 + 1 + 1 = 10 20 | 21 | typedef struct 22 | { 23 | u16* data; 24 | u8 length; 25 | }node_s; 26 | 27 | typedef struct 28 | { 29 | node_s* nodes; 30 | u16 width, height; 31 | vect3Df_s m, M; 32 | }grid_s; 33 | 34 | extern u32 nodeSize; 35 | 36 | void initAARs(void); 37 | void drawAARs(void); 38 | void toggleAAR(u16 id); 39 | void generateGrid(grid_s* g); 40 | void updateAAR(u16 id, vect3Df_s position); 41 | void AARsOBBContacts(OBB_s* o, bool sleep); 42 | AAR_s* createAAR(vect3Df_s position, vect3Df_s size, vect3Df_s normal); 43 | bool AAROBBContacts(AAR_s* a, OBB_s* o, vect3Df_s* v, bool port); 44 | bool intersectAABBAAR(vect3Df_s o1, vect3Df_s s, vect3Df_s o2, vect3Df_s sp); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/game/elevator.h: -------------------------------------------------------------------------------- 1 | #ifndef ELEVATOR_H 2 | #define ELEVATOR_H 3 | 4 | #include "gfx/md2.h" 5 | #include "utils/math.h" 6 | #include "game/room.h" 7 | 8 | #define ELEVATOR_UPDOWNBIT (4) 9 | #define ELEVATOR_SIZE (TILESIZE*3) 10 | 11 | #define ELEVATOR_RADIUS_IN (TILESIZE*2-0.03125/2) 12 | #define ELEVATOR_RADIUS_OUT (TILESIZE*2+0.03125) 13 | #define ELEVATOR_HEIGHT (TILESIZE*16) 14 | 15 | #define ELEVATOR_ANGLE (M_PI * 3 / 16) 16 | 17 | typedef enum 18 | { 19 | ELEVATOR_ARRIVING, 20 | ELEVATOR_OPENING, 21 | ELEVATOR_OPEN, 22 | ELEVATOR_CLOSING, 23 | ELEVATOR_LEAVING 24 | }elevatorState_t; 25 | 26 | typedef struct 27 | { 28 | vect3Df_s position, realPosition; 29 | rectangle_s* doorSurface; 30 | float progress; 31 | u8 direction; 32 | md2_instance_t modelInstance; 33 | elevatorState_t state; 34 | rectangle_s* floor; 35 | }elevator_s; 36 | 37 | void initElevators(void); 38 | void freeElevators(void); 39 | void initElevator(elevator_s* ev, room_s* r, vect3Di_s position, u8 direction, bool up); 40 | void setElevatorArriving(elevator_s* ev, float distance); 41 | void closeElevator(elevator_s* ev); 42 | void updateElevator(elevator_s* ev); 43 | void drawElevator(elevator_s* ev); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /source/game/activator.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds.h> 4 | #include "game/activator.h" 5 | #include "game/platform.h" 6 | #include "game/cubes.h" 7 | #include "utils/math.h" 8 | 9 | void initActivator(activator_s* a) 10 | { 11 | if(!a)return; 12 | 13 | a->numSlots=0; 14 | } 15 | 16 | void initActivatableObject(activatableObject_s* ao) 17 | { 18 | if(!ao)return; 19 | 20 | ao->active = false; 21 | ao->oldActive = false; 22 | } 23 | 24 | void changeActivation(activatableObject_s* ao, bool value) 25 | { 26 | if(!ao)return; 27 | 28 | ao->oldActive = ao->active; 29 | ao->active = value; 30 | } 31 | 32 | void useActivator(activator_s* a) 33 | { 34 | if(!a)return; 35 | int i; 36 | for(i=0;inumSlots;i++) 37 | { 38 | changeActivation(a->slot[i], true); 39 | } 40 | } 41 | 42 | void unuseActivator(activator_s* a) 43 | { 44 | if(!a)return; 45 | int i; 46 | for(i=0;inumSlots;i++) 47 | { 48 | changeActivation(a->slot[i], false); 49 | } 50 | } 51 | 52 | void addActivatorTarget(activator_s* a, activatableObject_s* target, activatorTarget_t type) 53 | { 54 | if(!a)return; 55 | if(a->numSlots>=NUMACTIVATORSLOTS)return; 56 | 57 | a->slot[a->numSlots] = target; 58 | 59 | a->numSlots++; 60 | unuseActivator(a); 61 | } 62 | -------------------------------------------------------------------------------- /include/game/energyball.h: -------------------------------------------------------------------------------- 1 | #ifndef ENERGYBALL_H 2 | #define ENERGYBALL_H 3 | 4 | #define NUMENERGYDEVICES (8) 5 | #define NUMENERGYBALLS (8) 6 | 7 | #include "utils/math.h" 8 | #include "game/room.h" 9 | #include "gfx/md2.h" 10 | #include "game/activator.h" 11 | #include "physics/physics.h" 12 | 13 | typedef enum 14 | { 15 | pX=0, 16 | mX=1, 17 | pY=2, 18 | mY=3, 19 | pZ=4, 20 | mZ=5 21 | }deviceOrientation_t; 22 | 23 | typedef struct 24 | { 25 | md2_instance_t modelInstance; 26 | deviceOrientation_t orientation; 27 | rectangle_s* surface; 28 | vect3Df_s position; 29 | activator_s activator; 30 | bool type; //true=launcher 31 | bool active; 32 | bool used; 33 | u8 id; 34 | }energyDevice_s; 35 | 36 | typedef struct 37 | { 38 | md2_instance_t modelInstance; 39 | energyDevice_s* launcher; 40 | vect3Df_s position, direction; 41 | float speed; 42 | u16 maxLife, life; 43 | bool used; 44 | u8 id; 45 | }energyBall_s; 46 | 47 | void initEnergyBalls(void); 48 | void exitEnergyBalls(void); 49 | 50 | energyDevice_s* createEnergyDevice(room_s* r, vect3Di_s pos, deviceOrientation_t or, bool type); 51 | void drawEnergyDevices(void); 52 | void updateEnergyDevices(void); 53 | 54 | energyBall_s* createEnergyBall(energyDevice_s* launcher, vect3Df_s pos, vect3Df_s dir, u16 life); 55 | void drawEnergyBalls(void); 56 | void updateEnergyBalls(room_s* r); 57 | 58 | #endif -------------------------------------------------------------------------------- /include/game/emancipation.h: -------------------------------------------------------------------------------- 1 | #ifndef EMANCIPATION_H 2 | #define EMANCIPATION_H 3 | 4 | #include "gfx/md2.h" 5 | #include "game/room.h" 6 | #include "game/player.h" 7 | #include "physics/OBB.h" 8 | 9 | #define NUMEMANCIPATIONGRIDS (16) 10 | #define NUMEMANCIPATORS (16) 11 | 12 | #define EMANCIPATIONGRIDHEIGHT (HEIGHTUNIT*8) 13 | #define BLACKENINGTIME (16*2) 14 | #define FADINGTIME (30) 15 | 16 | typedef struct 17 | { 18 | vect3Df_s position, velocity, axis; 19 | md2_instance_t modelInstance; 20 | float transformationMatrix[9]; 21 | float angle; 22 | u16 counter; 23 | bool used; 24 | }emancipator_s; 25 | 26 | typedef struct 27 | { 28 | vect3Df_s position; 29 | float length; 30 | bool direction; //true=Z, false=X 31 | bool used; 32 | }emancipationGrid_s; 33 | 34 | void initEmancipation(void); 35 | void exitEmancipation(void); 36 | 37 | void createEmancipator(md2_instance_t* mi, vect3Df_s pos, float* m); 38 | void updateEmancipators(void); 39 | void drawEmancipators(void); 40 | 41 | void createEmancipationGrid(room_s* r, vect3Di_s pos, float l, bool dir); 42 | void updateEmancipationGrids(player_s* pl); 43 | void drawEmancipationGrids(void); 44 | 45 | void getEmancipationGridAAR(emancipationGrid_s* eg, vect3Df_s* pos, vect3Df_s* sp); 46 | bool collideBoxEmancipationGrids(OBB_s* o); 47 | bool collideLineEmancipationGrids(vect3Df_s l, vect3Df_s v, float d); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/game/player.h: -------------------------------------------------------------------------------- 1 | #ifndef PLAYER_H 2 | #define PLAYER_H 3 | 4 | #include "utils/math.h" 5 | #include "game/pointphysics.h" 6 | #include "game/camera.h" 7 | #include "game/portal.h" 8 | #include "game/room.h" 9 | #include "game/sfx.h" 10 | #include "gfx/md2.h" 11 | 12 | #define PLAYER_RADIUS 1.2f 13 | 14 | typedef enum 15 | { 16 | PORTALGUN_IDLE = 0, 17 | PORTALGUN_SHOOT = 1, 18 | PORTALGUN_HOLD = 2, 19 | }portalGunAnim_t; 20 | 21 | typedef struct 22 | { 23 | md2_instance_t gunInstance; 24 | md2_instance_t ratmanInstance; 25 | physicalPoint_s object; 26 | camera_s camera; 27 | int life; 28 | vect3Df_s tempAngle; 29 | float walkCnt1, walkCnt2; 30 | bool inPortal, oldInPortal; 31 | bool flying; 32 | }player_s; 33 | 34 | extern SFX_s *gunSFX1, *gunSFX2; 35 | extern SFX_s *portalEnterSFX[2]; 36 | extern SFX_s *portalExitSFX[2]; 37 | 38 | extern texture_s gunTextureOrange, gunTextureBlue, ratmanTexture; 39 | 40 | void playerInit(void); 41 | void playerExit(void); 42 | 43 | void initPlayer(player_s* p); 44 | void updatePlayer(player_s* p, room_s* r); 45 | void updatePlayerWalk(player_s* p, float wc1, float wc2); 46 | 47 | void drawPlayer(player_s* p); 48 | void drawPlayerGun(player_s* p); 49 | 50 | void movePlayer(player_s* p, vect3Df_s v); 51 | void rotatePlayer(player_s* p, vect3Df_s v); 52 | 53 | void shootPlayerGun(player_s* p, room_s* r, portal_s* portal); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/game/portal.h: -------------------------------------------------------------------------------- 1 | #ifndef PORTAL_H 2 | #define PORTAL_H 3 | 4 | #include "utils/math.h" 5 | #include "game/room.h" 6 | #include "game/camera.h" 7 | #include "physics/AAR.h" 8 | 9 | #define NUM_PORTALS (2) 10 | 11 | #define PORTAL_HEIGHT (3.8f) 12 | #define PORTAL_WIDTH (1.8f) 13 | 14 | typedef struct portal_s 15 | { 16 | vect3Df_s position; 17 | vect3Df_s normal, plane[2]; 18 | vect3Df_s color; 19 | float matrix[4*4]; 20 | struct portal_s* target; 21 | AAR_s guideAAR[4]; 22 | float oldPlayerZ; 23 | bool oldPlayerR; 24 | bool open, draw; 25 | }portal_s; 26 | 27 | extern portal_s portals[NUM_PORTALS]; 28 | 29 | typedef void (*renderSceneCallback_t)(camera_s* c, portal_s* p, int depth, u8 stencil); 30 | 31 | void portalInit(); 32 | void portalExit(); 33 | 34 | void resetPortals(); 35 | 36 | void initPortal(portal_s* p); 37 | void drawPortals(portal_s* portals[], int n, renderSceneCallback_t callback, camera_s* c, int depth, u8 stencil); 38 | 39 | vect3Df_s warpPortalVector(portal_s* p, vect3Df_s v); 40 | void warpPortalMatrix(portal_s* p, float* m); 41 | 42 | bool isPointInPortal(portal_s* p, vect3Df_s o, vect3Df_s *v, float* x, float* y, float* z); 43 | 44 | void updatePortalOrientation(portal_s* p, vect3Df_s plane0, vect3Df_s normal); 45 | 46 | void generateGuideAAR(portal_s* p); 47 | 48 | void ejectPortalOBBs(portal_s* p); 49 | 50 | bool isPortalOnWall(room_s* r, portal_s* p, bool fix); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /data/passthrough.vsh: -------------------------------------------------------------------------------- 1 | ; make sure you update aemstro_as for this (01/01/15) 2 | 3 | ; setup constants 4 | .const c82, 1.0, 1.0, 1.0, 1.0 5 | .const c83, 0.0, 0.0, 0.0, 0.0 6 | 7 | ; setup outmap 8 | .out o0, result.position, 0xF 9 | .out o1, result.color, 0xF 10 | .out o2, result.texcoord0, 0x3 11 | .out o3, result.texcoord1, 0x3 12 | 13 | ; setup uniform map (required to use SHDR_GetUniformRegister) 14 | .uniform c84, c87, projection ; c84-c87 = projection matrix 15 | .uniform c88, c91, modelview ; c88-c91 = modelview matrix 16 | 17 | ; setup vsh and gsh 18 | .vsh main, endmain 19 | 20 | ; code 21 | main: 22 | ; tempreg = mdlvMtx * in.pos 23 | mov o0, v0 (0x6) 24 | mov o0, c82 (0x3) 25 | 26 | ; result.texcoord = in.texcoord 27 | mov o2, v1 (0x5) 28 | mov o3, v1 (0x5) 29 | 30 | ; result.color = EXPERIMENTS ! 31 | mov o1, c82 (0x5) 32 | 33 | end 34 | nop 35 | endmain: 36 | 37 | ; operand descriptors 38 | .opdesc x___, xyzw, xyzw ; 0x0 39 | .opdesc _y__, xyzw, xyzw ; 0x1 40 | .opdesc __z_, xyzw, xyzw ; 0x2 41 | .opdesc ___w, xyzw, xyzw ; 0x3 42 | .opdesc xyzw, zzzy, xyzw ; 0x4 43 | .opdesc xyzw, xyzw, xyzw ; 0x5 44 | .opdesc xyz_, xyzw, xyzw ; 0x6 45 | .opdesc xyzw, yyyw, xyzw ; 0x7 46 | .opdesc x___, wwww, xyzw ; 0x8 47 | .opdesc xyzw, xyzw, xxxx, xyzw ; 0x9 48 | .opdesc xyzw, xyzw, -xyzw ; 0xa 49 | .opdesc xyzw, xxxx, wwww ; 0xb 50 | .opdesc xyzw, -xxxx, wwww ; 0xc 51 | .opdesc xy__, yzzz, xyzw ; 0xd 52 | -------------------------------------------------------------------------------- /source/physics/physics.c: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | 3 | #include "physics/physics.h" 4 | #include "physics/physicsThread.h" 5 | 6 | physicsThread_s physicsThread; 7 | 8 | void initPhysics() 9 | { 10 | initOBBs(); 11 | initAARs(); 12 | 13 | initPhysicsThread(&physicsThread); 14 | } 15 | 16 | void exitPhysics() 17 | { 18 | exitPhysicsThread(&physicsThread); 19 | } 20 | 21 | void physicsCreateObb(OBB_s** out, vect3Df_s position, vect3Df_s size, md2_instance_t* model, float mass, float angle) 22 | { 23 | svcWaitSynchronization(physicsThread.requestMutex, U64_MAX); 24 | queueRequest(&physicsThread.requestList, createRequestCreateObb(out, position, size, model, mass, angle)); 25 | svcReleaseMutex(physicsThread.requestMutex); 26 | } 27 | 28 | void physicsResetObb(OBB_s* target, vect3Df_s position, vect3Df_s size, md2_instance_t* model, float mass, float angle) 29 | { 30 | svcWaitSynchronization(physicsThread.requestMutex, U64_MAX); 31 | queueRequest(&physicsThread.requestList, createRequestResetObb(target, position, size, model, mass, angle)); 32 | svcReleaseMutex(physicsThread.requestMutex); 33 | } 34 | 35 | void physicsCreateAar(AAR_s** out, vect3Df_s position, vect3Df_s size, vect3Df_s normal) 36 | { 37 | svcWaitSynchronization(physicsThread.requestMutex, U64_MAX); 38 | queueRequest(&physicsThread.requestList, createRequestCreateAar(out, position, size, normal)); 39 | svcReleaseMutex(physicsThread.requestMutex); 40 | } 41 | 42 | void physicsGenerateGrid() 43 | { 44 | svcWaitSynchronization(physicsThread.requestMutex, U64_MAX); 45 | queueRequest(&physicsThread.requestList, createRequestGenerateGrid()); 46 | svcReleaseMutex(physicsThread.requestMutex); 47 | } 48 | -------------------------------------------------------------------------------- /data/logo.vsh: -------------------------------------------------------------------------------- 1 | ; make sure you update aemstro_as for this (01/01/15) 2 | 3 | ; setup constants 4 | .const c81, 0.0009765625, 0.0009765625, 1.0, 1.0 5 | .const c82, 82.0, 0.5774, 0.5, 1.0 6 | .const c83, 1.0, 1.0, 1.0, 1.0 7 | 8 | ; setup outmap 9 | .out o0, result.position, 0xF 10 | .out o1, result.color, 0xF 11 | .out o2, result.texcoord0, 0x3 12 | .out o3, result.texcoord1, 0x3 13 | .out o4, result.view, 0xF 14 | 15 | ; setup uniform map (required to use SHDR_GetUniformRegister) 16 | .uniform c84, c87, projection ; c84-c87 = projection matrix 17 | .uniform c88, c91, modelview ; c88-c91 = modelview matrix 18 | .uniform c92, c92, textureDimensions 19 | 20 | ; setup vsh and gsh 21 | .vsh main, endmain 22 | 23 | ; code 24 | main: 25 | ; tempreg = mdlvMtx * in.pos 26 | dp4 o0, c88, v0 (0x0) 27 | dp4 o0, c89, v0 (0x1) 28 | dp4 o0, c90, v0 (0x2) 29 | mov o0, c82 (0x3) 30 | 31 | mov o4, r0 (0x5) 32 | 33 | ; result.texcoord = in.texcoord 34 | mul o2, c92, v0 (0x5) 35 | mul o3, c81, v0 (0x5) 36 | 37 | ; result.color = EXPERIMENTS ! 38 | mov o1, c83 (0x5) 39 | 40 | end 41 | nop 42 | endmain: 43 | 44 | ; operand descriptors 45 | .opdesc x___, xyzw, xyzw ; 0x0 46 | .opdesc _y__, xyzw, xyzw ; 0x1 47 | .opdesc __z_, xyzw, xyzw ; 0x2 48 | .opdesc ___w, xyzw, xyzw ; 0x3 49 | .opdesc xyzw, zzzy, xyzw ; 0x4 50 | .opdesc xyzw, xyzw, xyzw ; 0x5 51 | .opdesc xyz_, xyzw, xyzw ; 0x6 52 | .opdesc xyzw, yyyw, xyzw ; 0x7 53 | .opdesc x___, wwww, xyzw ; 0x8 54 | .opdesc xyzw, xyzw, xxxx, xyzw ; 0x9 55 | .opdesc xyzw, xyzw, -xyzw ; 0xa 56 | .opdesc xyzw, xxxx, wwww ; 0xb 57 | .opdesc xyzw, -xxxx, wwww ; 0xc 58 | .opdesc xy__, yzzz, xyzw ; 0xd 59 | -------------------------------------------------------------------------------- /source/game/sfx.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds.h> 4 | #include "game/sfx.h" 5 | #include "utils/filesystem.h" 6 | 7 | SFX_s SFX[NUMSFX]; 8 | 9 | bool soundEnabled; 10 | 11 | void initSound() 12 | { 13 | int i; 14 | for(i=0;idata=NULL; 46 | s->size=0; 47 | s->used=true; 48 | } 49 | 50 | void loadSFX(SFX_s* s, char* filename, u32 format) 51 | { 52 | if(!s)return; 53 | 54 | initSFX(s); 55 | 56 | s->data=bufferizeFile(filename, &s->size, true, true); 57 | s->format=format; 58 | } 59 | 60 | SFX_s* createSFX(char* filename, u32 format) 61 | { 62 | int i; 63 | for(i=0;iused || !s->data || !soundEnabled)return; 81 | 82 | channel++; 83 | channel%=8; 84 | 85 | // soundPlaySample(s->data, s->format, s->size, 22050, 127, 64, false, 0); 86 | csndPlaySound(channel+8, s->format, 22050, 1.0, 0.0, (u32*)s->data, (u32*)s->data, s->size); 87 | } 88 | -------------------------------------------------------------------------------- /source/physics/physicsThread.c: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | 4 | #include "physics/physicsThread.h" 5 | #include "physics/OBB.h" 6 | 7 | void physicsThreadMain(u32 arg) 8 | { 9 | physicsThread_s* p=(physicsThread_s*)arg; 10 | while(!p->exit) 11 | { 12 | svcWaitSynchronization(p->requestMutex, U64_MAX); 13 | appendRequestQueue(&p->privateList, &p->requestList); 14 | svcReleaseMutex(p->requestMutex); 15 | 16 | // bool debug=false; 17 | // u64 val=svcGetSystemTick(); 18 | 19 | request_s* r=NULL; 20 | while((r=unqueueRequest(&p->privateList)) && !p->exit) 21 | { 22 | handleRequest(p, r); 23 | svcSleepThread(1000); 24 | } 25 | 26 | // if(debug)print("%d ticks\n",(int)(svcGetSystemTick()-val)); 27 | updateOBBs(); 28 | 29 | svcSleepThread(1000000); 30 | } 31 | svcExitThread(); 32 | } 33 | 34 | void initPhysicsThread(physicsThread_s* p) 35 | { 36 | if(!p)return; 37 | 38 | initRequestQueue(&p->privateList); 39 | initRequestQueue(&p->requestList); 40 | 41 | p->exit=false; 42 | svcCreateMutex(&p->requestMutex, false); 43 | Result val = svcCreateThread(&p->thread, (void*)physicsThreadMain, (u32)p, (u32*)&p->stack[PHYSICSTHREAD_STACKSIZE/8], 0x18, 1); 44 | printf("%08X (%08X)\n",(unsigned int)val,(unsigned int)p->thread); 45 | if(val) 46 | { 47 | //thread creation failed ! what do we do ?! 48 | printf("physics thread creation failed ! what do we do ?!\n"); 49 | printf("%08X %08X %08X\n", (u32)physicsThreadMain, (u32)p, (u32)&p->stack[PHYSICSTHREAD_STACKSIZE/8]); 50 | while(1); 51 | } 52 | } 53 | 54 | void exitPhysicsThread(physicsThread_s* p) 55 | { 56 | if(!p)return; 57 | 58 | p->exit=true; 59 | svcWaitSynchronization(p->thread, U64_MAX); 60 | svcCloseHandle(p->requestMutex); 61 | svcCloseHandle(p->thread); 62 | } 63 | -------------------------------------------------------------------------------- /source/utils/filesystem.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include <3ds.h> 5 | #include "utils/filesystem.h" 6 | 7 | #define directoryName "content/" 8 | #define defaultPath ("sdmc:/" directoryName) 9 | 10 | static char* currentPath=NULL; 11 | 12 | void filesystemInit(int argc, char** argv) 13 | { 14 | if(argc && argv && !memcmp("sdmc:", argv[0], 5)) 15 | { 16 | //grab path from arguments 17 | int l; for(l=strlen(argv[0]); l>=0 && argv[0][l]!='/'; l--); 18 | l++; currentPath=malloc(l+strlen(directoryName)+1); 19 | memcpy(currentPath, argv[0], l); 20 | strcpy(¤tPath[l], directoryName); 21 | }else{ 22 | currentPath=(char*)defaultPath; 23 | } 24 | printf("%d\n%s\n",argv[0],currentPath); 25 | } 26 | 27 | void filesystemExit() 28 | { 29 | 30 | } 31 | 32 | FILE* openFile(const char* fn, const char* mode) 33 | { 34 | if(!fn || !mode)return NULL; 35 | static char fullPath[1024]; 36 | sprintf(fullPath, "%s%s", currentPath, fn); 37 | printf("opening %s\n", fullPath); 38 | return fopen(fullPath, mode); 39 | } 40 | 41 | void* bufferizeFile(char* filename, u32* size, bool binary, bool linear) 42 | { 43 | FILE* file; 44 | 45 | if(!binary)file = openFile(filename, "r+"); 46 | else file = openFile(filename, "rb+"); 47 | 48 | if(!file)return NULL; 49 | 50 | u8* buffer; 51 | long lsize; 52 | fseek (file, 0 , SEEK_END); 53 | lsize = ftell (file); 54 | rewind (file); 55 | if(linear)buffer=(u8*)linearMemAlign(lsize, 0x80); 56 | else buffer=(u8*)malloc(lsize); 57 | if(size)*size=lsize; 58 | 59 | if(!buffer) 60 | { 61 | fclose(file); 62 | return NULL; 63 | } 64 | 65 | fread(buffer, 1, lsize, file); 66 | fclose(file); 67 | return buffer; 68 | } 69 | -------------------------------------------------------------------------------- /source/game/light.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds.h> 3 | #include "game/light.h" 4 | 5 | void initLightData(lightingData_s* ld) 6 | { 7 | if(!ld)return; 8 | 9 | ld->type=LIGHTMAP_DATA; 10 | ld->size=0; 11 | ld->data.lightMap.buffer=NULL; 12 | ld->data.lightMap.coords=NULL; 13 | } 14 | 15 | void freeLightData(lightingData_s* ld) 16 | { 17 | if(!ld)return; 18 | 19 | switch(ld->type) 20 | { 21 | case LIGHTMAP_DATA: 22 | if(ld->data.lightMap.coords)free(ld->data.lightMap.coords); 23 | if(ld->data.lightMap.buffer)free(ld->data.lightMap.buffer); 24 | ld->data.lightMap.buffer=NULL; 25 | ld->data.lightMap.coords=NULL; 26 | if(ld->data.lightMap.texture)textureFree(ld->data.lightMap.texture); 27 | ld->size=0; 28 | break; 29 | case VERTEXLIGHT_DATA: 30 | if(ld->data.vertexLighting) 31 | { 32 | int i; 33 | for(i=0;isize;i++)if(ld->data.vertexLighting[i].values){free(ld->data.vertexLighting[i].values);ld->data.vertexLighting[i].values=NULL;} 34 | free(ld->data.vertexLighting); 35 | ld->data.vertexLighting=NULL; 36 | } 37 | break; 38 | } 39 | } 40 | 41 | //LIGHTMAP 42 | 43 | void initLightDataLM(lightingData_s* ld, u16 n) 44 | { 45 | if(!ld)return; 46 | 47 | ld->type=LIGHTMAP_DATA; 48 | ld->size=n; 49 | ld->data.lightMap.lmSize=vect3Di(0,0,0); 50 | ld->data.lightMap.buffer=NULL; 51 | ld->data.lightMap.coords=(lightMapCoordinates_s*)malloc(sizeof(lightMapCoordinates_s)*n); 52 | ld->data.lightMap.texture=NULL; 53 | } 54 | 55 | // VERTEX LIGHTING 56 | 57 | void initLightDataVL(lightingData_s* ld, u16 n) 58 | { 59 | if(!ld)return; 60 | 61 | ld->type=VERTEXLIGHT_DATA; 62 | ld->size=n; 63 | ld->data.vertexLighting=(vertexLightingData_s*)malloc(sizeof(vertexLightingData_s)*n); 64 | } 65 | 66 | -------------------------------------------------------------------------------- /light/source/light_main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "light_room.h" 4 | #include "light_room_io.h" 5 | #include "light_lightmap.h" 6 | 7 | void* bufferizeFile(char* filename, u32* size, bool binary) 8 | { 9 | FILE* file; 10 | 11 | if(!binary)file = fopen(filename, "r+"); 12 | else file = fopen(filename, "rb+"); 13 | 14 | if(!file)return NULL; 15 | 16 | u8* buffer; 17 | long lsize; 18 | fseek (file, 0 , SEEK_END); 19 | lsize = ftell (file); 20 | rewind (file); 21 | buffer=(u8*)malloc(lsize); 22 | if(size)*size=lsize; 23 | 24 | if(!buffer) 25 | { 26 | fclose(file); 27 | return NULL; 28 | } 29 | 30 | fread(buffer, 1, lsize, file); 31 | fclose(file); 32 | return buffer; 33 | } 34 | 35 | void writeVect3Di(vect3Di_s* v, FILE* f) 36 | { 37 | if(!v || !f)return; 38 | 39 | fwrite(v, sizeof(vect3Di_s), 1, f); 40 | } 41 | 42 | extern u8 currentResolution; 43 | 44 | int main(int argc, char** argv) 45 | { 46 | if(argc < 3) 47 | { 48 | printf("AS3D lightmap generator\n"); 49 | printf("\t usage : light \n"); 50 | return 0; 51 | } 52 | 53 | room_s room; 54 | readRoom(argv[1], &room, 0); 55 | lightMapData_s ld; 56 | while(generateLightmaps(&room, &ld)<0)currentResolution--; 57 | printf("final resolution : %d\n",currentResolution); 58 | 59 | u32 size; 60 | u8* buffer = bufferizeFile(argv[1], &size, true); 61 | 62 | FILE* f = fopen(argv[2], "wb"); 63 | 64 | mapHeader_s* h = (mapHeader_s*)buffer; 65 | h->lightPosition = size; 66 | 67 | fwrite(buffer, size, 1, f); 68 | 69 | writeVect3Di(&ld.lmSize,f); 70 | fwrite(ld.buffer, sizeof(u8), ld.lmSize.x*ld.lmSize.y, f); 71 | fwrite(ld.coords, sizeof(lightMapCoordinates_s), ld.num, f); 72 | 73 | fclose(f); 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /data/portal.vsh: -------------------------------------------------------------------------------- 1 | ; make sure you update aemstro_as for this (01/01/15) 2 | 3 | ; setup constants 4 | .const c82, 1.0, 1.0, 1.0, 1.0 5 | .const c83, 0.0, 0.0, 0.0, 0.0 6 | 7 | ; setup outmap 8 | .out o0, result.position, 0xF 9 | .out o1, result.color, 0xF 10 | .out o2, result.texcoord0, 0x3 11 | .out o3, result.texcoord1, 0x3 12 | 13 | ; setup uniform map (required to use SHDR_GetUniformRegister) 14 | .uniform c80, c80, color ; c80 = color 15 | .uniform c84, c87, projection ; c84-c87 = projection matrix 16 | .uniform c88, c91, modelview ; c88-c91 = modelview matrix 17 | 18 | ; setup vsh and gsh 19 | .vsh main, endmain 20 | 21 | ; code 22 | main: 23 | ; tempreg = mdlvMtx * in.pos 24 | dp4 r0, c88, v0 (0x0) 25 | dp4 r0, c89, v0 (0x1) 26 | dp4 r0, c90, v0 (0x2) 27 | mov r0, c82 (0x3) 28 | 29 | ; result.pos = projMtx * tempreg 30 | dp4 o0, c84, r0 (0x0) 31 | dp4 o0, c85, r0 (0x1) 32 | dp4 o0, c87, r0 (0x3) 33 | 34 | ifu end_if, else, b0 35 | dp4 o0, c86, r0 (0x2) 36 | else: 37 | mov o0, c83 (0x2) 38 | end_if: 39 | 40 | ; result.texcoord = in.texcoord 41 | mov o2, c82 (0x5) 42 | mov o3, c82 (0x5) 43 | 44 | ; result.color = EXPERIMENTS ! 45 | mov o1, c80 (0x5) 46 | 47 | end 48 | nop 49 | endmain: 50 | 51 | ; operand descriptors 52 | .opdesc x___, xyzw, xyzw ; 0x0 53 | .opdesc _y__, xyzw, xyzw ; 0x1 54 | .opdesc __z_, xyzw, xyzw ; 0x2 55 | .opdesc ___w, xyzw, xyzw ; 0x3 56 | .opdesc xyzw, zzzy, xyzw ; 0x4 57 | .opdesc xyzw, xyzw, xyzw ; 0x5 58 | .opdesc xyz_, xyzw, xyzw ; 0x6 59 | .opdesc xyzw, yyyw, xyzw ; 0x7 60 | .opdesc x___, wwww, xyzw ; 0x8 61 | .opdesc xyzw, xyzw, xxxx, xyzw ; 0x9 62 | .opdesc xyzw, xyzw, -xyzw ; 0xa 63 | .opdesc xyzw, xxxx, wwww ; 0xb 64 | .opdesc xyzw, -xxxx, wwww ; 0xc 65 | .opdesc xy__, yzzz, xyzw ; 0xd 66 | -------------------------------------------------------------------------------- /data/room.vsh: -------------------------------------------------------------------------------- 1 | ; make sure you update aemstro_as for this (01/01/15) 2 | 3 | ; setup constants 4 | .const c81, 0.0009765625, 0.0009765625, 1.0, 1.0 5 | .const c82, 82.0, 0.5774, 0.5, 1.0 6 | .const c83, 1.0, 1.0, 1.0, 1.0 7 | 8 | ; setup outmap 9 | .out o0, result.position, 0xF 10 | .out o1, result.color, 0xF 11 | .out o2, result.texcoord0, 0x3 12 | .out o3, result.texcoord1, 0x3 13 | .out o4, result.view, 0xF 14 | 15 | ; setup uniform map (required to use SHDR_GetUniformRegister) 16 | .uniform c84, c87, projection ; c84-c87 = projection matrix 17 | .uniform c88, c91, modelview ; c88-c91 = modelview matrix 18 | .uniform c92, c92, textureDimensions 19 | 20 | ; setup vsh and gsh 21 | .vsh main, endmain 22 | 23 | ; code 24 | main: 25 | ; tempreg = mdlvMtx * in.pos 26 | dp4 r0, c88, v0 (0x0) 27 | dp4 r0, c89, v0 (0x1) 28 | dp4 r0, c90, v0 (0x2) 29 | mov r0, c82 (0x3) 30 | 31 | mov o4, r0 (0x5) 32 | 33 | ; result.pos = projMtx * tempreg 34 | dp4 o0, c84, r0 (0x0) 35 | dp4 o0, c85, r0 (0x1) 36 | dp4 o0, c86, r0 (0x2) 37 | dp4 o0, c87, r0 (0x3) 38 | 39 | ; result.texcoord = in.texcoord 40 | mul o2, c92, v1 (0x5) 41 | mul o3, c81, v2 (0x5) 42 | 43 | ; result.color = EXPERIMENTS ! 44 | mov o1, c83 (0x5) 45 | 46 | end 47 | nop 48 | endmain: 49 | 50 | ; operand descriptors 51 | .opdesc x___, xyzw, xyzw ; 0x0 52 | .opdesc _y__, xyzw, xyzw ; 0x1 53 | .opdesc __z_, xyzw, xyzw ; 0x2 54 | .opdesc ___w, xyzw, xyzw ; 0x3 55 | .opdesc xyzw, zzzy, xyzw ; 0x4 56 | .opdesc xyzw, xyzw, xyzw ; 0x5 57 | .opdesc xyz_, xyzw, xyzw ; 0x6 58 | .opdesc xyzw, yyyw, xyzw ; 0x7 59 | .opdesc x___, wwww, xyzw ; 0x8 60 | .opdesc xyzw, xyzw, xxxx, xyzw ; 0x9 61 | .opdesc xyzw, xyzw, -xyzw ; 0xa 62 | .opdesc xyzw, xxxx, wwww ; 0xb 63 | .opdesc xyzw, -xxxx, wwww ; 0xc 64 | .opdesc xy__, yzzz, xyzw ; 0xd 65 | -------------------------------------------------------------------------------- /data/emancipation.vsh: -------------------------------------------------------------------------------- 1 | ; make sure you update aemstro_as for this (01/01/15) 2 | 3 | ; setup constants 4 | .const c81, 0.0009765625, 0.0009765625, 1.0, 1.0 5 | .const c82, 82.0, 0.5774, 0.5, 1.0 6 | .const c83, 1.0, 1.0, 1.0, 1.0 7 | 8 | ; setup outmap 9 | .out o0, result.position, 0xF 10 | .out o1, result.color, 0xF 11 | .out o2, result.texcoord0, 0x3 12 | .out o3, result.texcoord1, 0x3 13 | .out o4, result.view, 0xF 14 | 15 | ; setup uniform map (required to use SHDR_GetUniformRegister) 16 | .uniform c84, c87, projection ; c84-c87 = projection matrix 17 | .uniform c88, c91, modelview ; c88-c91 = modelview matrix 18 | .uniform c92, c92, textureDimensions 19 | 20 | ; setup vsh and gsh 21 | .vsh main, endmain 22 | 23 | ; code 24 | main: 25 | ; tempreg = mdlvMtx * in.pos 26 | dp4 r0, c88, v0 (0x0) 27 | dp4 r0, c89, v0 (0x1) 28 | dp4 r0, c90, v0 (0x2) 29 | mov r0, c82 (0x3) 30 | 31 | mov o4, r0 (0x5) 32 | 33 | ; result.pos = projMtx * tempreg 34 | dp4 o0, c84, r0 (0x0) 35 | dp4 o0, c85, r0 (0x1) 36 | dp4 o0, c86, r0 (0x2) 37 | dp4 o0, c87, r0 (0x3) 38 | 39 | ; result.texcoord = in.texcoord 40 | mul o2, c92, v0 (0x5) 41 | mul o3, c81, v0 (0x5) 42 | 43 | ; result.color = EXPERIMENTS ! 44 | mov o1, c83 (0x5) 45 | 46 | end 47 | nop 48 | endmain: 49 | 50 | ; operand descriptors 51 | .opdesc x___, xyzw, xyzw ; 0x0 52 | .opdesc _y__, xyzw, xyzw ; 0x1 53 | .opdesc __z_, xyzw, xyzw ; 0x2 54 | .opdesc ___w, xyzw, xyzw ; 0x3 55 | .opdesc xyzw, zzzy, xyzw ; 0x4 56 | .opdesc xyzw, xyzw, xyzw ; 0x5 57 | .opdesc xyz_, xyzw, xyzw ; 0x6 58 | .opdesc xyzw, yyyw, xyzw ; 0x7 59 | .opdesc x___, wwww, xyzw ; 0x8 60 | .opdesc xyzw, xyzw, xxxx, xyzw ; 0x9 61 | .opdesc xyzw, xyzw, -xyzw ; 0xa 62 | .opdesc xyzw, xxxx, wwww ; 0xb 63 | .opdesc xyzw, -xxxx, wwww ; 0xc 64 | .opdesc xy__, yzzz, xyzw ; 0xd 65 | -------------------------------------------------------------------------------- /include/physics/request.h: -------------------------------------------------------------------------------- 1 | #ifndef REQUEST_H 2 | #define REQUEST_H 3 | 4 | #include "utils/math.h" 5 | #include "physics/OBB.h" 6 | #include "physics/AAR.h" 7 | 8 | struct physicsThread_s; 9 | 10 | typedef enum 11 | { 12 | REQUEST_CREATE_OBB, 13 | REQUEST_RESET_OBB, 14 | REQUEST_CREATE_AAR, 15 | REQUEST_GENERATE_GRID, 16 | NUM_REQUEST_TYPES 17 | }requestTypes_t; 18 | 19 | //request 20 | typedef struct request_s 21 | { 22 | requestTypes_t type; 23 | void* data; 24 | struct request_s* next; 25 | }request_s; 26 | 27 | void initRequestPool(void); 28 | void allocatePoolRequests(void); 29 | request_s* createNewRequest(requestTypes_t t); 30 | request_s* getNewRequest(void); 31 | void freeRequest(request_s* r); 32 | 33 | void handleRequest(struct physicsThread_s* p, request_s* r); 34 | 35 | //request type 36 | typedef void (*requestHandler_func)(struct physicsThread_s* p, request_s* r); 37 | 38 | typedef struct 39 | { 40 | requestHandler_func handler; //executed by one of the producer threads 41 | u32 dataSize; 42 | }requestType_s; 43 | 44 | request_s* createRequestCreateObb(OBB_s** out, vect3Df_s position, vect3Df_s size, md2_instance_t* model, float mass, float angle); 45 | request_s* createRequestResetObb(OBB_s* target, vect3Df_s position, vect3Df_s size, md2_instance_t* model, float mass, float angle); 46 | request_s* createRequestCreateAar(AAR_s** out, vect3Df_s position, vect3Df_s size, vect3Df_s normal); 47 | request_s* createRequestGenerateGrid(); 48 | 49 | extern requestType_s requestTypes[NUM_REQUEST_TYPES]; 50 | 51 | //request queue (FIFO) 52 | typedef struct 53 | { 54 | request_s* first; 55 | request_s* last; 56 | int length; 57 | }requestQueue_s; 58 | 59 | void initRequestQueue(requestQueue_s* rq); 60 | void queueRequest(requestQueue_s* rq, request_s* r); 61 | request_s* unqueueRequest(requestQueue_s* rq); 62 | void appendRequestQueue(requestQueue_s* rq1, requestQueue_s* rq2); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /light/source/light_rectangle.h: -------------------------------------------------------------------------------- 1 | #ifndef __RECTANGLE9__ 2 | #define __RECTANGLE9__ 3 | 4 | #include "light_lightmap.h" 5 | 6 | typedef enum 7 | { 8 | EMPTY, 9 | RECTANGLE, 10 | HORIZONTAL, 11 | VERTICAL 12 | }treeNode_type; 13 | 14 | typedef struct treeNode_s 15 | { 16 | struct treeNode_s* son[2]; 17 | treeNode_type type; 18 | short data; 19 | }treeNode_s; 20 | 21 | typedef struct 22 | { 23 | treeNode_s* root; 24 | short width, height; 25 | }tree_s; 26 | 27 | typedef struct 28 | { 29 | vect3Di_s position, size; 30 | lightMapCoordinates_s* real; 31 | bool rot; 32 | }rectangle2D_s; 33 | 34 | typedef struct listCell2D_s 35 | { 36 | rectangle2D_s data; 37 | struct listCell2D_s* next; 38 | }listCell2D_s; 39 | 40 | typedef struct 41 | { 42 | listCell2D_s* first; 43 | int surface; 44 | int num; 45 | }rectangle2DList_s; 46 | 47 | static inline vect3Di_s vect2(s32 x, s32 y) 48 | { 49 | return (vect3Di_s){x,y,0}; 50 | } 51 | 52 | void initRectangle2DList(rectangle2DList_s* l); 53 | void insertRectangle2DList(rectangle2DList_s* l, rectangle2D_s rec); 54 | void packRectangles(rectangle2DList_s* l, short w, short h); 55 | bool packRectanglesSize(rectangle2DList_s* l, short* w, short* h); 56 | void freeRectangle2DList(rectangle2DList_s* l); 57 | 58 | void fillRectangle(u8* data, int w, int h, vect3Di_s* pos, vect3Di_s* size, u8 mask); 59 | void getMaxRectangle(u8* data, u8 val, int w, int h, vect3Di_s* pos, vect3Di_s* size); 60 | // bool collideLineRectangle(rectangle_s* rec, vect3D o, vect3D v, int32 d, int32* kk, vect3D* ip); 61 | // bool collideLineConvertedRectangle(vect3D n, vect3D p, vect3D s, vect3D o, vect3D v, int32 d, int32* kk, vect3D* ip); 62 | // vect3D getClosestPointRectangleStruct(rectangle_s* rec, vect3D o); 63 | // vect3D getClosestPointRectangle(vect3D p, vect3D s, vect3D o); 64 | 65 | // materialSlice_s* bindMaterial(material_s* m, rectangle_s* rec, int32* t, vect3D* v,bool DL); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /source/menu/cameratransition.c: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include "menu/cameratransition.h" 3 | 4 | cameraState_s cameraStates[]={{(vect3Df_s){3.48f, -0.9f, 10.84f}, (vect3Df_s){0.31f, -0.31f, 0.33f}}, 5 | {(vect3Df_s){0.2617f, 1.274f, 13.23f}, (vect3Df_s){-0.10f, -0.04f, -0.01f}}, 6 | {(vect3Df_s){-4.34f, -3.91f, 9.19f}, (vect3Df_s){0.34f, 0.41f, 0.26f}}, 7 | }; 8 | 9 | void applyCameraState(camera_s* c, cameraState_s* cs) 10 | { 11 | if(!c || !cs)return; 12 | 13 | c->position=cs->position; 14 | 15 | loadIdentity44((float*)c->orientation); 16 | rotateMatrixX((float*)c->orientation, cs->angle.x, false); 17 | rotateMatrixY((float*)c->orientation, cs->angle.y, false); 18 | rotateMatrixZ((float*)c->orientation, cs->angle.z, false); 19 | 20 | // printf("p : %f %f %f\n",cs->position.x,cs->position.y,cs->position.z); 21 | // printf("a : %f %f %f\n",cs->angle.x,cs->angle.y,cs->angle.z); 22 | } 23 | 24 | cameraTransition_s startCameraTransition(cameraState_s* s, cameraState_s* f, int length) 25 | { 26 | cameraTransition_s ct; 27 | 28 | ct.start=s; 29 | ct.finish=f; 30 | 31 | ct.progress=0; 32 | ct.length=length; 33 | 34 | return ct; 35 | } 36 | 37 | void updateCameraTransition(camera_s* c, cameraTransition_s* ct) 38 | { 39 | if(!c || !ct || !ct->start || !ct->finish || ct->progress>=ct->length)return; 40 | 41 | cameraState_s cs; 42 | 43 | //TEMP TEST 44 | cs.position=vect3Df(ct->start->position.x+((ct->finish->position.x-ct->start->position.x)*ct->progress)/ct->length, 45 | ct->start->position.y+((ct->finish->position.y-ct->start->position.y)*ct->progress)/ct->length, 46 | ct->start->position.z+((ct->finish->position.z-ct->start->position.z)*ct->progress)/ct->length); 47 | 48 | cs.angle=vect3Df(ct->start->angle.x+((ct->finish->angle.x-ct->start->angle.x)*ct->progress)/ct->length, 49 | ct->start->angle.y+((ct->finish->angle.y-ct->start->angle.y)*ct->progress)/ct->length, 50 | ct->start->angle.z+((ct->finish->angle.z-ct->start->angle.z)*ct->progress)/ct->length); 51 | 52 | applyCameraState(c, &cs); 53 | 54 | ct->progress++; 55 | } 56 | -------------------------------------------------------------------------------- /include/gfx/gs.h: -------------------------------------------------------------------------------- 1 | #ifndef GS_H 2 | #define GS_H 3 | 4 | #include <3ds.h> 5 | #include "utils/math.h" 6 | 7 | #define GS_MATRIXSTACK_SIZE (8) 8 | 9 | #define RGBA8(r,g,b,a) ((((r)&0xFF)<<24) | (((g)&0xFF)<<16) | (((b)&0xFF)<<8) | (((a)&0xFF)<<0)) 10 | 11 | typedef enum 12 | { 13 | GS_PROJECTION = 0, 14 | GS_MODELVIEW = 1, 15 | GS_MATRIXTYPES 16 | }GS_MATRIX; 17 | 18 | typedef struct 19 | { 20 | u8* data; 21 | u32 currentSize; // in bytes 22 | u32 maxSize; // in bytes 23 | u32 numVertices; 24 | u32* commands; 25 | u32 commandsSize; 26 | }gsVbo_s; 27 | 28 | typedef void (*gsRenderModeCallback)(void); 29 | 30 | typedef struct 31 | { 32 | gsRenderModeCallback init; 33 | gsRenderModeCallback exit; 34 | bool used; 35 | }gsRenderMode_s; 36 | 37 | typedef void (*gsCallback)(u32* outBuffer, u32* outDepthBuffer); 38 | 39 | void gsInit(shaderProgram_s* shader, gsCallback drawTop, gsCallback drawBottom); 40 | void gsDrawFrame(); 41 | void gsExit(void); 42 | 43 | int gsRegisterRenderMode(gsRenderModeCallback init, gsRenderModeCallback exit); 44 | void gsUnregisterRenderMode(int mode); 45 | void gsSwitchRenderMode(int mode); 46 | 47 | void gsSetShader(shaderProgram_s* shader); 48 | void gsSetBackgroundColor(u32 color); 49 | 50 | void gsStartFrame(void); 51 | void gsAdjustBufferMatrices(mtx44 transformation); 52 | 53 | void* gsLinearAlloc(size_t size); 54 | void gsLinearFree(void* mem); 55 | 56 | float* gsGetMatrix(GS_MATRIX m); 57 | int gsLoadMatrix(GS_MATRIX m, float* data); 58 | int gsPushMatrix(); 59 | int gsPopMatrix(); 60 | int gsMatrixMode(GS_MATRIX m); 61 | void gsInvalidateMatrixStack(); 62 | int gsUpdateTransformation(); 63 | 64 | void gsLoadIdentity(); 65 | void gsProjectionMatrix(float fovy, float aspect, float near, float far); 66 | void gsRotateX(float x); 67 | void gsRotateY(float y); 68 | void gsRotateZ(float z); 69 | void gsScale(float x, float y, float z); 70 | void gsTranslate(float x, float y, float z); 71 | int gsMultMatrix(float* data); 72 | int gsMultMatrix3(float* data); 73 | 74 | int gsVboInit(gsVbo_s* vbo); 75 | int gsVboCreate(gsVbo_s* vbo, u32 size); 76 | int gsVboFlushData(gsVbo_s* vbo); 77 | int gsVboDestroy(gsVbo_s* vbo); 78 | int gsVboDraw(gsVbo_s* vbo); 79 | void* gsVboGetOffset(gsVbo_s* vbo); 80 | int gsVboAddData(gsVbo_s* vbo, void* data, u32 size, u32 units); 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /light/source/light_room.h: -------------------------------------------------------------------------------- 1 | #ifndef ROOM_H 2 | #define ROOM_H 3 | 4 | #include 5 | #include "light_math.h" 6 | 7 | #define TILESIZE (2) 8 | #define TILESIZE_FLOAT ((float)TILESIZE) 9 | #define HEIGHTUNIT (1) 10 | #define HEIGHTUNIT_FLOAT ((float)HEIGHTUNIT) 11 | 12 | #define NUMLIGHTS (32) 13 | 14 | typedef struct 15 | { 16 | vect3Df_s position; 17 | float intensity; 18 | bool used; 19 | }light_s; 20 | 21 | extern light_s lights[NUMLIGHTS]; 22 | 23 | typedef struct 24 | { 25 | vect3Di_s position, size; 26 | vect3Df_s normal; 27 | bool portalable, hide, touched, collides; 28 | }rectangle_s; 29 | 30 | typedef struct listCell_s 31 | { 32 | rectangle_s data; 33 | struct listCell_s* next; 34 | }listCell_s; 35 | 36 | typedef struct 37 | { 38 | listCell_s* first; 39 | int num; 40 | }rectangleList_s; 41 | 42 | typedef struct 43 | { 44 | s16 x, y, z; 45 | s16 u, v; 46 | }rectangleVertex_s; 47 | 48 | typedef struct 49 | { 50 | // material_s** materials; 51 | vect3Df_s position; 52 | u16 width, height; 53 | rectangleList_s rectangles; 54 | int numVertices; 55 | rectangleVertex_s* vertexBuffer; 56 | int numIndexBuffers; 57 | int* numIndices; 58 | u16** indexBuffers; 59 | }room_s; 60 | 61 | void roomInit(); 62 | void roomExit(); 63 | 64 | void initRectangleList(rectangleList_s* p); 65 | rectangle_s* addRectangle(rectangle_s r, rectangleList_s* p); 66 | void popRectangle(rectangleList_s* p); 67 | 68 | void readVect3Df(vect3Df_s* v, FILE* f, bool fp); 69 | void readRectangle(rectangle_s* rec, FILE* f); 70 | void readRectangles(room_s* r, FILE* f); 71 | 72 | void initRoom(room_s* r, u16 w, u16 h, vect3Df_s p); 73 | void generateRectangleGeometry(rectangle_s* rec, vect3Di_s* texCoords, rectangleVertex_s* vbuf, int* numvert, u16* ibuf, int* numind); 74 | void generateRoomGeometry(room_s* r); 75 | rectangle_s* addRoomRectangle(room_s* r, rectangle_s rec); 76 | void removeRoomRectangles(room_s* r); 77 | void drawRoom(room_s* r); 78 | void transferRoomRectangles(room_s* r); 79 | 80 | vect3Df_s convertRectangleVector(vect3Di_s v); 81 | 82 | rectangle_s* collideLineMapClosest(room_s* r, rectangle_s* rec, vect3Df_s l, vect3Df_s u, float d, vect3Df_s* i, float* lk); 83 | bool collideLineRectangle(rectangle_s* rec, vect3Df_s o, vect3Df_s v, float d, float* kk, vect3Df_s* ip); 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /include/physics/PIC.h: -------------------------------------------------------------------------------- 1 | #ifndef PIC_H 2 | #define PIC_H 3 | 4 | #define PISIGNALDATA (6) 5 | #define PISIGNALMASK ((1<plane[1]=vectProduct(p->normal,p->plane[0]); 42 | 43 | // //TEST 44 | // generateGuidAAR(p); 45 | // } 46 | 47 | // static inline vect3D warpVector(portal_struct* p, vect3D v) 48 | // { 49 | // if(!p)return vect(0,0,0); 50 | // portal_struct* p2=p->targetPortal; 51 | // if(!p2)return vect(0,0,0); 52 | 53 | // // computePortalPlane(p2); 54 | 55 | // int32 x=dotProduct(v,p->plane[0]); 56 | // int32 y=dotProduct(v,p->plane[1]); 57 | // int32 z=dotProduct(v,p->normal); 58 | 59 | // return addVect(vectMult(p2->normal,-z),addVect(vectMult(p2->plane[0],-x),vectMult(p2->plane[1],y))); 60 | // } 61 | 62 | // static inline void warpMatrix(portal_struct* p, int32* m) //3x3 63 | // { 64 | // if(!m)return; 65 | 66 | // vect3D x=warpVector(p,vect(m[0],m[3],m[6])); 67 | // vect3D y=warpVector(p,vect(m[1],m[4],m[7])); 68 | // vect3D z=warpVector(p,vect(m[2],m[5],m[8])); 69 | 70 | // m[0]=x.x;m[3]=x.y;m[6]=x.z; 71 | // m[1]=y.x;m[4]=y.y;m[7]=y.z; 72 | // m[2]=z.x;m[5]=z.y;m[8]=z.z; 73 | // } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /source/gfx/text.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds.h> 3 | #include "gfx/text.h" 4 | #include "gfx/texture.h" 5 | #include "gfx/gs.h" 6 | 7 | #include "text_vsh_shbin.h" 8 | 9 | DVLB_s* textDvlb; 10 | shaderProgram_s textProgram; 11 | texture_s textTexture; 12 | extern u32 __linear_heap; 13 | #define textBaseAddr __linear_heap 14 | 15 | int textUniformOffset; 16 | 17 | void textInit() 18 | { 19 | textDvlb = DVLB_ParseFile((u32*)text_vsh_shbin, text_vsh_shbin_size); 20 | 21 | if(!textDvlb)return; 22 | 23 | shaderProgramInit(&textProgram); 24 | shaderProgramSetVsh(&textProgram, &textDvlb->DVLE[0]); 25 | shaderProgramSetGsh(&textProgram, &textDvlb->DVLE[1], 4); 26 | 27 | textureLoad(&textTexture, "font.png", GPU_TEXTURE_MAG_FILTER(GPU_NEAREST)|GPU_TEXTURE_MIN_FILTER(GPU_NEAREST), 0); 28 | 29 | textUniformOffset = shaderInstanceGetUniformLocation(textProgram.vertexShader, "offset"); 30 | 31 | printf("text %d\n", textUniformOffset); 32 | } 33 | 34 | void textExit() 35 | { 36 | textureFree(&textTexture); 37 | shaderProgramFree(&textProgram); 38 | DVLB_Free(textDvlb); 39 | } 40 | 41 | void textStartDrawing() 42 | { 43 | gsSetShader(&textProgram); 44 | 45 | textureBind(&textTexture, GPU_TEXUNIT0); 46 | 47 | GPU_SetAttributeBuffers( 48 | 1, // number of attributes 49 | (u32*)osConvertVirtToPhys(textBaseAddr), // we use the start of linear heap as base since that's where all our buffers are located 50 | GPU_ATTRIBFMT(0, 1, GPU_UNSIGNED_BYTE), // we want v0 (character) 51 | 0xFFE, // mask : we want v0 52 | 0x0, // permutation : we use identity 53 | 1, // number of buffers : we have one attribute per buffer 54 | (u32[]){(u32)0x0}, // buffer offsets (placeholder) 55 | (u64[]){0x0}, // attribute permutations for each buffer 56 | (u8[]){1} // number of attributes for each buffer 57 | ); 58 | } 59 | 60 | char* textMakeString(const char* s) 61 | { 62 | if(!s)return NULL; 63 | 64 | int l = strlen(s); 65 | char* ret = linearAlloc(l); 66 | if(!ret)return ret; 67 | memcpy(ret, s, l); 68 | return ret; 69 | } 70 | 71 | void textFreeString(char* s) 72 | { 73 | if(!s)return; 74 | 75 | linearFree(s); 76 | } 77 | 78 | void textDrawString(float x, float y, const char* s) 79 | { 80 | if(!s)return; 81 | if((u32)s < textBaseAddr)return; 82 | 83 | GPUCMD_AddWrite(GPUREG_ATTRIBBUFFER0_CONFIG0, (u32)s-textBaseAddr); 84 | 85 | GPU_SetFloatUniform(GPU_GEOMETRY_SHADER, textUniformOffset, (u32*)(float[]){1.0f, 0.0f, x, y}, 1); 86 | 87 | GPU_DrawArray(GPU_UNKPRIM, strlen(s)); 88 | } 89 | -------------------------------------------------------------------------------- /include/gfx/md2.h: -------------------------------------------------------------------------------- 1 | #ifndef MD2_H 2 | #define MD2_H 3 | 4 | #include <3ds.h> 5 | 6 | #include "utils/math.h" 7 | #include "gfx/texture.h" 8 | 9 | /* MD2 header */ 10 | typedef struct 11 | { 12 | int ident; 13 | int version; 14 | 15 | int skinwidth; 16 | int skinheight; 17 | 18 | int framesize; 19 | 20 | int num_skins; 21 | int num_vertices; 22 | int num_st; 23 | int num_tris; 24 | int num_glcmds; 25 | int num_frames; 26 | 27 | int offset_skins; 28 | int offset_st; 29 | int offset_tris; 30 | int offset_frames; 31 | int offset_glcmds; 32 | int offset_end; 33 | }md2_header_t; 34 | 35 | /* Texture name */ 36 | typedef struct 37 | { 38 | char name[64]; 39 | }md2_skin_t; 40 | 41 | /* Texture coords */ 42 | typedef struct 43 | { 44 | short s; 45 | short t; 46 | }md2_texCoord_t; 47 | 48 | /* Triangle info */ 49 | typedef struct 50 | { 51 | unsigned short vertex[3]; 52 | unsigned short st[3]; 53 | }md2_triangle_t; 54 | 55 | /* Compressed vertex */ 56 | typedef struct 57 | { 58 | unsigned char v[3]; 59 | unsigned char normalIndex; 60 | }md2_vertex_t; 61 | 62 | /* Model frame */ 63 | typedef struct 64 | { 65 | vect3Df_s scale; 66 | vect3Df_s translate; 67 | char name[16]; 68 | md2_vertex_t *verts; 69 | u16 next; 70 | }md2_frame_t; 71 | 72 | typedef struct 73 | { 74 | u16 v, st; 75 | }md2_vertperm_t; 76 | 77 | typedef struct 78 | { 79 | u16 start, end; 80 | }md2_anim_t; 81 | 82 | /* MD2 model structure */ 83 | typedef struct 84 | { 85 | md2_header_t header; 86 | 87 | md2_skin_t *skins; 88 | md2_texCoord_t *texcoords; 89 | md2_triangle_t *triangles; 90 | md2_frame_t *frames; 91 | 92 | u8 num_animations; 93 | md2_anim_t* animations; 94 | 95 | md2_vertperm_t* permutation; 96 | u32 permutation_size; 97 | 98 | u32 skin_width, skin_height; 99 | 100 | u16* indices; 101 | }md2_model_t; 102 | 103 | typedef struct 104 | { 105 | u16 currentFrame, nextFrame; 106 | u8 currentAnim, oldAnim; 107 | float interpolation, speed, alpha, brightness; 108 | bool oneshot; 109 | texture_s* texture; 110 | md2_model_t* model; 111 | }md2_instance_t; 112 | 113 | extern int md2GsMode; 114 | 115 | void md2Init(); 116 | void md2Exit(); 117 | void md2StartDrawing(); 118 | 119 | int md2ReadModel(md2_model_t *mdl, const char *filename); 120 | void md2FreeModel(md2_model_t *mdl); 121 | void md2RenderFrame(md2_model_t *mdl, int n1, int n2, float interp, float alpha, float brightness, texture_s* t); 122 | 123 | void md2InstanceInit(md2_instance_t* mi, md2_model_t* mdl, texture_s* t); 124 | void md2InstanceChangeAnimation(md2_instance_t* mi, u16 newAnim, bool oneshot); 125 | void md2InstanceUpdate(md2_instance_t* mi); 126 | void md2InstanceDraw(md2_instance_t* mi); 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /include/game/room.h: -------------------------------------------------------------------------------- 1 | #ifndef ROOM_H 2 | #define ROOM_H 3 | 4 | #include 5 | #include <3ds.h> 6 | #include "utils/math.h" 7 | #include "game/material.h" 8 | #include "game/light.h" 9 | #include "physics/AAR.h" 10 | 11 | #define TILESIZE (2) 12 | #define TILESIZE_FLOAT ((float)TILESIZE) 13 | #define HEIGHTUNIT (1) 14 | #define HEIGHTUNIT_FLOAT ((float)HEIGHTUNIT) 15 | 16 | #define CELLSIZE (4) 17 | 18 | typedef struct 19 | { 20 | vect3Di_s position, size; 21 | vect3Df_s normal; 22 | material_s* material; 23 | AAR_s* aar; 24 | union{ 25 | vertexLightingData_s* vertex; 26 | lightMapCoordinates_s* lightMap; 27 | }lightData; 28 | bool portalable, hide, touched, collides; 29 | }rectangle_s; 30 | 31 | typedef struct listCell_s 32 | { 33 | rectangle_s data; 34 | struct listCell_s* next; 35 | }listCell_s; 36 | 37 | typedef struct 38 | { 39 | listCell_s* first; 40 | int num; 41 | }rectangleList_s; 42 | 43 | typedef struct 44 | { 45 | rectangle_s** rectangles; 46 | int numRectangles; 47 | }gridCell_s; 48 | 49 | typedef struct 50 | { 51 | s16 x, y, z; 52 | s16 u, v; 53 | s16 u2, v2; 54 | }rectangleVertex_s; 55 | 56 | typedef struct 57 | { 58 | // material_s** materials; 59 | lightingData_s lightingData; 60 | vect3Df_s position; 61 | u16 width, height; 62 | gridCell_s* rectangleGrid; 63 | vect3Di_s rectangleGridSize; 64 | vect3Di_s rectangleGridOrigin; 65 | rectangleList_s rectangles; 66 | int numVertices; 67 | rectangleVertex_s* vertexBuffer; 68 | int numIndexBuffers; 69 | int* numIndices; 70 | texture_s** indexBufferTextures; 71 | u16** indexBuffers; 72 | }room_s; 73 | 74 | void roomInit(); 75 | void roomExit(); 76 | 77 | void initRectangleList(rectangleList_s* p); 78 | rectangle_s* addRectangle(rectangle_s r, rectangleList_s* p); 79 | void popRectangle(rectangleList_s* p); 80 | void getTextureCoordSlice(materialSlice_s* ms, rectangle_s* rec, vect3Di_s* v); 81 | void getMaterialTextureCoord(rectangle_s* rec, vect3Di_s* v); 82 | texture_s* getRectangleTexture(rectangle_s* rec); 83 | 84 | void readVect3Df(vect3Df_s* v, FILE* f, bool fp); 85 | void readRectangle(rectangle_s* rec, FILE* f); 86 | void readRectangles(room_s* r, FILE* f); 87 | 88 | void initRoom(room_s* r, u16 w, u16 h, vect3Df_s p); 89 | void freeRoom(room_s* r); 90 | void generateRoomGrid(room_s* r); 91 | void generateRectangleGeometry(rectangle_s* rec, vect3Di_s* texCoords, rectangleVertex_s* vbuf, int* numvert, u16* ibuf, int* numind); 92 | void generateRoomGeometry(room_s* r); 93 | rectangle_s* addRoomRectangle(room_s* r, rectangle_s rec); 94 | void removeRoomRectangles(room_s* r); 95 | void drawRoom(room_s* r); 96 | void transferRoomRectangles(room_s* r); 97 | 98 | vect3Df_s convertRectangleVector(vect3Di_s v); 99 | 100 | gridCell_s* getCurrentCell(room_s* r, vect3Df_s o); 101 | rectangle_s* collideGridCell(gridCell_s* gc, rectangle_s* rec, vect3Df_s l, vect3Df_s u, float d, vect3Df_s* i, vect3Df_s* n); 102 | rectangle_s* collideLineMapClosest(room_s* r, rectangle_s* rec, vect3Df_s l, vect3Df_s u, float d, vect3Df_s* i, float* lk); 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /include/physics/OBB.h: -------------------------------------------------------------------------------- 1 | #ifndef OBB_H 2 | #define OBB_H 3 | 4 | #include "utils/math.h" 5 | #include "gfx/md2.h" 6 | 7 | #define NUMOBJECTS (8) 8 | 9 | #define NUMOBBSEGMENTS (12) 10 | #define NUMOBBFACES (6) 11 | #define MAXCONTACTPOINTS (32) // pool system ? 12 | #define PENETRATIONTHRESHOLD (1<<6) 13 | #define MAXPENETRATIONBOX (1<<6) 14 | 15 | // #define SLEEPTHRESHOLD (50) 16 | #define SLEEPTHRESHOLD (0.001f) 17 | #define SLEEPTIMETHRESHOLD (48) 18 | 19 | static const u8 OBBSegments[NUMOBBSEGMENTS][2]={{0,1},{1,2},{3,2},{0,3}, 20 | {5,4},{5,6},{6,7},{4,7}, 21 | {3,4},{0,5},{1,6},{2,7}}; 22 | static const u8 OBBSegmentsPD[NUMOBBSEGMENTS][2]={{0,0},{1,2},{3,0},{0,2}, 23 | {5,2},{5,0},{6,2},{4,0}, 24 | {3,1},{0,1},{1,1},{2,1}}; 25 | 26 | static const u8 OBBFaces[NUMOBBFACES][4]={{0,1,2,3},{4,5,6,7},{0,5,4,3},{0,1,6,5},{1,2,7,6},{2,3,4,7}}; 27 | static const s8 OBBFacesPDDN[NUMOBBFACES][4]={{0,0,2,-2},{5,0,2,2},{0,1,2,-1},{0,0,1,-3},{1,1,2,1},{3,0,1,3}}; 28 | 29 | typedef enum 30 | { 31 | BOXCOLLISION, 32 | PLANECOLLISION, 33 | TESTPOINT, 34 | AARCOLLISION 35 | }contactPoint_type; 36 | 37 | typedef struct 38 | { 39 | vect3Df_s point; 40 | vect3Df_s normal; 41 | u16 penetration; 42 | void* target; 43 | contactPoint_type type; 44 | }contactPoint_struct; 45 | 46 | contactPoint_struct contactPoints[MAXCONTACTPOINTS]; 47 | 48 | typedef struct 49 | { 50 | float mass; 51 | float transformationMatrix[9]; //3x3 52 | float invInertiaMatrix[9]; //3x3 53 | float invWInertiaMatrix[9]; //3x3 54 | u16 maxPenetration; 55 | contactPoint_struct* contactPoints; //all point to the same array, temporary 56 | u8 numContactPoints; 57 | vect3Df_s size; 58 | vect3Df_s position; 59 | vect3Df_s velocity, angularVelocity, forces, moment; 60 | vect3Df_s angularMomentum; 61 | vect3Df_s AABBo, AABBs; 62 | md2_instance_t* modelInstance; 63 | u8 portal[2]; 64 | u8 oldPortal[2]; 65 | float oldPortalZ[2]; 66 | float energy; 67 | u16 counter; 68 | s16 groundID; 69 | bool portaled; 70 | bool sleep; 71 | bool used; 72 | }OBB_s; 73 | // 4 + 9*4*3 + 4 + 74 | 75 | extern OBB_s objects[NUMOBJECTS]; 76 | 77 | void initOBB(OBB_s* o, vect3Df_s pos, vect3Df_s size, md2_instance_t* model, float mass, float angle); 78 | void initObbTransformationMatrix(float* m, float angle); 79 | void getOBBVertices(OBB_s* o, vect3Df_s* v); 80 | void drawOBB(OBB_s* o); 81 | void applyOBBImpulses(OBB_s* o); 82 | void applyOBBForce(OBB_s* o, vect3Df_s p, vect3Df_s f); 83 | void updateOBB(OBB_s* o); 84 | 85 | void initOBBs(void); 86 | void updateOBBs(void); 87 | void drawOBBs(void); 88 | void wakeOBBs(void); 89 | OBB_s* createOBB(vect3Df_s position, vect3Df_s size, md2_instance_t* model, float mass, float angle); 90 | void updateOBBPortals(OBB_s* o, u8 id, bool init); 91 | void getVertices(vect3Df_s s, vect3Df_s p, vect3Df_s u1, vect3Df_s u2, vect3Df_s u3, vect3Df_s* v); 92 | void collideOBBs(OBB_s* o1, OBB_s* o2); 93 | void getBoxAABB(OBB_s* o, vect3Df_s* s); 94 | void setObbVelocity(OBB_s* o, vect3Df_s v); 95 | 96 | OBB_s* collideRayBoxes(vect3Df_s o, vect3Df_s u, float l); 97 | 98 | bool clipSegmentOBB(float* ss, vect3Df_s *uu, vect3Df_s* p1, vect3Df_s* p2, vect3Df_s vv, vect3Df_s* uu1, vect3Df_s* uu2, vect3Df_s vv1, vect3Df_s* n1, vect3Df_s* n2, bool* b1, bool* b2, float* k1, float* k2); 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /source/game/controls.c: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include "game/controls.h" 4 | #include "game/timedbutton.h" 5 | 6 | OBB_s* gravityGunObject; 7 | 8 | void initControls() 9 | { 10 | gravityGunObject = NULL; 11 | } 12 | 13 | void exitControls() 14 | { 15 | 16 | } 17 | 18 | touchPosition g_lastTouch = { 0, 0 }; 19 | touchPosition g_currentTouch = { 0, 0 }; 20 | 21 | void touchControl(player_s* p) { 22 | if (keysDown() & KEY_TOUCH) 23 | { 24 | touchRead(&g_lastTouch);// = touchReadXY(); 25 | g_lastTouch.px <<= 7; 26 | g_lastTouch.py <<= 7; 27 | } 28 | if (keysHeld() & KEY_TOUCH) 29 | { 30 | int dx, dy; 31 | touchRead(&g_currentTouch);// = touchReadXY(); 32 | // let's use some fixed point magic to improve touch smoothing accuracy 33 | g_currentTouch.px <<= 7; 34 | g_currentTouch.py <<= 7; 35 | 36 | dx = (g_currentTouch.px - g_lastTouch.px) >> 6; 37 | dy = (g_currentTouch.py - g_lastTouch.py) >> 6; 38 | 39 | 40 | dx *= 3; 41 | dy *= 3; 42 | 43 | rotatePlayer(p, vect3Df((abs(dy)<5) ? 0 : (dy*0.001f), (abs(dx)<5) ? 0 : (dx*0.001f), 0.0f)); 44 | 45 | // some simple averaging / smoothing through weightened (.5 + .5) accumulation 46 | g_lastTouch.px = (g_lastTouch.px + g_currentTouch.px) / 2; 47 | g_lastTouch.py = (g_lastTouch.py + g_currentTouch.py) / 2; 48 | } 49 | } 50 | 51 | void updateControls(player_s* p) 52 | { 53 | circlePosition cpad; 54 | circlePosition cstick; 55 | 56 | hidCircleRead(&cpad); 57 | irrstCstickRead(&cstick); 58 | 59 | touchControl(p); 60 | rotatePlayer(p, vect3Df((abs(cstick.dy)<5)?0:(-cstick.dy*0.001f), (abs(cstick.dx)<5)?0:(cstick.dx*0.001f), 0.0f)); 61 | 62 | if(abs(cpad.dx) > 15 || abs(cpad.dy) > 15) //dead zone 63 | { 64 | float factor = 0.0015f; 65 | 66 | if(p->flying)factor*=2; 67 | else if(!p->object.contact)factor*=0.06f; 68 | else updatePlayerWalk(p, cpad.dy*factor*2, cpad.dx*factor); 69 | 70 | movePlayer(p, vect3Df(cpad.dx*factor, 0.0f, -cpad.dy*factor)); 71 | } 72 | 73 | if(keysDown()&KEY_ZL) 74 | { 75 | // "USE" key 76 | vect3Df_s u = moveCameraVector(&p->camera, vect3Df(0.0f, 0.0f, -1.0f), true); 77 | timedButton_s* tb = collideRayTimedButtons(p->object.position, u, TILESIZE_FLOAT*2); 78 | if(tb) 79 | { 80 | activateTimedButton(tb); 81 | }else{ 82 | OBB_s* o = collideRayBoxes(p->object.position, u, TILESIZE_FLOAT*4); 83 | if(o) 84 | { 85 | gravityGunObject = o; 86 | } 87 | } 88 | } 89 | 90 | if(keysDown()&KEY_ZR) 91 | { 92 | // JUMP key 93 | if(p->object.contact) 94 | { 95 | p->object.speed.y += 0.6f; 96 | } 97 | } 98 | 99 | if(gravityGunObject) 100 | { 101 | if(!(keysHeld()&KEY_ZL)) 102 | { 103 | gravityGunObject = NULL; 104 | md2InstanceChangeAnimation(&p->gunInstance, 0, false); 105 | md2InstanceChangeAnimation(&p->gunInstance, 1, true); 106 | }else{ 107 | const vect3Df_s u = moveCameraVector(&p->camera, vect3Df(0.0f, 0.0f, -5.0f), true); 108 | const vect3Df_s t = vaddf(u, p->object.position); 109 | const vect3Df_s v = vmulf(vsubf(t, gravityGunObject->position), 1.75f); 110 | setObbVelocity(gravityGunObject, v); 111 | md2InstanceChangeAnimation(&p->gunInstance, 2, false); 112 | } 113 | }else if(p->gunInstance.currentAnim == 2){ 114 | md2InstanceChangeAnimation(&p->gunInstance, 0, false); 115 | md2InstanceChangeAnimation(&p->gunInstance, 1, true); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /data/text.vsh: -------------------------------------------------------------------------------- 1 | ; make sure you update aemstro_as for this (01/01/15) 2 | 3 | ; setup constants 4 | .const c20, 1.0, 0.0, 0.5, 1.0 5 | 6 | .const c21, 0.0, 0.0, -0.5, 1.0 7 | .const c22, -0.1, 0.0, -0.5, 1.0 8 | .const c23, -0.1, -0.05, -0.5, 1.0 9 | .const c24, 0.0, -0.05, -0.5, 1.0 10 | 11 | .const c25, 31.0, 32.0, 0.0, 10.0 12 | .const c26, 0.00, 0.00, 0.0, 1.0 13 | 14 | .const c30, 0.0078125, 0.0068359375, 1.0, 0.0 15 | .const c31, 1.0, 1.0, 1.0, 1.0 16 | 17 | ; setup outmap 18 | .out o0, result.position, 0xF 19 | .out o1, result.color, 0xF 20 | .out o2, result.texcoord0, 0x3 21 | .out o3, result.texcoord1, 0x3 22 | 23 | ; setup uniform map (required to use SHDR_GetUniformRegister) 24 | .uniform c0, c3, projection ; c0-c3 = projection matrix 25 | .uniform c4, c7, modelview ; c4-c7 = modelview matrix 26 | .uniform c8, c8, lightDirection ; c8 = light direction vector 27 | .uniform c9, c9, lightAmbient ; c9 = light ambient color 28 | 29 | .uniform c80, c80, offset ; c80 = text position offset 30 | 31 | ; setup vsh and gsh 32 | .vsh main, endmain 33 | .gsh main_gsh, endmain_gsh 34 | 35 | ; code 36 | main: 37 | ;mov r0, c20 (0x5) 38 | mov r0, v0 (0x5) 39 | 40 | cmp c25, GT, GT, v0 (0x5) 41 | 42 | ifc end_if, else, cmp.x 43 | mov o0, v0 (0x5) 44 | mov o1, c25 (0x5) 45 | mov o2, c25 (0x5) 46 | mov o3, c25 (0x5) 47 | nop 48 | else: 49 | add r0, c25, r0 (0xb) 50 | 51 | mul r0, c30, r0 (0x1) 52 | mov r0, c30 (0x0) 53 | 54 | mov o0, c21 (0x8) 55 | mov o0, r0 (0xa) 56 | 57 | mov o1, c22 (0x8) 58 | add o1, c30, r0 (0x4) 59 | 60 | mov o2, c23 (0x8) 61 | add o2, c30, r0 (0x6) 62 | 63 | mov o3, c24 (0x8) 64 | add o3, c30, r0 (0x7) 65 | 66 | nop 67 | end_if: 68 | nop 69 | 70 | end 71 | nop 72 | endmain: 73 | 74 | main_gsh: 75 | 76 | cmp c25, EQ, EQ, v2 (0xc) 77 | 78 | ifc end_if_2, else_2, cmp.x 79 | ; special character ! 80 | cmp c25, EQ, EQ, v0 (0xd) 81 | ifc end_if_3, else_3, cmp.x 82 | ; 10 is newline '\n' 83 | mov r15, c80 (0xe) 84 | add r15, c22, r15 (0x8) 85 | nop 86 | else_3: 87 | ; we process everything else as carriage return 88 | mov r15, c80 (0x5) 89 | end_if_3: 90 | nop 91 | else_2: 92 | ; output a character 93 | 94 | setemit vtx0, false, false 95 | add o0, v0, r15 (0x8) 96 | mov o0, c21 (0x7) 97 | mov o1, c31 (0x5) 98 | mov o2, v0 (0x9) 99 | mov o3, c20 (0x8) 100 | emit 101 | 102 | setemit vtx1, false, false 103 | add o0, v1, r15 (0x8) 104 | mov o0, c21 (0x7) 105 | mov o1, c31 (0x5) 106 | mov o2, v1 (0x9) 107 | mov o3, c20 (0x8) 108 | emit 109 | 110 | setemit vtx2, true, true 111 | add o0, v2, r15 (0x8) 112 | mov o0, c21 (0x7) 113 | mov o1, c31 (0x5) 114 | mov o2, v2 (0x9) 115 | mov o3, c20 (0x8) 116 | emit 117 | 118 | setemit vtx1, true, false 119 | add o0, v3, r15 (0x8) 120 | mov o0, c21 (0x7) 121 | mov o1, c31 (0x5) 122 | mov o2, v3 (0x9) 123 | mov o3, c20 (0x8) 124 | emit 125 | 126 | add r15, v3, r15 (0x8) 127 | end_if_2: 128 | 129 | end 130 | nop 131 | endmain_gsh: 132 | 133 | ; operand descriptors 134 | .opdesc x___, wwww, wwww ; 0x0 135 | .opdesc _y__, xxxx, xxxx ; 0x1 136 | .opdesc __z_, xyzw, xyzw ; 0x2 137 | .opdesc ___w, xyzw, xyzw ; 0x3 138 | .opdesc __zw, wywy, xyxy ; 0x4 139 | .opdesc xyzw, xyzw, xyzw ; 0x5 140 | .opdesc __zw, zyzy, xyxy ; 0x6 141 | .opdesc __zw, zwzw, xyxy ; 0x7 142 | .opdesc xy__, xyzw, xyzw ; 0x8 143 | .opdesc xy__, zwzw, zwzw ; 0x9 144 | .opdesc __zw, xyxy, xyxy ; 0xa 145 | .opdesc x___, -yywz, xyzw ; 0xb 146 | .opdesc xyzw, zzzz, zwzw ; 0xc 147 | .opdesc xyzw, wwww, xyzw ; 0xd 148 | .opdesc _y__, xyzw, xyzw ; 0xe 149 | .opdesc _y__, -xyzw, xyzw ; 0xf 150 | -------------------------------------------------------------------------------- /source/game/elevator.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds.h> 4 | #include "game/elevator.h" 5 | #include "gfx/gs.h" 6 | 7 | #define ELEVATOR_SPEED (0.05f) 8 | 9 | md2_model_t elevatorModel; 10 | md2_model_t elevatorFrameModel; 11 | texture_s elevatorTexture; 12 | texture_s elevatorFrameTexture; 13 | 14 | void initElevators(void) 15 | { 16 | md2ReadModel(&elevatorModel, "elevator.md2"); 17 | textureLoad(&elevatorTexture, "balllauncher.png", GPU_TEXTURE_MAG_FILTER(GPU_LINEAR)|GPU_TEXTURE_MIN_FILTER(GPU_LINEAR), 0); 18 | 19 | md2ReadModel(&elevatorFrameModel, "elevatorframe.md2"); 20 | textureLoad(&elevatorFrameTexture, "cubedispenser.png", GPU_TEXTURE_MAG_FILTER(GPU_LINEAR)|GPU_TEXTURE_MIN_FILTER(GPU_LINEAR), 0); 21 | } 22 | 23 | void exitElevators(void) 24 | { 25 | md2FreeModel(&elevatorModel); 26 | md2FreeModel(&elevatorFrameModel); 27 | 28 | textureFree(&elevatorTexture); 29 | textureFree(&elevatorFrameTexture); 30 | } 31 | 32 | void initElevator(elevator_s* ev, room_s* r, vect3Di_s position, u8 direction, bool up) 33 | { 34 | if(!ev)return; 35 | 36 | ev->position=convertRectangleVector(vect3Di(position.x, position.y-4, position.z));; 37 | ev->direction=direction|(up<progress=0; 39 | ev->state=ELEVATOR_OPEN; 40 | ev->doorSurface=NULL; 41 | md2InstanceInit(&ev->modelInstance, &elevatorModel, &elevatorTexture); 42 | ev->modelInstance.speed=0.1f; 43 | 44 | printf("EV %d\n",up); 45 | printf("EV %d\n",ev->direction); 46 | } 47 | 48 | void setElevatorArriving(elevator_s* ev, float distance) 49 | { 50 | if(!ev)return; 51 | 52 | ev->state=ELEVATOR_ARRIVING; 53 | ev->progress=distance; 54 | 55 | updateElevator(ev); 56 | } 57 | 58 | void closeElevator(elevator_s* ev) 59 | { 60 | if(!ev || ev->state!=ELEVATOR_OPEN)return; 61 | 62 | md2InstanceChangeAnimation(&ev->modelInstance, 0, false); 63 | md2InstanceChangeAnimation(&ev->modelInstance, 3, true); 64 | ev->state=ELEVATOR_CLOSING; 65 | } 66 | 67 | void updateElevator(elevator_s* ev) 68 | { 69 | if(!ev)return; 70 | 71 | switch(ev->state) 72 | { 73 | case ELEVATOR_ARRIVING: 74 | md2InstanceChangeAnimation(&ev->modelInstance, 0, false); 75 | if(ev->progress<=0) 76 | { 77 | ev->progress=0; 78 | md2InstanceChangeAnimation(&ev->modelInstance, 2, false); 79 | md2InstanceChangeAnimation(&ev->modelInstance, 1, true); 80 | ev->state=ELEVATOR_OPENING; 81 | }else ev->progress-=ELEVATOR_SPEED; 82 | break; 83 | case ELEVATOR_OPENING: 84 | ev->progress=0; 85 | if(ev->modelInstance.currentAnim==2)ev->state=ELEVATOR_OPEN; 86 | break; 87 | case ELEVATOR_OPEN: 88 | ev->progress=0; 89 | break; 90 | case ELEVATOR_CLOSING: 91 | ev->progress=0; 92 | if(ev->modelInstance.currentAnim==0)ev->state=ELEVATOR_LEAVING; 93 | break; 94 | case ELEVATOR_LEAVING: 95 | md2InstanceChangeAnimation(&ev->modelInstance, 0, false); 96 | ev->progress+=ELEVATOR_SPEED; 97 | break; 98 | } 99 | 100 | bool up=(ev->direction&(1<realPosition=ev->position; 102 | ev->realPosition.y+=up?(ev->progress):(-ev->progress); 103 | 104 | if(ev->doorSurface)ev->doorSurface->collides=ev->state!=ELEVATOR_OPEN; 105 | 106 | md2InstanceUpdate(&ev->modelInstance); 107 | } 108 | 109 | void drawElevator(elevator_s* ev) 110 | { 111 | if(!ev)return; 112 | 113 | gsPushMatrix(); 114 | gsSwitchRenderMode(md2GsMode); 115 | 116 | gsTranslate(ev->position.x, ev->position.y, ev->position.z); 117 | 118 | switch(ev->direction&(~(1<modelInstance); 135 | gsPopMatrix(); 136 | } 137 | -------------------------------------------------------------------------------- /source/game/door.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds.h> 4 | #include "game/door.h" 5 | #include "gfx/gs.h" 6 | 7 | door_s door[NUMDOORS]; 8 | md2_model_t doorModel; 9 | texture_s doorTexture; 10 | SFX_s* doorOpenSFX; 11 | SFX_s* doorCloseSFX; 12 | 13 | void initDoors(void) 14 | { 15 | int i; 16 | for(i=0;irectangle[0]=addRoomRectangle(r, rec); 56 | if(d->rectangle[0]){d->rectangle[0]->hide=true;d->rectangle[0]->portalable=false;d->rectangle[0]->collides=true;} 57 | 58 | rec.position.y+=rec.size.y; 59 | rec.size.y=-rec.size.y; 60 | d->rectangle[1]=addRoomRectangle(r, rec); 61 | if(d->rectangle[1]){d->rectangle[1]->hide=true;d->rectangle[1]->portalable=false;d->rectangle[1]->collides=true;} 62 | 63 | md2InstanceInit(&d->modelInstance, &doorModel, &doorTexture); 64 | d->position=convertRectangleVector(vect3Di(position.x, position.y, position.z)); 65 | d->orientation=orientation; 66 | initActivatableObject(&d->ao); 67 | d->used=true; 68 | } 69 | 70 | door_s* createDoor(room_s* r, vect3Di_s position, bool orientation) 71 | { 72 | if(!r)return NULL; 73 | int i; 74 | for(i=0;iused)return; 88 | 89 | if(d->ao.active) 90 | { 91 | if(d->modelInstance.currentAnim==0) 92 | { 93 | md2InstanceChangeAnimation(&d->modelInstance, 2, false); 94 | md2InstanceChangeAnimation(&d->modelInstance, 1, true); 95 | playSFX(doorOpenSFX); 96 | }else if(d->modelInstance.oldAnim==1 && d->modelInstance.currentAnim==2) 97 | { 98 | if(d->rectangle[0]){d->rectangle[0]->collides=false;/*toggleAAR(d->rectangle[0]->AARid);*/} 99 | if(d->rectangle[1]){d->rectangle[1]->collides=false;/*toggleAAR(d->rectangle[1]->AARid);*/} 100 | } 101 | }else 102 | { 103 | if(d->modelInstance.currentAnim==2) 104 | { 105 | md2InstanceChangeAnimation(&d->modelInstance, 0, false); 106 | md2InstanceChangeAnimation(&d->modelInstance, 3, true); 107 | playSFX(doorCloseSFX); 108 | if(d->rectangle[0]){d->rectangle[0]->collides=true;/*toggleAAR(d->rectangle[0]->AARid);*/} 109 | if(d->rectangle[1]){d->rectangle[1]->collides=true;/*toggleAAR(d->rectangle[1]->AARid);*/} 110 | } 111 | } 112 | 113 | md2InstanceUpdate(&d->modelInstance); 114 | d->ao.active=false; 115 | } 116 | 117 | void updateDoors(void) 118 | { 119 | int i; 120 | for(i=0;iused)return; 129 | 130 | gsPushMatrix(); 131 | gsSwitchRenderMode(md2GsMode); 132 | 133 | gsTranslate(d->position.x, d->position.y, d->position.z); 134 | 135 | if(d->orientation)gsRotateY(M_PI/2); 136 | 137 | md2InstanceDraw(&d->modelInstance); 138 | gsPopMatrix(); 139 | } 140 | 141 | void drawDoors(void) 142 | { 143 | int i; 144 | for(i=0;i 2 | #include <3ds.h> 3 | 4 | #include "game/camera.h" 5 | #include "gfx/gs.h" 6 | 7 | vect3Df_s normGravityVector; //TEMP 8 | 9 | void initCamera(camera_s* c) 10 | { 11 | if(!c)return; 12 | 13 | initProjectionMatrix((float*)c->projection, 1.3962634f, 240.0f/400.0f, 0.01f, 1000.0f); 14 | loadIdentity44((float*)c->orientation); 15 | c->position=vect3Df(0.0f, 0.0f, 0.0f); 16 | 17 | normGravityVector=vect3Df(0.0f, -1.0f, 0.0f); //TEMP 18 | } 19 | 20 | void updateCameraFrustum(camera_s* c) 21 | { 22 | if(!c)return; 23 | 24 | float final[4*4]; 25 | multMatrix44((float*)c->projection, (float*)c->modelview, final); 26 | 27 | const vect4Df_s rowX = getMatrixColumn4(final, 0); 28 | const vect4Df_s rowY = getMatrixColumn4(final, 1); 29 | const vect4Df_s rowZ = getMatrixColumn4(final, 2); 30 | const vect4Df_s rowW = getMatrixColumn4(final, 3); 31 | 32 | //ordered by priority for culling 33 | c->frustumPlane[0] = vnormf4(vsubf4(rowW, rowZ)); //near plane 34 | c->frustumPlane[1] = vnormf4(vaddf4(rowW, rowX)); //right plane 35 | c->frustumPlane[2] = vnormf4(vsubf4(rowW, rowX)); //left plane 36 | c->frustumPlane[3] = vnormf4(vaddf4(rowW, rowY)); //top plane 37 | c->frustumPlane[4] = vnormf4(vsubf4(rowW, rowY)); //bottom plane 38 | c->frustumPlane[5] = vnormf4(vaddf4(rowW, rowZ)); //far plane 39 | } 40 | 41 | void rotateCamera(camera_s* c, vect3Df_s a) 42 | { 43 | if(!c)return; 44 | 45 | rotateMatrixX((float*)c->orientation, -a.x, true); 46 | rotateMatrixAxis((float*)c->orientation, -a.y, normGravityVector, false); 47 | } 48 | 49 | void setCameraPosition(camera_s* c, vect3Df_s v) 50 | { 51 | if(!c)NULL; 52 | 53 | c->position=v; 54 | } 55 | 56 | vect3Df_s moveCameraVector(camera_s* c, vect3Df_s v, bool free) 57 | { 58 | if(!c)NULL; 59 | 60 | vect3Df_s v1=vect3Df(c->orientation[2][0],c->orientation[2][1],c->orientation[2][2]); 61 | 62 | if(!free)v1=vnormf(vsubf(v1,vmulf(normGravityVector,vdotf(normGravityVector,v1)))); 63 | 64 | return vect3Df((v.z*v1.x)+(v.x*c->orientation[0][0]), (v.z*v1.y)+(v.x*c->orientation[0][1]), (v.z*v1.z)+(v.x*c->orientation[0][2])); 65 | } 66 | 67 | void moveCamera(camera_s* c, vect3Df_s v) 68 | { 69 | if(!c)NULL; 70 | 71 | c->position=vaddf(c->position, moveCameraVector(c, v, true)); 72 | } 73 | 74 | void updateCamera(camera_s* c) 75 | { 76 | if(!c)return; 77 | 78 | memcpy(c->modelview, c->orientation, sizeof(mtx44)); 79 | translateMatrix((float*)c->modelview, -c->position.x, -c->position.y, -c->position.z); 80 | 81 | updateCameraFrustum(c); 82 | } 83 | 84 | void useCamera(camera_s* c) 85 | { 86 | if(!c)return; 87 | 88 | gsMatrixMode(GS_PROJECTION); 89 | gsLoadIdentity(); 90 | gsMultMatrix((float*)c->projection); 91 | 92 | gsMatrixMode(GS_MODELVIEW); 93 | gsMultMatrix((float*)c->modelview); 94 | } 95 | 96 | bool pointInCameraFrustum(camera_s* c, vect3Df_s pt) 97 | { 98 | if(!c)return false; 99 | const vect4Df_s pt4=vect4Df(pt.x,pt.y,pt.z,1.0f); 100 | int i; for(i=0;i<6;i++)if(vdotf4(pt4,c->frustumPlane[i])<0.0f)return false; 101 | return true; 102 | } 103 | 104 | vect3Df_s box[]={(vect3Df_s){0.f,0.f,0.f}, 105 | (vect3Df_s){1.f,0.f,0.f}, 106 | (vect3Df_s){0.f,1.f,0.f}, 107 | (vect3Df_s){0.f,0.f,1.f}, 108 | (vect3Df_s){1.f,1.f,0.f}, 109 | (vect3Df_s){1.f,0.f,1.f}, 110 | (vect3Df_s){0.f,1.f,1.f}, 111 | (vect3Df_s){1.f,1.f,1.f}}; 112 | 113 | //et "Assarsson and Moller report that they found no observable penalty in the rendering when skipping further tests" 114 | bool aabbInCameraFrustum(camera_s* c, vect3Df_s o, vect3Df_s s, int planes) 115 | { 116 | if(!c)return false; 117 | if(planes<=0 || planes>6)return false; 118 | int i, j; 119 | for(i=0;ifrustumPlane[i])<0.0f)out++; 126 | else in++; 127 | } 128 | if(!in)return false; 129 | } 130 | return true; 131 | } 132 | 133 | vect4Df_s projectPointCamera(camera_s* c, vect3Df_s p) 134 | { 135 | if(!c)return vect4Df(0.0f, 0.0f, 0.0f, 0.0f); 136 | 137 | vect4Df_s v = vect4Df(p.x, p.y, p.z, 1.0f); 138 | v = multMatrix44Vect4((float*)c->modelview, v, false); 139 | float depth = v.z / v.w; 140 | v = multMatrix44Vect4((float*)c->projection, v, false); 141 | 142 | return vect4Df(v.x/v.w, v.y/v.w, v.z/v.w, depth); 143 | } 144 | -------------------------------------------------------------------------------- /source/game/bigbutton.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds.h> 4 | #include "game/bigbutton.h" 5 | #include "gfx/gs.h" 6 | 7 | bigButton_s bigButton[NUMBIGBUTTONS]; 8 | 9 | md2_model_t bigButtonModel; 10 | texture_s bigButtonTexture, bigButtonActiveTexture; 11 | 12 | void initBigButtons(void) 13 | { 14 | int i; 15 | for(i=0;iroom=r; 41 | 42 | md2InstanceInit(&bb->modelInstance, &bigButtonModel, &bigButtonTexture); 43 | 44 | {//for collisions 45 | rectangle_s rec; 46 | rectangle_s* recp; 47 | rec.material=NULL; 48 | 49 | rec.position=vaddi(pos,vect3Di(-1,1,-1)); 50 | rec.size=vect3Di(2,0,2); 51 | rec.normal=vect3Df(0,-1.0f,0); 52 | recp=addRoomRectangle(r, rec); 53 | if(recp){recp->hide=true;recp->collides=true;bb->surface=recp;} 54 | 55 | rec.position=vaddi(pos,vect3Di(-1,0,-1)); 56 | rec.size=vect3Di(2,1,0); 57 | rec.normal=vect3Df(0,0,-1.0f); 58 | recp=addRoomRectangle(r, rec); 59 | if(recp){recp->hide=true;recp->collides=true;} 60 | 61 | rec.position=vaddi(pos,vect3Di(-1,1,1)); 62 | rec.size=vect3Di(2,-1,0); 63 | rec.normal=vect3Df(0,0,1.0f); 64 | recp=addRoomRectangle(r, rec); 65 | if(recp){recp->hide=true;recp->collides=true;} 66 | 67 | rec.position=vaddi(pos,vect3Di(-1,0,-1)); 68 | rec.size=vect3Di(0,1,2); 69 | rec.normal=vect3Df(-1.0f,0,0); 70 | recp=addRoomRectangle(r, rec); 71 | if(recp){recp->hide=true;recp->collides=true;} 72 | 73 | rec.position=vaddi(pos,vect3Di(1,1,-1)); 74 | rec.size=vect3Di(0,-1,2) 75 | ;rec.normal=vect3Df(1.0f,0,0); 76 | recp=addRoomRectangle(r, rec); 77 | if(recp){recp->hide=true;recp->collides=true;} 78 | 79 | } 80 | 81 | // pos=vect(pos.x+r->position.x, pos.y, pos.z+r->position.y); 82 | bb->position=convertRectangleVector(pos); 83 | 84 | initActivator(&bb->activator); 85 | bb->active=false; 86 | 87 | bb->used=true; 88 | } 89 | 90 | bigButton_s* createBigButton(room_s* r, vect3Di_s position) 91 | { 92 | if(!r)return NULL; 93 | int i; 94 | for(i=0;iused)return; 108 | 109 | gsPushMatrix(); 110 | gsSwitchRenderMode(md2GsMode); 111 | 112 | gsTranslate(bb->position.x, bb->position.y, bb->position.z); 113 | 114 | bb->modelInstance.texture = bb->active?&bigButtonActiveTexture:&bigButtonTexture; 115 | md2InstanceDraw(&bb->modelInstance); 116 | gsPopMatrix(); 117 | } 118 | 119 | void drawBigButtons(void) 120 | { 121 | int i; 122 | for(i=0;isurface)return false; 134 | 135 | vect3Df_s s; 136 | getBoxAABB(o, &s); 137 | 138 | return intersectAABBAAR(o->position, s, vaddf(bb->position, vect3Df(-TILESIZE_FLOAT, 1.0f, -TILESIZE_FLOAT)), vect3Df(TILESIZE_FLOAT*2,0,TILESIZE_FLOAT*2)); 139 | } 140 | 141 | void updateBigButton(bigButton_s* bb) 142 | { 143 | if(!bb || !bb->used)return; 144 | 145 | bb->active=false; 146 | if(bb->surface && bb->surface->touched)bb->active=true; 147 | 148 | int i; 149 | for(i=0; iused) 153 | { 154 | if(intersectOBBButton(bb, o)) 155 | { 156 | bb->active = true; 157 | break; 158 | } 159 | } 160 | } 161 | 162 | if(bb->active) 163 | { 164 | md2InstanceChangeAnimation(&bb->modelInstance,1,false); 165 | useActivator(&bb->activator); 166 | }else{ 167 | md2InstanceChangeAnimation(&bb->modelInstance,0,false); 168 | unuseActivator(&bb->activator); 169 | } 170 | 171 | md2InstanceUpdate(&bb->modelInstance); 172 | } 173 | 174 | void updateBigButtons(void) 175 | { 176 | int i; 177 | for(i=0;i 2 | #include 3 | #include <3ds.h> 4 | #include "game/platform.h" 5 | #include "gfx/gs.h" 6 | 7 | #define LOGOSIZE (192) 8 | #define LOGOHEIGHT (64) 9 | #define PLATFORMHEIGHT (0.3f) 10 | 11 | platform_s platform[NUMPLATFORMS]; 12 | md2_model_t platformModel; 13 | texture_s platformTexture; 14 | md2_instance_t platformModelInstance; 15 | 16 | void initPlatforms(void) 17 | { 18 | int i; 19 | for(i=0;iposition.x, orig.y, orig.z+r->position.y); 42 | // dest=vect3Df(dest.x+r->position.x, dest.y, dest.z+r->position.y); 43 | 44 | pf->id=id; 45 | pf->origin=convertRectangleVector(orig); 46 | pf->destination=convertRectangleVector(dest); 47 | 48 | pf->position=pf->origin; 49 | pf->velocity=vdivf(vnormf(vsubf(pf->destination,pf->origin)),16); 50 | 51 | pf->direction=true; 52 | pf->touched=false; 53 | pf->backandforth=true; 54 | 55 | initActivatableObject(&pf->ao); 56 | pf->ao.active=true; 57 | 58 | pf->aar=createAAR(vaddf(pf->position, vect3Df(-PLATFORMSIZE, PLATFORMHEIGHT, -PLATFORMSIZE)), vect3Df(2*PLATFORMSIZE, 0.0f, 2*PLATFORMSIZE), vect3Df(0.0f, 1.0f, 0.0f)); 59 | 60 | // addPlatform(id,vmulf(pf->origin,4),vmulf(pf->destination,4),BAF); //TEMP 61 | 62 | pf->used=true; 63 | } 64 | 65 | platform_s* createPlatform(room_s* r, vect3Di_s orig, vect3Di_s dest, bool BAF) 66 | { 67 | if(!r)return NULL; 68 | int i; 69 | for(i=0;iposition.x, pf->position.y, pf->position.z); 87 | md2InstanceDraw(&platformModelInstance); 88 | gsPopMatrix(); 89 | } 90 | 91 | void drawPlatforms(void) 92 | { 93 | int i; 94 | for(i=0;iposition, s, vaddf(pf->position, vect3Df(-PLATFORMSIZE, 1.0f, -PLATFORMSIZE)), vect3Df(PLATFORMSIZE*2,0,PLATFORMSIZE*2)); 108 | } 109 | 110 | void updatePlatform(platform_s* pf, player_s* p) 111 | { 112 | if(!pf)return; 113 | 114 | if(pf->ao.active) 115 | { 116 | if(pf->touched && p->object.position.y>pf->position.y+p->object.radius) 117 | { 118 | p->object.position=vaddf(p->object.position,pf->velocity); 119 | }else if(pf->oldTouched){ 120 | p->object.speed=vaddf(p->object.speed,pf->velocity); 121 | } 122 | 123 | if(pf->direction) 124 | { 125 | if(vdotf(vsubf(pf->position,pf->destination),pf->velocity)>0) 126 | { 127 | if(pf->backandforth) 128 | { 129 | pf->velocity=vmulf(pf->velocity,-1); 130 | pf->direction=false; 131 | }else{ 132 | pf->velocity=vect3Df(0,0,0); 133 | pf->ao.active=false; 134 | } 135 | } 136 | }else{ 137 | if(vdotf(vsubf(pf->position,pf->origin),pf->velocity)>0) 138 | { 139 | pf->velocity=vmulf(pf->velocity,-1); 140 | pf->direction=true; 141 | } 142 | } 143 | 144 | int i; 145 | for(i=0; ivelocity); 150 | } 151 | } 152 | 153 | pf->position=vaddf(pf->position,pf->velocity); 154 | } 155 | 156 | if(pf->aar) 157 | { 158 | pf->aar->position = vaddf(pf->position, vect3Df(-PLATFORMSIZE, PLATFORMHEIGHT, -PLATFORMSIZE)); 159 | } 160 | 161 | pf->ao.oldActive=pf->ao.active; 162 | pf->oldTouched=pf->touched; 163 | pf->touched=false; 164 | } 165 | 166 | void updatePlatforms(player_s* p) 167 | { 168 | int i; 169 | for(i=0;i 2 | #include 3 | #include <3ds.h> 4 | #include "game/timedbutton.h" 5 | #include "gfx/gs.h" 6 | 7 | #define BUTTONTIMER (7*30) 8 | #define TIMEDBUTTON_RADIUS_OUT (TILESIZE/2) 9 | #define TIMEDBUTTON_HEIGHT (TILESIZE*2) 10 | 11 | timedButton_s timedButton[NUMTIMEDBUTTONS]; 12 | 13 | md2_model_t timedButtonModel; 14 | texture_s timedButtonTexture; 15 | texture_s timedButtonActiveTexture; 16 | 17 | void initTimedButtons(void) 18 | { 19 | int i; 20 | for(i=0;iroom=r; 46 | 47 | md2InstanceInit(&tb->modelInstance, &timedButtonModel, &timedButtonTexture); 48 | 49 | tb->position=convertRectangleVector(pos); 50 | 51 | initActivator(&tb->activator); 52 | tb->active=false; 53 | tb->angle=angle; 54 | 55 | tb->used=true; 56 | } 57 | 58 | timedButton_s* createTimedButton(room_s* r, vect3Di_s position, float angle) 59 | { 60 | if(!r)return NULL; 61 | int i; 62 | for(i=0;iused)return; 76 | 77 | gsPushMatrix(); 78 | gsSwitchRenderMode(md2GsMode); 79 | 80 | gsTranslate(tb->position.x, tb->position.y, tb->position.z); 81 | 82 | gsRotateY(tb->angle); 83 | 84 | tb->modelInstance.texture = tb->active?&timedButtonActiveTexture:&timedButtonTexture; 85 | 86 | md2InstanceDraw(&tb->modelInstance); 87 | gsPopMatrix(); 88 | } 89 | 90 | void drawTimedButtons(void) 91 | { 92 | int i; 93 | for(i=0;iused)return; 105 | 106 | if(tb->active) 107 | { 108 | md2InstanceChangeAnimation(&tb->modelInstance,1,false); 109 | useActivator(&tb->activator); 110 | tb->active--; 111 | }else{ 112 | md2InstanceChangeAnimation(&tb->modelInstance,0,false); 113 | unuseActivator(&tb->activator); 114 | } 115 | 116 | md2InstanceUpdate(&tb->modelInstance); 117 | } 118 | 119 | void activateTimedButton(timedButton_s* tb) 120 | { 121 | if(!tb || !tb->used)return; 122 | 123 | tb->active=BUTTONTIMER; 124 | } 125 | 126 | void updateTimedButtons(void) 127 | { 128 | int i; 129 | for(i=0;il)continue; 157 | float d=distanceLinePoint(o,v,p); 158 | if(d<=TILESIZE_FLOAT)return tb; 159 | } 160 | } 161 | return NULL; 162 | } 163 | 164 | bool checkObjectTimedButtonCollision(physicalPoint_s* o, room_s* r, timedButton_s* tb) 165 | { 166 | if(!o || !r || !tb)return false; 167 | 168 | bool ret=false; 169 | 170 | vect3Df_s u=vect3Df(o->position.x-tb->position.x,0,o->position.z-tb->position.z); 171 | float v=vmagf(u); 172 | 173 | if(fabs(o->position.y-tb->position.y)>TIMEDBUTTON_HEIGHT)return ret; 174 | 175 | if(vradius+TIMEDBUTTON_RADIUS_OUT) 176 | { 177 | u=vdivf(vmulf(u,o->radius+TIMEDBUTTON_RADIUS_OUT-v),v); 178 | o->position=vaddf(o->position,u); 179 | ret=true; 180 | } 181 | 182 | return ret; 183 | } 184 | 185 | bool checkObjectTimedButtonsCollision(physicalPoint_s* o, room_s* r) 186 | { 187 | int i; 188 | bool ret=false; 189 | for(i=0;i 2 | #include 3 | #include "light_lightmap.h" 4 | #include "light_rectangle.h" 5 | 6 | #define AMBIENTLIGHT (10) 7 | #define LIGHTMAPRESOLUTION (currentResolution) 8 | 9 | u8 currentResolution = 32; 10 | 11 | //LIGHTMAP 12 | 13 | void initLightDataLM(lightMapData_s* ld, u16 n) 14 | { 15 | if(!ld)return; 16 | 17 | ld->num=n; 18 | ld->lmSize=vect3Di(0,0,0); 19 | ld->buffer=NULL; 20 | ld->coords=(lightMapCoordinates_s*)malloc(sizeof(lightMapCoordinates_s)*n); 21 | } 22 | 23 | u8 computeLighting(vect3Df_s l, float intensity, vect3Df_s p, rectangle_s* rec, room_s* r) 24 | { 25 | float dist=vdistf(l,p); 26 | if(distnormal); 32 | v=maxf(0,v); 33 | v*=3; 34 | v/=4; 35 | v+=0.25f; 36 | // printf("%f\n",v); 37 | return (u8)(v*(255-((dist*255)/intensity))); 38 | } 39 | return 0; 40 | } 41 | 42 | u8 computeLightings(vect3Df_s p, rectangle_s* rec, room_s* r) 43 | { 44 | int v=AMBIENTLIGHT; 45 | int i; 46 | for(i=0;iposition, l->intensity, p, rec, r); 52 | } 53 | } 54 | return (u8)(mini(maxi(v,0),255)); 55 | } 56 | 57 | void fillBuffer(u8* buffer, vect3Di_s p, vect3Di_s s, u8* v, bool rot, int w, int h) 58 | { 59 | if(!buffer || !v)return; 60 | int i; 61 | // u8 vt=(rand()%31)<<3; 62 | if(!rot) 63 | { 64 | printf("bounds %d %d\n",p.x+s.x,p.y+s.y); 65 | for(i=0;isize; 92 | if(size.x>0)u.x=(TILESIZE_FLOAT*2)/LIGHTMAPRESOLUTION; 93 | else if(size.x)u.x=-(TILESIZE_FLOAT*2)/LIGHTMAPRESOLUTION; 94 | if(size.y>0)u.y=(TILESIZE_FLOAT*2)/LIGHTMAPRESOLUTION; 95 | else if(size.y)u.y=-(TILESIZE_FLOAT*2)/LIGHTMAPRESOLUTION; 96 | if(size.z>0)u.z=(TILESIZE_FLOAT*2)/LIGHTMAPRESOLUTION; 97 | else if(size.z)u.z=-(TILESIZE_FLOAT*2)/LIGHTMAPRESOLUTION; 98 | return u; 99 | } 100 | 101 | void generateLightmap(rectangle_s* rec, room_s* r, lightMapData_s* lmd, u8* b, lightMapCoordinates_s* lmc) 102 | { 103 | if(rec && b) 104 | { 105 | u16 x=lmc->lmSize.x, y=lmc->lmSize.y; 106 | u8* data=malloc(x*y); 107 | if(!data)return; 108 | vect3Df_s p=convertRectangleVector(rec->position); 109 | // printf("p : %f, %f, %f\n",p.x,p.y,p.z); 110 | printf("p : %d, %d, %d\n",rec->position.x,rec->position.y,rec->position.z); 111 | printf("t : %d, %d\n",lmc->lmPos.x,lmc->lmPos.y); 112 | int i; 113 | vect3Df_s u=getUnitVect(rec); 114 | for(i=0;isize.x)data[i+j*x]=computeLightings(vaddf(p,vect3Df(0,i*u.y+u.y/2,j*u.z+u.z/2)),rec,r); 120 | else if(rec->size.y)data[i+j*x]=computeLightings(vaddf(p,vect3Df(i*u.x+u.x/2,j*u.y+u.y/2,0)),rec,r); 121 | else data[i+j*x]=computeLightings(vaddf(p,vect3Df(i*u.x+u.x/2,0,j*u.z+u.z/2)),rec,r); 122 | } 123 | } 124 | fillBuffer(b, vect3Di(lmc->lmPos.x,lmc->lmPos.y,0), vect3Di(lmc->lmSize.x,lmc->lmSize.y,0), data, lmc->rot, lmd->lmSize.x, lmd->lmSize.y); 125 | free(data); 126 | }else printf("NOTHING?\n"); 127 | } 128 | 129 | int generateLightmaps(room_s* r, lightMapData_s* ld) 130 | { 131 | if(!r)return -1; 132 | listCell_s *lc=r->rectangles.first; 133 | rectangle2DList_s rl; 134 | initRectangle2DList(&rl); 135 | int i=0; 136 | initLightDataLM(ld, r->rectangles.num); 137 | 138 | while(lc) 139 | { 140 | insertRectangle2DList(&rl,(rectangle2D_s){vect2(0,0),vect2(abs(lc->data.size.x?(lc->data.size.x*LIGHTMAPRESOLUTION):(lc->data.size.y*LIGHTMAPRESOLUTION*HEIGHTUNIT/(TILESIZE_FLOAT*2))), 141 | abs((lc->data.size.y&&lc->data.size.x)?(lc->data.size.y*LIGHTMAPRESOLUTION*HEIGHTUNIT/(TILESIZE_FLOAT*2)):(lc->data.size.z*LIGHTMAPRESOLUTION))), 142 | &ld->coords[i++], false}); 143 | lc=lc->next; 144 | } 145 | short w=32, h=32; 146 | 147 | bool rr=packRectanglesSize(&rl, &w, &h); 148 | ld->lmSize=vect3Di(w,h,0); 149 | printf("done : %d %dx%d\n",(int)rr,w,h); 150 | 151 | if(!rr) 152 | { 153 | //TEMP 154 | // freeLightData(ld); 155 | return -1; 156 | } 157 | 158 | ld->buffer=malloc(w*h); 159 | 160 | if(!ld->buffer) 161 | { 162 | // freeLightData(ld); 163 | return -1; 164 | } 165 | 166 | lc=r->rectangles.first; 167 | i=0; 168 | while(lc) 169 | { 170 | generateLightmap(&lc->data, r, ld, ld->buffer, &ld->coords[i++]); 171 | lc=lc->next; 172 | } 173 | 174 | freeRectangle2DList(&rl); 175 | printf("freed.\n"); 176 | 177 | return 0; 178 | } 179 | -------------------------------------------------------------------------------- /source/game/sludge.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds.h> 4 | #include "game/sludge.h" 5 | #include "game/emancipation.h" 6 | #include "gfx/gs.h" 7 | 8 | rectangleList_s sludgeRectangleList; 9 | texture_s sludgeTexture; 10 | 11 | rectangleVertex_s* sludgeVertexBuffer = NULL; 12 | u16* sludgeIndexBuffer = NULL; 13 | int sludgeNumVertices = 0; 14 | int sludgeNumIndices = 0; 15 | 16 | void initSludge(void) 17 | { 18 | initRectangleList(&sludgeRectangleList); 19 | 20 | textureLoad(&sludgeTexture, "sludge.png", GPU_TEXTURE_MAG_FILTER(GPU_LINEAR)|GPU_TEXTURE_MIN_FILTER(GPU_LINEAR)|GPU_TEXTURE_WRAP_S(GPU_REPEAT)|GPU_TEXTURE_WRAP_T(GPU_REPEAT), 10); 21 | 22 | sludgeVertexBuffer = NULL; 23 | sludgeIndexBuffer = NULL; 24 | sludgeNumVertices = 0; 25 | sludgeNumIndices = 0; 26 | } 27 | 28 | void exitSludge(void) 29 | { 30 | while(sludgeRectangleList.num)popRectangle(&sludgeRectangleList); 31 | if(sludgeVertexBuffer)linearFree(sludgeVertexBuffer); 32 | if(sludgeIndexBuffer)linearFree(sludgeIndexBuffer); 33 | textureFree(&sludgeTexture); 34 | } 35 | 36 | void addSludgeRectangle(rectangle_s* rec) 37 | { 38 | if(!rec)return; 39 | 40 | addRectangle(*rec, &sludgeRectangleList); 41 | } 42 | 43 | void generateSludgeRectangleGeometry(rectangle_s* rec) 44 | { 45 | if(!rec)return; 46 | 47 | vect3Di_s texCoords[4]; 48 | 49 | texCoords[0] = vect3Di(rec->position.x, rec->position.z, 0); 50 | texCoords[1] = vect3Di(rec->position.x+rec->size.x, rec->position.z, 0); 51 | texCoords[2] = vect3Di(rec->position.x+rec->size.x, rec->position.z+rec->size.z, 0); 52 | texCoords[3] = vect3Di(rec->position.x, rec->position.z+rec->size.z, 0); 53 | 54 | int i; for(i=0; i<4; i++)texCoords[i] = vmuli(texCoords[i], 16); 55 | 56 | generateRectangleGeometry(rec, texCoords, sludgeVertexBuffer, &sludgeNumVertices, sludgeIndexBuffer, &sludgeNumIndices); 57 | } 58 | 59 | void generateSludgeGeometry(void) 60 | { 61 | if(!sludgeRectangleList.num)return; 62 | 63 | listCell_s* lc=sludgeRectangleList.first; 64 | 65 | sludgeVertexBuffer = linearAlloc(sizeof(rectangleVertex_s) * sludgeRectangleList.num * 4); 66 | sludgeIndexBuffer = linearAlloc(sizeof(u16) * sludgeRectangleList.num * 6); 67 | 68 | while(lc) 69 | { 70 | generateSludgeRectangleGeometry(&lc->data); 71 | lc=lc->next; 72 | } 73 | } 74 | 75 | void updateSludge(player_s* p) 76 | { 77 | if(!p)return; 78 | 79 | int i; 80 | for(i=0; iused && collideBoxSludge(o)) 84 | { 85 | createEmancipator(o->modelInstance, o->position, o->transformationMatrix); 86 | resetDispenserCube(o); 87 | printf("sludged up yo\n"); 88 | } 89 | } 90 | 91 | if(collideAABBSludge(p->object.position, vect3Df(PLAYER_RADIUS,PLAYER_RADIUS,PLAYER_RADIUS))) 92 | { 93 | p->life -= 100; 94 | printf("player's dead yo\n"); 95 | } 96 | } 97 | 98 | int sludgeAnimationCounter=0; 99 | 100 | extern shaderProgram_s roomProgram; 101 | extern int roomUniformTextureDimensions; 102 | extern u32 __linear_heap; 103 | #define roomBaseAddr __linear_heap 104 | 105 | void drawSludge(room_s* r) 106 | { 107 | if(!r || !sludgeIndexBuffer || !sludgeVertexBuffer || !sludgeRectangleList.num)return; 108 | 109 | //TODO : sludge texture animation 110 | 111 | gsSwitchRenderMode(-1); 112 | 113 | gsSetShader(&roomProgram); 114 | 115 | GPU_SetAttributeBuffers( 116 | 3, // number of attributes 117 | (u32*)osConvertVirtToPhys(roomBaseAddr), // we use the start of linear heap as base since that's where all our buffers are located 118 | GPU_ATTRIBFMT(0, 3, GPU_SHORT)|GPU_ATTRIBFMT(1, 2, GPU_SHORT)|GPU_ATTRIBFMT(2, 2, GPU_SHORT), // we want v0, v1 and v2 119 | 0xFF8, // mask : we want v0, v1 and v2 120 | 0x210, // permutation : we use identity 121 | 1, // number of buffers : we have one attribute per buffer 122 | (u32[]){(u32)sludgeVertexBuffer-roomBaseAddr}, // buffer offsets (placeholders) 123 | (u64[]){0x210}, // attribute permutations for each buffer 124 | (u8[]){3} // number of attributes for each buffer 125 | ); 126 | 127 | gsPushMatrix(); 128 | 129 | gsScale(TILESIZE_FLOAT*2, HEIGHTUNIT_FLOAT, TILESIZE_FLOAT*2); 130 | gsTranslate(0.0f, -HEIGHTUNIT_FLOAT*0.6f, 0.0f); 131 | 132 | gsUpdateTransformation(); 133 | 134 | textureBind(&sludgeTexture, GPU_TEXUNIT0); 135 | GPU_SetFloatUniform(GPU_VERTEX_SHADER, roomUniformTextureDimensions, (u32*)(float[]){0.0f, 0.0f, 1.0f / sludgeTexture.height, 1.0f / sludgeTexture.width}, 1); 136 | GPU_DrawElements(GPU_UNKPRIM, (u32*)((u32)sludgeIndexBuffer-roomBaseAddr), sludgeNumIndices); 137 | 138 | gsPopMatrix(); 139 | } 140 | 141 | bool sludgeAABBCollision(rectangle_s* rec, vect3Df_s p, vect3Df_s s) 142 | { 143 | if(!rec)return false; 144 | 145 | vect3Df_s pos=convertRectangleVector(rec->position); 146 | vect3Df_s sp=convertRectangleVector(rec->size); 147 | 148 | if(sp.x<0){pos.x+=sp.x;sp.x=-sp.x;} 149 | if(sp.z<0){pos.z+=sp.z;sp.z=-sp.z;} 150 | 151 | sp.x/=2; sp.z/=2; 152 | pos.x+=sp.x; pos.z+=sp.z; 153 | pos.y-=SLUDGEMARGIN; 154 | 155 | return intersectAABBAAR(p, s, pos, sp); 156 | } 157 | 158 | bool collideAABBSludge(vect3Df_s p, vect3Df_s s) 159 | { 160 | listCell_s* lc=sludgeRectangleList.first; 161 | 162 | while(lc) 163 | { 164 | if(sludgeAABBCollision(&lc->data, p, s))return true; 165 | lc=lc->next; 166 | } 167 | return false; 168 | } 169 | 170 | bool collideBoxSludge(OBB_s* o) 171 | { 172 | if(!o)return false; 173 | 174 | vect3Df_s p=o->position; 175 | vect3Df_s s; 176 | getBoxAABB(o,&s); 177 | 178 | return collideAABBSludge(p,s); 179 | } 180 | -------------------------------------------------------------------------------- /light/source/light_room_io.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "light_room.h" 4 | #include "light_room_io.h" 5 | 6 | light_s lights[NUMLIGHTS]; 7 | 8 | void initLights() 9 | { 10 | int i; 11 | for(i=0;ix=f32tofloat(fpv[0]); 45 | v->y=f32tofloat(fpv[1]); 46 | v->z=f32tofloat(fpv[2]); 47 | }else fread(v, sizeof(vect3Df_s), 1, f); 48 | } 49 | 50 | void readRectangle(rectangle_s* rec, FILE* f) 51 | { 52 | if(!rec || !f)return; 53 | 54 | readVect3Di(&rec->position, f); 55 | readVect3Di(&rec->size, f); 56 | readVect3Df(&rec->normal, f, true); 57 | 58 | // printf("rec : %d %d %d\n", rec->position.x, rec->position.y, rec->position.z); 59 | 60 | fread(&rec->portalable, sizeof(bool), 1, f); 61 | 62 | u16 mid=0; fread(&mid,sizeof(u16),1,f); 63 | } 64 | 65 | void readRectangles(room_s* r, FILE* f) 66 | { 67 | if(!r || !f)return; 68 | int i; 69 | int k=r->rectangles.num; 70 | r->rectangles.num=0; 71 | for(i=0;irectangles.num,sizeof(int),1,f); 226 | 227 | printf("RECTANGLE NUMBER %d\n", r->rectangles.num); 228 | 229 | readRectangles(r, f); 230 | 231 | //entities 232 | fseek(f, h.entityPosition, SEEK_SET); 233 | readEntities(r, f); 234 | 235 | fclose(f); 236 | } 237 | -------------------------------------------------------------------------------- /source/game/walldoor.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds.h> 4 | #include "game/walldoor.h" 5 | #include "game/room_io.h" 6 | #include "game/elevator.h" 7 | #include "game/door.h" 8 | #include "gfx/gs.h" 9 | 10 | #define DOORFRAMELENGTH (8) 11 | #define WALLDOORINTERVAL (32) 12 | 13 | room_s elevatorRoom; 14 | 15 | wallDoor_s entryWallDoor; 16 | wallDoor_s exitWallDoor; 17 | 18 | md2_model_t wallDoorModel; 19 | texture_s wallDoorTexture; 20 | 21 | vect3Df_s doorFrameData[]={{-TILESIZE*2,HEIGHTUNIT*8,0},{-TILESIZE*2,HEIGHTUNIT*5,0},{-TILESIZE,HEIGHTUNIT*8,0},{-TILESIZE,HEIGHTUNIT*7,0},{TILESIZE,HEIGHTUNIT*8,0},{TILESIZE,HEIGHTUNIT*7,0},{TILESIZE*2,HEIGHTUNIT*8,0},{TILESIZE*2,HEIGHTUNIT*5,0}}; 22 | 23 | vect3Di_s wallDoorV1[]={{0,0,1}, 24 | {0,0,-1}, 25 | {0,0,0}, 26 | {0,0,0}, 27 | {1,0,0}, 28 | {-1,0,0}}; 29 | 30 | vect3Di_s wallDoorV2[]={{-1,0,0}, 31 | {1,0,0}, 32 | {0,0,0}, 33 | {0,0,0}, 34 | {0,0,-1}, 35 | {0,0,1}}; 36 | 37 | vect3Df_s wallDoorV1f[]={{0,0,1}, 38 | {0,0,-1}, 39 | {0,0,0}, 40 | {0,0,0}, 41 | {1,0,0}, 42 | {-1,0,0}}; 43 | 44 | vect3Df_s wallDoorV2f[]={{-1,0,0}, 45 | {1,0,0}, 46 | {0,0,0}, 47 | {0,0,0}, 48 | {0,0,-1}, 49 | {0,0,1}}; 50 | 51 | void initWallDoor(wallDoor_s* wd) 52 | { 53 | if(!wd)return; 54 | 55 | wd->used=false; 56 | wd->rectangle=NULL; 57 | 58 | initActivatableObject(&wd->ao); 59 | 60 | md2InstanceInit(&wd->modelInstance, &wallDoorModel, &wallDoorTexture); 61 | } 62 | 63 | void initWallDoors(void) 64 | { 65 | initWallDoor(&entryWallDoor); 66 | initWallDoor(&exitWallDoor); 67 | 68 | //TEMP ? 69 | md2ReadModel(&wallDoorModel, "door.md2"); 70 | textureLoad(&wallDoorTexture, "door.png", GPU_TEXTURE_MAG_FILTER(GPU_LINEAR)|GPU_TEXTURE_MIN_FILTER(GPU_LINEAR), 10); 71 | 72 | readRoom("elevatorroom.map", &elevatorRoom, MAP_READ_LIGHT); 73 | } 74 | 75 | void exitWallDoors(void) 76 | { 77 | md2FreeModel(&wallDoorModel); 78 | textureFree(&wallDoorTexture); 79 | freeRoom(&elevatorRoom); 80 | } 81 | 82 | void setupWallDoor(room_s* r, wallDoor_s* wd, vect3Di_s position, u8 orientation) 83 | { 84 | if(!wd || wd->used)return; 85 | if(!r)return; 86 | 87 | wd->used=true; 88 | wd->gridPosition=vect3Di(position.x, position.y-4, position.z); 89 | wd->position=convertRectangleVector(wd->gridPosition); 90 | wd->orientation=orientation; 91 | // wd->frameMaterial=getMaterial(1); 92 | 93 | printf("ORIENTATION %d\n",orientation); 94 | 95 | rectangle_s rec; 96 | rectangle_s* recp; 97 | 98 | //door wall 99 | rec.material=NULL; 100 | rec.position=vaddi(position,vsubi(vect3Di(0,-4,0),wallDoorV1[orientation])); 101 | rec.size=vaddi(vect3Di(0,8,0),vmuli(wallDoorV1[orientation],2)); 102 | rec.normal=wallDoorV2f[orientation]; 103 | wd->rectangle=addRoomRectangle(r, rec); 104 | if(wd->rectangle)wd->rectangle->hide=true; 105 | 106 | //elevator 107 | initElevator(&wd->elevator, r, vaddi(position,vmuli(wallDoorV2[wd->orientation],7)), orientation, true); 108 | setElevatorArriving(&wd->elevator, 2.5f); 109 | 110 | //elevator room 111 | insertRoom(r, &elevatorRoom, position, orientation); 112 | } 113 | 114 | bool pointInWallDoorRoom(wallDoor_s* wd, vect3Df_s p) 115 | { 116 | if(!wd)return false; 117 | float v1=vdotf(vsubf(p,wd->position), wallDoorV1f[wd->orientation]); 118 | float v2=vdotf(vsubf(p,wd->position), wallDoorV2f[wd->orientation]); 119 | return (v1<=18)&&(wd->gridPosition.y-2<=p.y)&&(v2<=30) && (v1>=-18)&&(wd->gridPosition.y+22>=p.y)&&(v2>0); 120 | } 121 | 122 | void updateWallDoor(player_s* pl, wallDoor_s* wd) 123 | { 124 | if(!wd || !pl)return; 125 | 126 | bool pin=pointInWallDoorRoom(wd, pl->object.position); 127 | 128 | if(pin || wd->ao.active) 129 | { 130 | if(wd->modelInstance.currentAnim==0) 131 | { 132 | playSFX(doorOpenSFX); 133 | md2InstanceChangeAnimation(&wd->modelInstance, 2, false); 134 | md2InstanceChangeAnimation(&wd->modelInstance, 1, true); 135 | } 136 | updateElevator(&wd->elevator); 137 | }else{ 138 | if(wd->modelInstance.currentAnim==2) 139 | { 140 | playSFX(doorCloseSFX); 141 | md2InstanceChangeAnimation(&wd->modelInstance, 0, false); 142 | md2InstanceChangeAnimation(&wd->modelInstance, 3, true); 143 | } 144 | } 145 | 146 | if(wd->rectangle) 147 | { 148 | if(wd->modelInstance.currentAnim==2)wd->rectangle->collides=false; 149 | else wd->rectangle->collides=true; 150 | } 151 | 152 | md2InstanceUpdate(&wd->modelInstance); 153 | } 154 | 155 | extern int currentLevel; 156 | 157 | void updateWallDoors(player_s* pl) 158 | { 159 | if(!pl)return; 160 | 161 | updateWallDoor(pl, &entryWallDoor); 162 | updateWallDoor(pl, &exitWallDoor); 163 | 164 | if(exitWallDoor.elevator.state==ELEVATOR_LEAVING) 165 | { 166 | currentLevel++; 167 | pl->life-=100; 168 | printf("finished level ! yay !\n"); 169 | } 170 | } 171 | 172 | void drawWallDoor(wallDoor_s* wd) 173 | { 174 | if(!wd || !wd->used)return; 175 | 176 | gsPushMatrix(); 177 | gsSwitchRenderMode(md2GsMode); 178 | 179 | gsTranslate(wd->position.x, wd->position.y, wd->position.z); 180 | 181 | switch(wd->orientation) 182 | { 183 | case 4: 184 | gsRotateY(M_PI); 185 | break; 186 | case 1: 187 | gsRotateY(M_PI/2); 188 | break; 189 | case 0: 190 | gsRotateY(-M_PI/2); 191 | break; 192 | } 193 | 194 | md2InstanceDraw(&wd->modelInstance); 195 | gsPopMatrix(); 196 | 197 | drawElevator(&wd->elevator); 198 | } 199 | 200 | void drawWallDoors(void) 201 | { 202 | drawWallDoor(&entryWallDoor); 203 | drawWallDoor(&exitWallDoor); 204 | } 205 | -------------------------------------------------------------------------------- /light/source/light_room.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "light_room.h" 6 | 7 | void roomInit() 8 | { 9 | } 10 | 11 | void roomExit() 12 | { 13 | } 14 | 15 | void initRectangleList(rectangleList_s* p) 16 | { 17 | p->first=NULL; 18 | p->num=0; 19 | } 20 | 21 | vect3Di_s orientVector(vect3Di_s v, u8 k) 22 | { 23 | vect3Di_s u; 24 | 25 | switch(k) 26 | { 27 | case 0: 28 | u.x=-v.z; 29 | u.y=v.y; 30 | u.z=v.x; 31 | break; 32 | case 1: 33 | u.x=v.z; 34 | u.y=v.y; 35 | u.z=-v.x; 36 | break; 37 | case 4: 38 | u.x=v.x; 39 | u.y=v.y; 40 | u.z=-v.z; 41 | break; 42 | default: 43 | u=v; 44 | break; 45 | } 46 | 47 | return u; 48 | } 49 | 50 | void invertRectangle(rectangle_s* rec) 51 | { 52 | if(!rec)return; 53 | 54 | if(rec->size.x) 55 | { 56 | rec->position.x+=rec->size.x; 57 | rec->size.x=-rec->size.x; 58 | }else{ 59 | rec->position.z+=rec->size.z; 60 | rec->size.z=-rec->size.z; 61 | } 62 | } 63 | 64 | void roomOriginSize(room_s* r, vect3Di_s* o, vect3Di_s* s) 65 | { 66 | if(!r || (!o && !s))return; 67 | 68 | vect3Di_s m=vect3Di(8192,8192,8192); vect3Di_s M=vect3Di(0,0,0); 69 | 70 | listCell_s *lc=r->rectangles.first; 71 | 72 | while(lc) 73 | { 74 | m=vmini(lc->data.position,m); 75 | m=vmini(vaddi(lc->data.position,lc->data.size),m); 76 | M=vmaxi(lc->data.position,M); 77 | M=vmaxi(vaddi(lc->data.position,lc->data.size),M); 78 | lc=lc->next; 79 | } 80 | 81 | if(o)*o=m; 82 | if(s)*s=vsubi(M,m); 83 | } 84 | 85 | rectangle_s* addRectangle(rectangle_s r, rectangleList_s* p) 86 | { 87 | listCell_s* pc=(listCell_s*)malloc(sizeof(listCell_s)); 88 | pc->next=p->first; 89 | pc->data=r; 90 | p->first=pc; 91 | p->num++; 92 | return &pc->data; 93 | } 94 | 95 | void popRectangle(rectangleList_s* p) 96 | { 97 | p->num--; 98 | if(p->first) 99 | { 100 | listCell_s* pc=p->first; 101 | p->first=pc->next; 102 | free(pc); 103 | } 104 | } 105 | 106 | rectangle_s* addRoomRectangle(room_s* r, rectangle_s rec) 107 | { 108 | if((!rec.size.x && (!rec.size.z || !rec.size.y)) || (!rec.size.y && !rec.size.z))return NULL; 109 | rec.hide=false; 110 | return addRectangle(rec, &r->rectangles); 111 | } 112 | 113 | void removeRoomRectangles(room_s* r) 114 | { 115 | while(r->rectangles.num)popRectangle(&r->rectangles); 116 | } 117 | 118 | void initRoom(room_s* r, u16 w, u16 h, vect3Df_s p) 119 | { 120 | if(!r)return; 121 | 122 | r->width=w; 123 | r->height=h; 124 | r->position=p; 125 | 126 | initRectangleList(&r->rectangles); 127 | 128 | r->vertexBuffer=NULL; 129 | r->indexBuffers=NULL; 130 | 131 | // if(r->height && r->width) 132 | // { 133 | // r->materials=malloc(r->height*r->width*sizeof(material_s*)); 134 | // int i;for(i=0;iheight*r->width;i++){r->materials[i]=NULL;} 135 | // }else r->materials=NULL; 136 | } 137 | 138 | u8 getNormalOrientation(vect3Di_s v) 139 | { 140 | if(v.x>0)return 0; 141 | if(v.x<0)return 1; 142 | if(v.y>0)return 2; 143 | if(v.y<0)return 3; 144 | if(v.z>0)return 4; 145 | if(v.z<0)return 5; 146 | return 0; 147 | } 148 | 149 | void getRectangleUnitVectors(rectangle_s* rec, vect3Di_s* v1, vect3Di_s* v2) 150 | { 151 | if(!rec)return; 152 | 153 | if(rec->size.x) 154 | { 155 | if(v1)*v1=vect3Di(rec->size.x, 0, 0); 156 | if(v2) 157 | { 158 | if(rec->size.y)*v2=vect3Di(0, rec->size.y, 0); 159 | else *v2=vect3Di(0, 0, rec->size.z); 160 | } 161 | }else{ 162 | if(v1)*v1=vect3Di(0, rec->size.y, 0); 163 | if(v2)*v2=vect3Di(0, 0, rec->size.z); 164 | } 165 | } 166 | 167 | vect3Df_s convertRectangleVector(vect3Di_s v) 168 | { 169 | return vect3Df(v.x*TILESIZE_FLOAT*2, v.y*HEIGHTUNIT_FLOAT, v.z*TILESIZE_FLOAT*2); 170 | } 171 | 172 | bool collideLineRectangle(rectangle_s* rec, vect3Df_s o, vect3Df_s v, float d, float* kk, vect3Df_s* ip) 173 | { 174 | if(!rec)return false; 175 | vect3Df_s n=vect3Df(fabs(rec->normal.x),fabs(rec->normal.y),fabs(rec->normal.z)); 176 | float p1=vdotf(v,n); 177 | if(fabs(p1)>0.001f) 178 | { 179 | vect3Df_s p = convertRectangleVector(rec->position); 180 | vect3Df_s s = convertRectangleVector(rec->size); 181 | 182 | float p2=vdotf(vsubf(p,o),n); 183 | 184 | float k=p2/p1; 185 | s8 sign=((s.x>0)^(s.y<0)^(s.z>0)^(p1<0))?(-1):(1); 186 | if(kk) 187 | { 188 | *kk=k+sign; 189 | } 190 | if(k<0 || k>=d){return false;} 191 | vect3Df_s i=vaddf(o,vmulf(v,k)); 192 | if(ip)*ip=i; 193 | i=vsubf(i,p); 194 | 195 | bool r=true; 196 | if(s.x) 197 | { 198 | if(s.x>0)r=r&&i.x=0; 199 | else r=r&&i.x>s.x&&i.x<=0; 200 | } 201 | if(s.y) 202 | { 203 | if(s.y>0)r=r&&i.y=0; 204 | else r=r&&i.y>s.y&&i.y<=0; 205 | } 206 | if(s.z) 207 | { 208 | if(s.z>0)r=r&&i.z=0; 209 | else r=r&&i.z>s.z&&i.z<=0; 210 | } 211 | return r; 212 | } 213 | return false; 214 | } 215 | 216 | rectangle_s* collideLineMapClosest(room_s* r, rectangle_s* rec, vect3Df_s l, vect3Df_s u, float d, vect3Df_s* i, float* lk) 217 | { 218 | if(!r)return NULL; 219 | listCell_s *lc=r->rectangles.first; 220 | vect3Df_s v; 221 | float lowestK=d; 222 | rectangle_s* hit=NULL; 223 | while(lc) 224 | { 225 | // if(&lc->data!=rec && lc->data.collides) 226 | if(&lc->data!=rec) 227 | { 228 | float k; 229 | if(collideLineRectangle(&lc->data,l,u,lowestK,&k,&v)) 230 | { 231 | if(k %f\n",lowestK,k); 234 | if(i)*i=v; 235 | if(lk)*lk=k; 236 | lowestK=k; 237 | hit=&lc->data; 238 | } 239 | } 240 | } 241 | lc=lc->next; 242 | } 243 | return hit; 244 | } 245 | -------------------------------------------------------------------------------- /light/source/light_math.h: -------------------------------------------------------------------------------- 1 | #ifndef MATH_H 2 | #define MATH_H 3 | 4 | #include "types.h" 5 | #include 6 | 7 | #define f32tofloat(n) (((float)(n)) / (float)(1<<12)) 8 | #define f32toint(n) ((n) >> 12) 9 | #define floattof32(n) ((int)((n) * (1 << 12))) 10 | #define inttof32(n) ((n) << 12) 11 | 12 | #define f32tot16(n) ((t16)(n >> 8)) 13 | #define inttot16(n) ((n) << 4) 14 | #define t16toint(n) ((n) >> 4) 15 | #define floattot16(n) ((t16)((n) * (1 << 4))) 16 | 17 | typedef float mtx44[4][4]; 18 | typedef float mtx33[3][3]; 19 | 20 | static inline float minf(float a, float b) 21 | { 22 | return ab?a:b; 28 | } 29 | 30 | static inline int mini(int a, int b) 31 | { 32 | return ab?a:b; 38 | } 39 | 40 | typedef struct 41 | { 42 | s32 x, y, z; 43 | }vect3Di_s; 44 | 45 | static inline vect3Di_s vect3Di(s32 x, s32 y, s32 z) 46 | { 47 | return (vect3Di_s){x,y,z}; 48 | } 49 | 50 | static inline vect3Di_s vaddi(vect3Di_s u, vect3Di_s v) 51 | { 52 | return (vect3Di_s){u.x+v.x,u.y+v.y,u.z+v.z}; 53 | } 54 | 55 | static inline vect3Di_s vsubi(vect3Di_s u, vect3Di_s v) 56 | { 57 | return (vect3Di_s){u.x-v.x,u.y-v.y,u.z-v.z}; 58 | } 59 | 60 | static inline vect3Di_s vmuli(vect3Di_s v, s32 f) 61 | { 62 | return (vect3Di_s){v.x*f,v.y*f,v.z*f}; 63 | } 64 | 65 | static inline vect3Di_s vmini(vect3Di_s u, vect3Di_s v) 66 | { 67 | return vect3Di(mini(u.x,v.x),mini(u.y,v.y),mini(u.z,v.z)); 68 | } 69 | 70 | static inline vect3Di_s vmaxi(vect3Di_s u, vect3Di_s v) 71 | { 72 | return vect3Di(maxi(u.x,v.x),maxi(u.y,v.y),maxi(u.z,v.z)); 73 | } 74 | 75 | typedef struct 76 | { 77 | float x, y, z; 78 | }vect3Df_s; 79 | 80 | static inline vect3Df_s vect3Df(float x, float y, float z) 81 | { 82 | return (vect3Df_s){x,y,z}; 83 | } 84 | 85 | static inline vect3Df_s vaddf(vect3Df_s u, vect3Df_s v) 86 | { 87 | return (vect3Df_s){u.x+v.x,u.y+v.y,u.z+v.z}; 88 | } 89 | 90 | static inline vect3Df_s vsubf(vect3Df_s u, vect3Df_s v) 91 | { 92 | return (vect3Df_s){u.x-v.x,u.y-v.y,u.z-v.z}; 93 | } 94 | 95 | static inline vect3Df_s vmulf(vect3Df_s v, float f) 96 | { 97 | return (vect3Df_s){v.x*f,v.y*f,v.z*f}; 98 | } 99 | 100 | static inline vect3Df_s vdivf(vect3Df_s v, float f) 101 | { 102 | return (vect3Df_s){v.x/f,v.y/f,v.z/f}; 103 | } 104 | 105 | static inline vect3Df_s vscalef(vect3Df_s v1, vect3Df_s v2) 106 | { 107 | return (vect3Df_s){v1.x*v2.x,v1.y*v2.y,v1.z*v2.z}; 108 | } 109 | 110 | static inline float vmagf(vect3Df_s v) 111 | { 112 | return sqrtf(v.x*v.x+v.y*v.y+v.z*v.z); 113 | } 114 | 115 | static inline float vdistf(vect3Df_s v1, vect3Df_s v2) 116 | { 117 | 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)); 118 | } 119 | 120 | static inline vect3Df_s vnormf(vect3Df_s v) 121 | { 122 | const float l=sqrtf(v.x*v.x+v.y*v.y+v.z*v.z); 123 | return (vect3Df_s){v.x/l,v.y/l,v.z/l}; 124 | } 125 | 126 | static inline float vdotf(vect3Df_s v1, vect3Df_s v2) 127 | { 128 | return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z; 129 | } 130 | 131 | static inline vect3Df_s vprodf(vect3Df_s v1, vect3Df_s v2) 132 | { 133 | return vect3Df((v1.y*v2.z)-(v1.z*v2.y),(v1.z*v2.x)-(v1.x*v2.z),(v1.x*v2.y)-(v1.y*v2.x)); 134 | } 135 | 136 | static inline vect3Df_s vevalf(float* m, vect3Df_s v) //3x3 137 | { 138 | return vect3Df(((v.x*m[0])+(v.y*m[1])+(v.z*m[2])), 139 | ((v.x*m[3])+(v.y*m[4])+(v.z*m[5])), 140 | ((v.x*m[6])+(v.y*m[7])+(v.z*m[8]))); 141 | } 142 | 143 | typedef struct 144 | { 145 | float x, y, z, w; 146 | }vect4Df_s; 147 | 148 | static inline vect4Df_s vect4Df(float x, float y, float z, float w) 149 | { 150 | return (vect4Df_s){x,y,z,w}; 151 | } 152 | 153 | static inline vect4Df_s vaddf4(vect4Df_s u, vect4Df_s v) 154 | { 155 | return (vect4Df_s){u.x+v.x,u.y+v.y,u.z+v.z,u.w+v.w}; 156 | } 157 | 158 | static inline vect4Df_s vsubf4(vect4Df_s u, vect4Df_s v) 159 | { 160 | return (vect4Df_s){u.x-v.x,u.y-v.y,u.z-v.z,u.w-v.w}; 161 | } 162 | 163 | static inline vect4Df_s vmulf4(vect4Df_s v, float f) 164 | { 165 | return (vect4Df_s){v.x*f,v.y*f,v.z*f,v.w*f}; 166 | } 167 | 168 | static inline float vdotf4(vect4Df_s v1, vect4Df_s v2) 169 | { 170 | return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z+v1.w*v2.w; 171 | } 172 | 173 | static inline vect4Df_s vnormf4(vect4Df_s v) 174 | { 175 | const float l=sqrtf(v.x*v.x+v.y*v.y+v.z*v.z+v.w*v.w); 176 | return (vect4Df_s){v.x/l,v.y/l,v.z/l,v.w/l}; 177 | } 178 | 179 | //interstuff 180 | static inline vect3Di_s vf2i(vect3Df_s v) 181 | { 182 | return (vect3Di_s){floorf(v.x),floorf(v.y),floorf(v.z)}; 183 | } 184 | 185 | static inline vect3Df_s vi2f(vect3Di_s v) 186 | { 187 | return (vect3Df_s){(float)v.x,(float)v.y,(float)v.z}; 188 | } 189 | 190 | void loadIdentity44(float* m); 191 | void transposeMatrix44(float* m1, float* m2); 192 | void multMatrix44(float* m1, float* m2, float* m); 193 | vect3Df_s multMatrix44Vect3(float* m, vect3Df_s v, bool transpose); 194 | vect4Df_s multMatrix44Vect4(float* m, vect4Df_s v, bool transpose); 195 | 196 | void translateMatrix(float* tm, float x, float y, float z); 197 | void rotateMatrixX(float* tm, float x, bool r); 198 | void rotateMatrixY(float* tm, float x, bool r); 199 | void rotateMatrixZ(float* tm, float x, bool r); 200 | void scaleMatrix(float* tm, float x, float y, float z); 201 | void rotateMatrixAxis(float* tm, float x, vect3Df_s a, bool r); 202 | 203 | void multMatrix33(float* m1, float* m2, float* m); 204 | void addMatrix33(float* m1, float* m2, float* m); 205 | void fixMatrix33(float* m); 206 | void transposeMatrix33(float* m1, float* m2); 207 | 208 | void initProjectionMatrix(float* m, float fovy, float aspect, float near, float far); 209 | 210 | vect3Df_s getMatrixColumn(float* m, u8 i); 211 | vect3Df_s getMatrixRow(float* m, u8 i); 212 | vect4Df_s getMatrixColumn4(float* m, u8 i); 213 | vect4Df_s getMatrixRow4(float* m, u8 i); 214 | 215 | #endif 216 | -------------------------------------------------------------------------------- /include/utils/math.h: -------------------------------------------------------------------------------- 1 | #ifndef MATH_H 2 | #define MATH_H 3 | 4 | #include <3ds/types.h> 5 | #include 6 | 7 | #define f32tofloat(n) (((float)(n)) / (float)(1<<12)) 8 | #define f32toint(n) ((n) >> 12) 9 | #define floattof32(n) ((int)((n) * (1 << 12))) 10 | #define inttof32(n) ((n) << 12) 11 | 12 | #define f32tot16(n) ((t16)(n >> 8)) 13 | #define inttot16(n) ((n) << 4) 14 | #define t16toint(n) ((n) >> 4) 15 | #define floattot16(n) ((t16)((n) * (1 << 4))) 16 | 17 | typedef float mtx44[4][4]; 18 | typedef float mtx33[3][3]; 19 | 20 | static inline float minf(float a, float b) 21 | { 22 | return ab?a:b; 28 | } 29 | 30 | static inline int mini(int a, int b) 31 | { 32 | return ab?a:b; 38 | } 39 | 40 | typedef struct 41 | { 42 | s32 x, y, z; 43 | }vect3Di_s; 44 | 45 | static inline vect3Di_s vect3Di(s32 x, s32 y, s32 z) 46 | { 47 | return (vect3Di_s){x,y,z}; 48 | } 49 | 50 | static inline vect3Di_s vaddi(vect3Di_s u, vect3Di_s v) 51 | { 52 | return (vect3Di_s){u.x+v.x,u.y+v.y,u.z+v.z}; 53 | } 54 | 55 | static inline vect3Di_s vsubi(vect3Di_s u, vect3Di_s v) 56 | { 57 | return (vect3Di_s){u.x-v.x,u.y-v.y,u.z-v.z}; 58 | } 59 | 60 | static inline vect3Di_s vmuli(vect3Di_s v, s32 f) 61 | { 62 | return (vect3Di_s){v.x*f,v.y*f,v.z*f}; 63 | } 64 | 65 | static inline vect3Di_s vmini(vect3Di_s u, vect3Di_s v) 66 | { 67 | return vect3Di(mini(u.x,v.x),mini(u.y,v.y),mini(u.z,v.z)); 68 | } 69 | 70 | static inline vect3Di_s vmaxi(vect3Di_s u, vect3Di_s v) 71 | { 72 | return vect3Di(maxi(u.x,v.x),maxi(u.y,v.y),maxi(u.z,v.z)); 73 | } 74 | 75 | typedef struct 76 | { 77 | float x, y, z; 78 | }vect3Df_s; 79 | 80 | static inline vect3Df_s vect3Df(float x, float y, float z) 81 | { 82 | return (vect3Df_s){x,y,z}; 83 | } 84 | 85 | static inline vect3Df_s vaddf(vect3Df_s u, vect3Df_s v) 86 | { 87 | return (vect3Df_s){u.x+v.x,u.y+v.y,u.z+v.z}; 88 | } 89 | 90 | static inline vect3Df_s vsubf(vect3Df_s u, vect3Df_s v) 91 | { 92 | return (vect3Df_s){u.x-v.x,u.y-v.y,u.z-v.z}; 93 | } 94 | 95 | static inline vect3Df_s vmulf(vect3Df_s v, float f) 96 | { 97 | return (vect3Df_s){v.x*f,v.y*f,v.z*f}; 98 | } 99 | 100 | static inline vect3Df_s vdivf(vect3Df_s v, float f) 101 | { 102 | return (vect3Df_s){v.x/f,v.y/f,v.z/f}; 103 | } 104 | 105 | static inline vect3Df_s vscalef(vect3Df_s v1, vect3Df_s v2) 106 | { 107 | return (vect3Df_s){v1.x*v2.x,v1.y*v2.y,v1.z*v2.z}; 108 | } 109 | 110 | static inline float vmagf(vect3Df_s v) 111 | { 112 | return sqrtf(v.x*v.x+v.y*v.y+v.z*v.z); 113 | } 114 | 115 | static inline float vdistf(vect3Df_s v1, vect3Df_s v2) 116 | { 117 | 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)); 118 | } 119 | 120 | static inline vect3Df_s vnormf(vect3Df_s v) 121 | { 122 | const float l=sqrtf(v.x*v.x+v.y*v.y+v.z*v.z); 123 | return (vect3Df_s){v.x/l,v.y/l,v.z/l}; 124 | } 125 | 126 | static inline float vdotf(vect3Df_s v1, vect3Df_s v2) 127 | { 128 | return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z; 129 | } 130 | 131 | static inline vect3Df_s vprodf(vect3Df_s v1, vect3Df_s v2) 132 | { 133 | return vect3Df((v1.y*v2.z)-(v1.z*v2.y),(v1.z*v2.x)-(v1.x*v2.z),(v1.x*v2.y)-(v1.y*v2.x)); 134 | } 135 | 136 | static inline vect3Df_s vevalf(float* m, vect3Df_s v) //3x3 137 | { 138 | return vect3Df(((v.x*m[0])+(v.y*m[1])+(v.z*m[2])), 139 | ((v.x*m[3])+(v.y*m[4])+(v.z*m[5])), 140 | ((v.x*m[6])+(v.y*m[7])+(v.z*m[8]))); 141 | } 142 | 143 | typedef struct 144 | { 145 | float x, y, z, w; 146 | }vect4Df_s; 147 | 148 | static inline vect4Df_s vect4Df(float x, float y, float z, float w) 149 | { 150 | return (vect4Df_s){x,y,z,w}; 151 | } 152 | 153 | static inline vect4Df_s vaddf4(vect4Df_s u, vect4Df_s v) 154 | { 155 | return (vect4Df_s){u.x+v.x,u.y+v.y,u.z+v.z,u.w+v.w}; 156 | } 157 | 158 | static inline vect4Df_s vsubf4(vect4Df_s u, vect4Df_s v) 159 | { 160 | return (vect4Df_s){u.x-v.x,u.y-v.y,u.z-v.z,u.w-v.w}; 161 | } 162 | 163 | static inline vect4Df_s vmulf4(vect4Df_s v, float f) 164 | { 165 | return (vect4Df_s){v.x*f,v.y*f,v.z*f,v.w*f}; 166 | } 167 | 168 | static inline float vdotf4(vect4Df_s v1, vect4Df_s v2) 169 | { 170 | return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z+v1.w*v2.w; 171 | } 172 | 173 | static inline vect4Df_s vnormf4(vect4Df_s v) 174 | { 175 | const float l=sqrtf(v.x*v.x+v.y*v.y+v.z*v.z+v.w*v.w); 176 | return (vect4Df_s){v.x/l,v.y/l,v.z/l,v.w/l}; 177 | } 178 | 179 | //interstuff 180 | static inline vect3Di_s vf2i(vect3Df_s v) 181 | { 182 | return (vect3Di_s){floorf(v.x),floorf(v.y),floorf(v.z)}; 183 | } 184 | 185 | static inline vect3Df_s vi2f(vect3Di_s v) 186 | { 187 | return (vect3Df_s){(float)v.x,(float)v.y,(float)v.z}; 188 | } 189 | 190 | void loadIdentity44(float* m); 191 | void transposeMatrix44(float* m1, float* m2); 192 | void multMatrix44(float* m1, float* m2, float* m); 193 | vect3Df_s multMatrix44Vect3(float* m, vect3Df_s v, bool transpose); 194 | vect4Df_s multMatrix44Vect4(float* m, vect4Df_s v, bool transpose); 195 | 196 | void translateMatrix(float* tm, float x, float y, float z); 197 | void rotateMatrixX(float* tm, float x, bool r); 198 | void rotateMatrixY(float* tm, float x, bool r); 199 | void rotateMatrixZ(float* tm, float x, bool r); 200 | void scaleMatrix(float* tm, float x, float y, float z); 201 | void rotateMatrixAxis(float* tm, float x, vect3Df_s a, bool r); 202 | 203 | void loadIdentity33(float* m); 204 | void multMatrix33(float* m1, float* m2, float* m); 205 | void addMatrix33(float* m1, float* m2, float* m); 206 | void fixMatrix33(float* m); 207 | void transposeMatrix33(float* m1, float* m2); 208 | 209 | void initProjectionMatrix(float* m, float fovy, float aspect, float near, float far); 210 | 211 | vect3Df_s getMatrixColumn(float* m, u8 i); 212 | vect3Df_s getMatrixRow(float* m, u8 i); 213 | vect4Df_s getMatrixColumn4(float* m, u8 i); 214 | vect4Df_s getMatrixRow4(float* m, u8 i); 215 | 216 | #endif 217 | -------------------------------------------------------------------------------- /tools/norm.py: -------------------------------------------------------------------------------- 1 | norms = [[-0.525731, 0.000000, 0.850651], [-0.442863, 0.238856, 0.864188], [-0.295242, 0.000000, 0.955423], [-0.309017, 0.500000, 0.809017], [-0.162460, 0.262866, 0.951056], [ 0.000000, 0.000000, 1.000000], [ 0.000000, 0.850651, 0.525731], [-0.147621, 0.716567, 0.681718], [ 0.147621, 0.716567, 0.681718], [ 0.000000, 0.525731, 0.850651], [ 0.309017, 0.500000, 0.809017], [ 0.525731, 0.000000, 0.850651], [ 0.295242, 0.000000, 0.955423], [ 0.442863, 0.238856, 0.864188], [ 0.162460, 0.262866, 0.951056], [-0.681718, 0.147621, 0.716567], [-0.809017, 0.309017, 0.500000], [-0.587785, 0.425325, 0.688191], [-0.850651, 0.525731, 0.000000], [-0.864188, 0.442863, 0.238856], [-0.716567, 0.681718, 0.147621], [-0.688191, 0.587785, 0.425325], [-0.500000, 0.809017, 0.309017], [-0.238856, 0.864188, 0.442863], [-0.425325, 0.688191, 0.587785], [-0.716567, 0.681718, -0.147621], [-0.500000, 0.809017, -0.309017], [-0.525731, 0.850651, 0.000000], [ 0.000000, 0.850651, -0.525731], [-0.238856, 0.864188, -0.442863], [ 0.000000, 0.955423, -0.295242], [-0.262866, 0.951056, -0.162460], [ 0.000000, 1.000000, 0.000000], [ 0.000000, 0.955423, 0.295242], [-0.262866, 0.951056, 0.162460], [ 0.238856, 0.864188, 0.442863], [ 0.262866, 0.951056, 0.162460], [ 0.500000, 0.809017, 0.309017], [ 0.238856, 0.864188, -0.442863], [ 0.262866, 0.951056, -0.162460], [ 0.500000, 0.809017, -0.309017], [ 0.850651, 0.525731, 0.000000], [ 0.716567, 0.681718, 0.147621], [ 0.716567, 0.681718, -0.147621], [ 0.525731, 0.850651, 0.000000], [ 0.425325, 0.688191, 0.587785], [ 0.864188, 0.442863, 0.238856], [ 0.688191, 0.587785, 0.425325], [ 0.809017, 0.309017, 0.500000], [ 0.681718, 0.147621, 0.716567], [ 0.587785, 0.425325, 0.688191], [ 0.955423, 0.295242, 0.000000], [ 1.000000, 0.000000, 0.000000], [ 0.951056, 0.162460, 0.262866], [ 0.850651, -0.525731, 0.000000], [ 0.955423, -0.295242, 0.000000], [ 0.864188, -0.442863, 0.238856], [ 0.951056, -0.162460, 0.262866], [ 0.809017, -0.309017, 0.500000], [ 0.681718, -0.147621, 0.716567], [ 0.850651, 0.000000, 0.525731], [ 0.864188, 0.442863, -0.238856], [ 0.809017, 0.309017, -0.500000], [ 0.951056, 0.162460, -0.262866], [ 0.525731, 0.000000, -0.850651], [ 0.681718, 0.147621, -0.716567], [ 0.681718, -0.147621, -0.716567], [ 0.850651, 0.000000, -0.525731], [ 0.809017, -0.309017, -0.500000], [ 0.864188, -0.442863, -0.238856], [ 0.951056, -0.162460, -0.262866], [ 0.147621, 0.716567, -0.681718], [ 0.309017, 0.500000, -0.809017], [ 0.425325, 0.688191, -0.587785], [ 0.442863, 0.238856, -0.864188], [ 0.587785, 0.425325, -0.688191], [ 0.688191, 0.587785, -0.425325], [-0.147621, 0.716567, -0.681718], [-0.309017, 0.500000, -0.809017], [ 0.000000, 0.525731, -0.850651], [-0.525731, 0.000000, -0.850651], [-0.442863, 0.238856, -0.864188], [-0.295242, 0.000000, -0.955423], [-0.162460, 0.262866, -0.951056], [ 0.000000, 0.000000, -1.000000], [ 0.295242, 0.000000, -0.955423], [ 0.162460, 0.262866, -0.951056], [-0.442863, -0.238856, -0.864188], [-0.309017, -0.500000, -0.809017], [-0.162460, -0.262866, -0.951056], [ 0.000000, -0.850651, -0.525731], [-0.147621, -0.716567, -0.681718], [ 0.147621, -0.716567, -0.681718], [ 0.000000, -0.525731, -0.850651], [ 0.309017, -0.500000, -0.809017], [ 0.442863, -0.238856, -0.864188], [ 0.162460, -0.262866, -0.951056], [ 0.238856, -0.864188, -0.442863], [ 0.500000, -0.809017, -0.309017], [ 0.425325, -0.688191, -0.587785], [ 0.716567, -0.681718, -0.147621], [ 0.688191, -0.587785, -0.425325], [ 0.587785, -0.425325, -0.688191], [ 0.000000, -0.955423, -0.295242], [ 0.000000, -1.000000, 0.000000], [ 0.262866, -0.951056, -0.162460], [ 0.000000, -0.850651, 0.525731], [ 0.000000, -0.955423, 0.295242], [ 0.238856, -0.864188, 0.442863], [ 0.262866, -0.951056, 0.162460], [ 0.500000, -0.809017, 0.309017], [ 0.716567, -0.681718, 0.147621], [ 0.525731, -0.850651, 0.000000], [-0.238856, -0.864188, -0.442863], [-0.500000, -0.809017, -0.309017], [-0.262866, -0.951056, -0.162460], [-0.850651, -0.525731, 0.000000], [-0.716567, -0.681718, -0.147621], [-0.716567, -0.681718, 0.147621], [-0.525731, -0.850651, 0.000000], [-0.500000, -0.809017, 0.309017], [-0.238856, -0.864188, 0.442863], [-0.262866, -0.951056, 0.162460], [-0.864188, -0.442863, 0.238856], [-0.809017, -0.309017, 0.500000], [-0.688191, -0.587785, 0.425325], [-0.681718, -0.147621, 0.716567], [-0.442863, -0.238856, 0.864188], [-0.587785, -0.425325, 0.688191], [-0.309017, -0.500000, 0.809017], [-0.147621, -0.716567, 0.681718], [-0.425325, -0.688191, 0.587785], [-0.162460, -0.262866, 0.951056], [ 0.442863, -0.238856, 0.864188], [ 0.162460, -0.262866, 0.951056], [ 0.309017, -0.500000, 0.809017], [ 0.147621, -0.716567, 0.681718], [ 0.000000, -0.525731, 0.850651], [ 0.425325, -0.688191, 0.587785], [ 0.587785, -0.425325, 0.688191], [ 0.688191, -0.587785, 0.425325], [-0.955423, 0.295242, 0.000000], [-0.951056, 0.162460, 0.262866], [-1.000000, 0.000000, 0.000000], [-0.850651, 0.000000, 0.525731], [-0.955423, -0.295242, 0.000000], [-0.951056, -0.162460, 0.262866], [-0.864188, 0.442863, -0.238856], [-0.951056, 0.162460, -0.262866], [-0.809017, 0.309017, -0.500000], [-0.864188, -0.442863, -0.238856], [-0.951056, -0.162460, -0.262866], [-0.809017, -0.309017, -0.500000], [-0.681718, 0.147621, -0.716567], [-0.681718, -0.147621, -0.716567], [-0.850651, 0.000000, -0.525731], [-0.688191, 0.587785, -0.425325], [-0.587785, 0.425325, -0.688191], [-0.425325, 0.688191, -0.587785], [-0.425325, -0.688191, -0.587785], [-0.587785, -0.425325, -0.688191], [-0.688191, -0.587785, -0.42532]] 2 | 3 | out = [] 4 | permutation = [{},{}] 5 | for i, v in enumerate(norms): 6 | if [-v[0],-v[1],-v[2]] not in out: 7 | permutation[0][i] = len(out) 8 | out.append(v) 9 | else: 10 | permutation[1][i] = out.index([-v[0],-v[1],-v[2]]) 11 | 12 | for i in permutation[1]: 13 | # permutation[0][i] = len(out) + permutation[1][i] 14 | permutation[0][i] = permutation[1][i] 15 | 16 | # print(permutation[0]) 17 | # print(len(out)) 18 | 19 | # for i, n in enumerate(out): 20 | # print(".const c%d, %f, %f, %f, 0.0" % (i, n[0], n[1], n[2])) 21 | 22 | for i in range(len(norms)): 23 | print(permutation[0][i]) 24 | -------------------------------------------------------------------------------- /source/physics/request.c: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | 4 | #include "physics/physicsThread.h" 5 | #include "physics/request.h" 6 | 7 | #define REQUESTPOOL_ALLOCSIZE (128) 8 | 9 | request_s* requestPool; 10 | 11 | void initRequestPool(void) 12 | { 13 | requestPool=NULL; 14 | } 15 | 16 | void allocatePoolRequests(void) 17 | { 18 | request_s* newRequests=malloc(sizeof(request_s)*REQUESTPOOL_ALLOCSIZE); 19 | int i; for(i=0;inext; 30 | r->next=NULL; 31 | return r; 32 | } 33 | 34 | request_s* createNewRequest(requestTypes_t t) 35 | { 36 | if(t<0 || t>=NUM_REQUEST_TYPES)return NULL; 37 | request_s* r=getNewRequest(); 38 | if(!r)return r; 39 | r->type=t; 40 | r->data=requestTypes[t].dataSize?malloc(requestTypes[t].dataSize):NULL; 41 | return r; 42 | } 43 | 44 | void freeRequest(request_s* r) 45 | { 46 | if(!r)return; 47 | if(r->data){free(r->data);r->data=NULL;} 48 | r->next=requestPool; 49 | requestPool=r; 50 | } 51 | 52 | //REQUEST_CREATE_OBB 53 | typedef struct 54 | { 55 | OBB_s** out; 56 | vect3Df_s position, size; 57 | md2_instance_t* model; 58 | float mass, angle; 59 | }requestCreateObbData_s; 60 | 61 | request_s* createRequestCreateObb(OBB_s** out, vect3Df_s position, vect3Df_s size, md2_instance_t* model, float mass, float angle) 62 | { 63 | request_s* r=createNewRequest(REQUEST_CREATE_OBB); 64 | if(!r)return r; 65 | requestCreateObbData_s* d=(requestCreateObbData_s*)r->data; 66 | 67 | d->out = out; 68 | d->position = position; 69 | d->size = size; 70 | d->model = model; 71 | d->mass = mass; 72 | d->angle = angle; 73 | 74 | return r; 75 | } 76 | 77 | void requestCreateObbHandler(struct physicsThread_s* p, request_s* r) 78 | { 79 | if(!p || !r)return; 80 | requestCreateObbData_s* d=(requestCreateObbData_s*)r->data; 81 | 82 | OBB_s* o = createOBB(d->position, d->size, d->model, d->mass, d->angle); 83 | if(d->out)*d->out = o; 84 | } 85 | 86 | //REQUEST_RESET_OBB 87 | typedef struct 88 | { 89 | OBB_s* target; 90 | vect3Df_s position, size; 91 | md2_instance_t* model; 92 | float mass, angle; 93 | }requestResetObbData_s; 94 | 95 | request_s* createRequestResetObb(OBB_s* target, vect3Df_s position, vect3Df_s size, md2_instance_t* model, float mass, float angle) 96 | { 97 | request_s* r=createNewRequest(REQUEST_RESET_OBB); 98 | if(!r)return r; 99 | requestResetObbData_s* d=(requestResetObbData_s*)r->data; 100 | 101 | d->target = target; 102 | d->position = position; 103 | d->size = size; 104 | d->model = model; 105 | d->mass = mass; 106 | d->angle = angle; 107 | 108 | return r; 109 | } 110 | 111 | void requestResetObbHandler(struct physicsThread_s* p, request_s* r) 112 | { 113 | if(!p || !r)return; 114 | requestResetObbData_s* d=(requestResetObbData_s*)r->data; 115 | 116 | initOBB(d->target, d->position, d->size, d->model, d->mass, d->angle); 117 | } 118 | 119 | //REQUEST_CREATE_AAR 120 | typedef struct 121 | { 122 | AAR_s** out; 123 | vect3Df_s position, size, normal; 124 | }requestCreateAarData_s; 125 | 126 | request_s* createRequestCreateAar(AAR_s** out, vect3Df_s position, vect3Df_s size, vect3Df_s normal) 127 | { 128 | request_s* r=createNewRequest(REQUEST_CREATE_AAR); 129 | if(!r)return r; 130 | requestCreateAarData_s* d=(requestCreateAarData_s*)r->data; 131 | 132 | if(size.x<0){position.x+=size.x;size.x=-size.x;} 133 | if(size.y<0){position.y+=size.y;size.y=-size.y;} 134 | if(size.z<0){position.z+=size.z;size.z=-size.z;} 135 | 136 | d->out = out; 137 | d->position = position; 138 | d->size = size; 139 | d->normal = normal; 140 | 141 | return r; 142 | } 143 | 144 | void requestCreateAarHandler(struct physicsThread_s* p, request_s* r) 145 | { 146 | if(!p || !r)return; 147 | requestCreateAarData_s* d=(requestCreateAarData_s*)r->data; 148 | 149 | AAR_s* a = createAAR(d->position, d->size, d->normal); 150 | if(d->out)*d->out = a; 151 | } 152 | 153 | //REQUEST_GENERATE_GRID 154 | 155 | request_s* createRequestGenerateGrid() 156 | { 157 | return createNewRequest(REQUEST_GENERATE_GRID); 158 | } 159 | 160 | void requestGenerateGridHandler(struct physicsThread_s* p, request_s* r) 161 | { 162 | if(!p || !r)return; 163 | 164 | generateGrid(NULL); 165 | } 166 | 167 | requestType_s requestTypes[NUM_REQUEST_TYPES]= { 168 | (requestType_s){requestCreateObbHandler, sizeof(requestCreateObbData_s)}, // REQUEST_CREATE_OBB 169 | (requestType_s){requestResetObbHandler, sizeof(requestResetObbData_s)}, // REQUEST_RESET_AAR 170 | (requestType_s){requestCreateAarHandler, sizeof(requestCreateAarData_s)}, // REQUEST_CREATE_AAR 171 | (requestType_s){requestGenerateGridHandler, 0}, // REQUEST_GENERATE_GRID 172 | }; 173 | 174 | //request 175 | void handleRequest(physicsThread_s* p, request_s* r) 176 | { 177 | if(!p || !r || r->type>=NUM_REQUEST_TYPES)return; 178 | 179 | requestTypes[r->type].handler(p,r); 180 | } 181 | 182 | //request queue 183 | void initRequestQueue(requestQueue_s* rq) 184 | { 185 | if(!rq)return; 186 | 187 | rq->first=rq->last=NULL; 188 | rq->length=0; 189 | } 190 | 191 | void queueRequest(requestQueue_s* rq, request_s* r) 192 | { 193 | if(!rq || !r)return; 194 | 195 | r->next=NULL; 196 | if(!rq->length)rq->first=rq->last=r; 197 | else rq->last=rq->last->next=r; 198 | rq->length++; 199 | } 200 | 201 | void appendRequestQueue(requestQueue_s* rq1, requestQueue_s* rq2) 202 | { 203 | if(!rq1 || !rq2 || !rq2->length)return; 204 | 205 | if(!rq1->length)*rq1=*rq2; 206 | else{ 207 | rq1->last->next=rq2->first; 208 | rq1->last=rq2->last; 209 | rq1->length+=rq2->length; 210 | } 211 | rq2->length=0;rq2->first=rq2->last=NULL; 212 | } 213 | 214 | request_s* unqueueRequest(requestQueue_s* rq) 215 | { 216 | if(!rq || !rq->length)return NULL; 217 | 218 | request_s* r=rq->first; 219 | if(rq->length==1)rq->first=rq->last=NULL; 220 | else rq->first=r->next; 221 | r->next=NULL; 222 | rq->length--; 223 | 224 | return r; 225 | } 226 | -------------------------------------------------------------------------------- /source/game/cubes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds.h> 4 | #include "game/cubes.h" 5 | #include "game/emancipation.h" 6 | #include "gfx/gs.h" 7 | 8 | cubeDispenser_s cubeDispenser[NUMCUBEDISPENSERS]; 9 | md2_model_t cubeModel, cubeDispenserModel; 10 | texture_s storageCubeTexture, companionCubeTexture, cubeDispenserTexture; 11 | md2_instance_t storageCubeModelInstance, companionCubeModelInstance; 12 | 13 | void initCubes(void) 14 | { 15 | int i; 16 | for(i=0;imodelInstance, &cubeDispenserModel, &cubeDispenserTexture); 49 | 50 | cd->openingRectangle=NULL; 51 | 52 | {//for collisions 53 | rectangle_s rec; 54 | rectangle_s* recp; 55 | rec.material=NULL; 56 | 57 | rec.position=vaddi(pos,vect3Di(-1,-8,1)); 58 | rec.size=vect3Di(2,0,-2); 59 | rec.normal=vect3Df(0,(1),0); 60 | recp=addRoomRectangle(r, rec); 61 | if(recp){recp->hide=true;recp->collides=true;} 62 | cd->openingRectangle=recp; 63 | 64 | rec.position=vaddi(pos,vect3Di(-1,-8,-1)); 65 | rec.size=vect3Di(2,8,0); 66 | rec.normal=vect3Df(0,0,-(1)); 67 | recp=addRoomRectangle(r, rec); 68 | if(recp){recp->hide=true;recp->collides=true;} 69 | 70 | rec.position=vaddi(pos,vect3Di(-1,0,1)); 71 | rec.size=vect3Di(2,-8,0); 72 | rec.normal=vect3Df(0,0,(1)); 73 | recp=addRoomRectangle(r, rec); 74 | if(recp){recp->hide=true;recp->collides=true;} 75 | 76 | rec.position=vaddi(pos,vect3Di(-1,-8,-1)); 77 | rec.size=vect3Di(0,8,2); 78 | rec.normal=vect3Df(-(1),0,0); 79 | recp=addRoomRectangle(r, rec); 80 | if(recp){recp->hide=true;recp->collides=true;} 81 | 82 | rec.position=vaddi(pos,vect3Di(1,0,-1)); 83 | rec.size=vect3Di(0,-8,2); 84 | rec.normal=vect3Df((1),0,0); 85 | recp=addRoomRectangle(r, rec); 86 | if(recp){recp->hide=true;recp->collides=true;} 87 | } 88 | 89 | // pos=vect3Di(pos.x+r->position.x, pos.y, pos.z+r->position.y); 90 | cd->position=convertRectangleVector(pos); 91 | 92 | cd->companion=companion; 93 | cd->currentCube=NULL; 94 | 95 | md2InstanceChangeAnimation(&cd->modelInstance,0,false); 96 | 97 | cd->used=true; 98 | 99 | initActivatableObject(&cd->ao); 100 | cd->ao.active=true; 101 | } 102 | 103 | cubeDispenser_s* createCubeDispenser(room_s* r, vect3Di_s pos, bool companion) 104 | { 105 | if(!r)return NULL; 106 | 107 | int i; 108 | for(i=0;iposition.x,cd->position.y,cd->position.z); 126 | md2InstanceDraw(&cd->modelInstance); 127 | gsPopMatrix(); 128 | } 129 | 130 | void drawCubeDispensers(void) 131 | { 132 | int i; 133 | for(i=0;icurrentCube)physicsResetObb(cd->currentCube, vaddf(cd->position, vect3Df(0.0f, -2.0f, 0.0f)), vect3Df(1.0f, 1.0f, 1.0f), (cd->companion)?(&companionCubeModelInstance):(&storageCubeModelInstance), 1.0f, 0.0f); 144 | md2InstanceChangeAnimation(&cd->modelInstance,1,true); 145 | } 146 | 147 | extern OBB_s* gravityGunObject; 148 | 149 | void resetDispenserCube(OBB_s* o) 150 | { 151 | if(!o)return; 152 | 153 | if(gravityGunObject==o)gravityGunObject=NULL; 154 | 155 | int i; 156 | for(i=0; icurrentCube && !cd->currentCube->used)cd->currentCube=NULL; 171 | if(cd->ao.active && !cd->ao.oldActive) 172 | { 173 | if(!cd->currentCube) 174 | { 175 | physicsCreateObb(&cd->currentCube, vaddf(cd->position, vect3Df(0.0f, -2.0f, 0.0f)), vect3Df(1.0f, 1.0f, 1.0f), (cd->companion)?(&companionCubeModelInstance):(&storageCubeModelInstance), 1.0f, 0.0f); 176 | }else{ 177 | createEmancipator(cd->currentCube->modelInstance,cd->currentCube->position,cd->currentCube->transformationMatrix); 178 | if(cd->currentCube==gravityGunObject)gravityGunObject=NULL; 179 | resetCubeDispenserCube(cd); 180 | } 181 | md2InstanceChangeAnimation(&cd->modelInstance,1,true); 182 | } 183 | 184 | md2InstanceUpdate(&cd->modelInstance); 185 | cd->ao.oldActive = cd->ao.active; 186 | } 187 | 188 | void updateCubeDispensers(void) 189 | { 190 | int i; 191 | for(i=0;i 2 | #include <3ds.h> 3 | #include "game/material.h" 4 | #include "game/room.h" 5 | #include "utils/iniparser.h" 6 | 7 | material_s materials[NUMMATERIALS]; 8 | material_s* defaultMaterial; 9 | materialSlice_s materialSlices[NUMMATERIALSLICES]; 10 | materialSlice_s* defaultMaterialSlice; 11 | 12 | void initMaterials(void) 13 | { 14 | int i; 15 | for(i=0;iused=false; 19 | m->id=i; 20 | m->top=m->bottom=m->side=NULL; 21 | } 22 | for(i=0;iused=false; 26 | ms->id=i; 27 | ms->img=NULL; 28 | } 29 | defaultMaterial=createMaterial(); 30 | defaultMaterialSlice=createMaterialSlice(); 31 | loadMaterialSlice(defaultMaterialSlice, "default.png"); 32 | } 33 | 34 | materialSlice_s* createMaterialSlice() 35 | { 36 | int i; 37 | for(i=0;iused=true; 43 | ms->img=NULL; 44 | return ms; 45 | } 46 | } 47 | return NULL; 48 | } 49 | 50 | material_s* createMaterial() 51 | { 52 | int i; 53 | for(i=0;iused=true; 59 | m->top=m->bottom=m->side=NULL; 60 | return m; 61 | } 62 | } 63 | return NULL; 64 | } 65 | 66 | void loadMaterialSlice(materialSlice_s* ms, char* filename) 67 | { 68 | if(ms) 69 | { 70 | ms->img=textureCreate(filename, GPU_TEXTURE_MAG_FILTER(GPU_LINEAR)|GPU_TEXTURE_MIN_FILTER(GPU_LINEAR)|GPU_TEXTURE_WRAP_S(GPU_REPEAT)|GPU_TEXTURE_WRAP_T(GPU_REPEAT), 10); 71 | ms->align=false; 72 | ms->factorX=1; 73 | ms->factorY=1; 74 | } 75 | } 76 | 77 | void loadMaterialSlices(char* filename) 78 | { 79 | dictionary* dic=iniparser_load(filename); 80 | int i=0; 81 | char* r; 82 | char key[255]; 83 | sprintf(key,"slice%d:texture",i); 84 | while((r=dictionary_get(dic, key, NULL))) 85 | { 86 | materialSlice_s* ms=createMaterialSlice(); 87 | loadMaterialSlice(ms,r); 88 | printf("loaded %d : %s",i,r); 89 | 90 | int k=0; 91 | sprintf(key,"slice%d:align",i); 92 | sscanf(dictionary_get(dic, key, "0"),"%d",&k); 93 | ms->align=(k!=0); 94 | sprintf(key,"slice%d:factor",i); 95 | sscanf(dictionary_get(dic, key, "1"),"%d",&k); 96 | ms->factorX=k; 97 | ms->factorY=k; 98 | 99 | { 100 | char def[16]; 101 | sprintf(def,"%d",ms->factorX); 102 | sprintf(key,"slice%d:factorx",i); 103 | sscanf(dictionary_get(dic, key, def),"%d",&k); 104 | ms->factorX=k; 105 | sprintf(key,"slice%d:factory",i); 106 | sscanf(dictionary_get(dic, key, def),"%d",&k); 107 | ms->factorY=k; 108 | } 109 | 110 | // if(!ms->img){break;} 111 | i++; 112 | sprintf(key,"slice%d:texture",i); 113 | } 114 | iniparser_freedict(dic); 115 | } 116 | 117 | void loadMaterials(char* filename) 118 | { 119 | dictionary* dic=iniparser_load(filename); 120 | int i=0; 121 | char *r1, *r2, *r3; 122 | char key1[255],key2[255],key3[255]; 123 | sprintf(key1,"material%d:top",i); 124 | sprintf(key2,"material%d:side",i); 125 | sprintf(key3,"material%d:bottom",i); 126 | (r1=dictionary_get(dic, key1, NULL));(r2=dictionary_get(dic, key2, NULL));(r3=dictionary_get(dic, key3, NULL)); 127 | while(r1||r2||r3) 128 | { 129 | material_s* m=createMaterial(); 130 | if(!m){break;} 131 | if(r1) 132 | { 133 | int k; 134 | sscanf(r1,"%d",&k); 135 | m->top=&materialSlices[k+1]; 136 | } 137 | if(r2) 138 | { 139 | int k; 140 | sscanf(r2,"%d",&k); 141 | m->side=&materialSlices[k+1]; 142 | } 143 | if(r3) 144 | { 145 | int k; 146 | sscanf(r3,"%d",&k); 147 | m->bottom=&materialSlices[k+1]; 148 | } 149 | i++; 150 | sprintf(key1,"material%d:top",i); 151 | sprintf(key2,"material%d:side",i); 152 | sprintf(key3,"material%d:bottom",i); 153 | r1=dictionary_get(dic, key1, NULL);r2=dictionary_get(dic, key2, NULL);r3=dictionary_get(dic, key3, NULL); 154 | } 155 | iniparser_freedict(dic); 156 | } 157 | 158 | material_s* getMaterial(u16 i) 159 | { 160 | if(i<0 || i>NUMMATERIALS)i=0; 161 | return &materials[i]; 162 | } 163 | 164 | void getTextureCoordSlice(materialSlice_s* ms, rectangle_s* rec, vect3Di_s* v) 165 | { 166 | if(!v)return; 167 | if(!ms)ms=defaultMaterialSlice; 168 | if(!ms->img)return; 169 | 170 | vect3Di_s p1=vect3Di(0,0,0), p2; 171 | 172 | float heightRatio=(HEIGHTUNIT_FLOAT / (TILESIZE_FLOAT*2)) / ms->factorY; 173 | 174 | if(!rec->size.x) 175 | { 176 | p1=vect3Di((ms->img->width * rec->position.z) / ms->factorX, ms->img->height * rec->position.y * heightRatio, 0); 177 | p2=vect3Di((ms->img->width * rec->size.z) / ms->factorX, ms->img->height * rec->size.y * heightRatio, 0); 178 | }else if(!rec->size.y) 179 | { 180 | p1=vect3Di((ms->img->width * rec->position.z) / ms->factorX, (ms->img->height * rec->position.x) / ms->factorX, 0); 181 | p2=vect3Di((ms->img->width * rec->size.z) / ms->factorX, (ms->img->height * rec->size.x) / ms->factorX, 0); 182 | }else 183 | { 184 | p1=vect3Di(ms->img->width * rec->position.y * heightRatio, (ms->img->height * rec->position.x) / ms->factorX, 0); 185 | p2=vect3Di(ms->img->width * rec->size.y * heightRatio, (ms->img->height * rec->size.x) / ms->factorX, 0); 186 | } 187 | 188 | p1.x%=(ms->img->width); 189 | p1.y%=(ms->img->height); 190 | 191 | p2=vaddi(p1,p2); 192 | 193 | v[0]=vect3Di(p1.x, p1.y, 0); 194 | v[1]=vect3Di(p1.x, p2.y, 0); 195 | v[2]=vect3Di(p2.x, p2.y, 0); 196 | v[3]=vect3Di(p2.x, p1.y, 0); 197 | } 198 | 199 | void getMaterialTextureCoord(rectangle_s* rec, vect3Di_s* v) 200 | { 201 | if(!rec || !rec->material || !v)return; 202 | 203 | materialSlice_s* ms=rec->material->side; 204 | 205 | if(!rec->size.y) 206 | { 207 | if(rec->normal.y>0)ms=rec->material->top; 208 | else ms=rec->material->bottom; 209 | } 210 | 211 | getTextureCoordSlice(ms, rec, v); 212 | } 213 | 214 | texture_s* getRectangleTexture(rectangle_s* rec) 215 | { 216 | if(!rec)return NULL; 217 | material_s* m=rec->material; 218 | if(!m)m=defaultMaterial; 219 | 220 | materialSlice_s* ms=rec->material->side; 221 | if(!rec->size.y) 222 | { 223 | if(rec->normal.y>0)ms=rec->material->top; 224 | else ms=rec->material->bottom; 225 | } 226 | if(!ms)ms=defaultMaterialSlice; 227 | 228 | return ms->img; 229 | } 230 | -------------------------------------------------------------------------------- /light/source/light_math.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "light_math.h" 5 | 6 | void loadIdentity44(float* m) 7 | { 8 | if(!m)return; 9 | 10 | memset(m, 0x00, 16*4); 11 | m[0]=m[5]=m[10]=m[15]=1.0f; 12 | } 13 | 14 | void transposeMatrix33(float* m1, float* m2) //3x3 15 | { 16 | int i, j; 17 | for(i=0;i<3;i++)for(j=0;j<3;j++)m2[j+i*3]=m1[i+j*3]; 18 | } 19 | 20 | void multMatrix33(float* m1, float* m2, float* m) //3x3 21 | { 22 | int i, j; 23 | for(i=0;i<3;i++)for(j=0;j<3;j++)m[j+i*3]=(m1[0+i*3]*m2[j+0*3])+(m1[1+i*3]*m2[j+1*3])+(m1[2+i*3]*m2[j+2*3]); 24 | } 25 | 26 | void addMatrix33(float* m1, float* m2, float* m) //3x3 27 | { 28 | int i, j; 29 | for(i=0;i<3;i++)for(j=0;j<3;j++)m[j+i*3]=m1[j+i*3]+m2[j+i*3]; 30 | } 31 | 32 | void projectVectorPlane(vect3Df_s* v, vect3Df_s n) 33 | { 34 | if(!v)return; 35 | float r=vdotf(*v,n); 36 | *v=vsubf(*v,vmulf(n,r)); 37 | } 38 | 39 | void fixMatrix33(float* m) //3x3 40 | { 41 | if(!m)return; 42 | vect3Df_s x=vect3Df(m[0],m[3],m[6]); 43 | vect3Df_s y=vect3Df(m[1],m[4],m[7]); 44 | vect3Df_s z=vect3Df(m[2],m[5],m[8]); 45 | 46 | projectVectorPlane(&x,y); 47 | projectVectorPlane(&z,y); 48 | projectVectorPlane(&z,x); 49 | 50 | x=vnormf(x); 51 | y=vnormf(y); 52 | z=vnormf(z); 53 | 54 | m[0]=x.x;m[3]=x.y;m[6]=x.z; 55 | m[1]=y.x;m[4]=y.y;m[7]=y.z; 56 | m[2]=z.x;m[5]=z.y;m[8]=z.z; 57 | } 58 | 59 | void transposeMatrix44(float* m1, float* m2) //4x4 60 | { 61 | int i, j; 62 | for(i=0;i<4;i++)for(j=0;j<4;j++)m2[j+i*4]=m1[i+j*4]; 63 | } 64 | 65 | void multMatrix44(float* m1, float* m2, float* m) //4x4 66 | { 67 | int i, j; 68 | 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]); 69 | } 70 | 71 | vect3Df_s multMatrix44Vect3(float* m, vect3Df_s v, bool transpose) 72 | { 73 | if(!transpose) return vect3Df(vdotf(v, vect3Df(m[0+0*4], m[1+0*4], m[2+0*4])), vdotf(v, vect3Df(m[0+1*4], m[1+1*4], m[2+1*4])), vdotf(v, vect3Df(m[0+2*4], m[1+2*4], m[2+2*4]))); 74 | else return vect3Df(vdotf(v, vect3Df(m[0+0*4], m[0+1*4], m[0+2*4])), vdotf(v, vect3Df(m[1+0*4], m[1+1*4], m[1+2*4])), vdotf(v, vect3Df(m[2+0*4], m[2+1*4], m[2+2*4]))); 75 | } 76 | 77 | vect4Df_s multMatrix44Vect4(float* m, vect4Df_s v, bool transpose) 78 | { 79 | if(!transpose) return vect4Df(vdotf4(v, vect4Df(m[0+0*4], m[1+0*4], m[2+0*4], m[3+0*4])), vdotf4(v, vect4Df(m[0+1*4], m[1+1*4], m[2+1*4], m[3+1*4])), vdotf4(v, vect4Df(m[0+2*4], m[1+2*4], m[2+2*4], m[3+2*4])), vdotf4(v, vect4Df(m[0+3*4], m[1+3*4], m[2+3*4], m[3+3*4]))); 80 | else return vect4Df(vdotf4(v, vect4Df(m[0+0*4], m[0+1*4], m[0+2*4], m[0+3*4])), vdotf4(v, vect4Df(m[1+0*4], m[1+1*4], m[1+2*4], m[1+3*4])), vdotf4(v, vect4Df(m[2+0*4], m[2+1*4], m[2+2*4], m[2+3*4])), vdotf4(v, vect4Df(m[3+0*4], m[3+1*4], m[3+2*4], m[3+3*4]))); 81 | } 82 | 83 | void translateMatrix(float* tm, float x, float y, float z) 84 | { 85 | float rm[16], m[16]; 86 | 87 | loadIdentity44(rm); 88 | rm[3]=x; 89 | rm[7]=y; 90 | rm[11]=z; 91 | 92 | multMatrix44(tm,rm,m); 93 | memcpy(tm,m,16*sizeof(float)); 94 | } 95 | 96 | // 00 01 02 03 97 | // 04 05 06 07 98 | // 08 09 10 11 99 | // 12 13 14 15 100 | 101 | void rotateMatrixX(float* tm, float x, bool r) 102 | { 103 | float rm[16], m[16]; 104 | memset(rm, 0x00, 16*4); 105 | rm[0]=1.0f; 106 | rm[5]=cos(x); 107 | rm[6]=sin(x); 108 | rm[9]=-sin(x); 109 | rm[10]=cos(x); 110 | rm[15]=1.0f; 111 | if(!r)multMatrix44(tm,rm,m); 112 | else multMatrix44(rm,tm,m); 113 | memcpy(tm,m,16*sizeof(float)); 114 | } 115 | 116 | void rotateMatrixY(float* tm, float x, bool r) 117 | { 118 | float rm[16], m[16]; 119 | memset(rm, 0x00, 16*4); 120 | rm[0]=cos(x); 121 | rm[2]=sin(x); 122 | rm[5]=1.0f; 123 | rm[8]=-sin(x); 124 | rm[10]=cos(x); 125 | rm[15]=1.0f; 126 | if(!r)multMatrix44(tm,rm,m); 127 | else multMatrix44(rm,tm,m); 128 | memcpy(tm,m,16*sizeof(float)); 129 | } 130 | 131 | void rotateMatrixZ(float* tm, float x, bool r) 132 | { 133 | float rm[16], m[16]; 134 | memset(rm, 0x00, 16*4); 135 | rm[0]=cos(x); 136 | rm[1]=sin(x); 137 | rm[4]=-sin(x); 138 | rm[5]=cos(x); 139 | rm[10]=1.0f; 140 | rm[15]=1.0f; 141 | if(!r)multMatrix44(tm,rm,m); 142 | else multMatrix44(rm,tm,m); 143 | memcpy(tm,m,16*sizeof(float)); 144 | } 145 | 146 | void rotateMatrixAxis(float* tm, float x, vect3Df_s a, bool r) 147 | { 148 | float rm[16], m[16]; 149 | 150 | float cosval=cos(x); 151 | float sinval=sin(x); 152 | float onemcosval=1.0f-cosval; 153 | 154 | memset(rm, 0x00, sizeof(rm)); 155 | 156 | rm[0]=cosval + a.x*a.x*onemcosval; 157 | rm[1]=a.x*a.y*onemcosval-a.z*sinval; 158 | rm[2]=a.x*a.z*onemcosval + a.y*sinval; 159 | 160 | rm[4]=a.x*a.y*onemcosval + a.z*sinval; 161 | rm[5]=cosval + a.y*a.y*onemcosval; 162 | rm[6]=a.y*a.z*onemcosval-a.x*sinval; 163 | 164 | rm[8]=a.x*a.z*onemcosval-a.y*sinval; 165 | rm[9]=a.y*a.z*onemcosval + a.x*sinval; 166 | rm[10]=cosval + a.z*a.z*onemcosval; 167 | 168 | rm[15]=1.0f; 169 | 170 | if(r)multMatrix44(rm,tm,m); 171 | else multMatrix44(tm,rm,m); 172 | memcpy(tm,m,16*sizeof(float)); 173 | } 174 | 175 | void scaleMatrix(float* tm, float x, float y, float z) 176 | { 177 | tm[0]*=x; tm[4]*=x; tm[8]*=x; tm[12]*=x; 178 | tm[1]*=y; tm[5]*=y; tm[9]*=y; tm[13]*=y; 179 | tm[2]*=z; tm[6]*=z; tm[10]*=z; tm[14]*=z; 180 | } 181 | 182 | void initProjectionMatrix(float* m, float fovy, float aspect, float near, float far) 183 | { 184 | float top = near*tan(fovy/2); 185 | float right = (top*aspect); 186 | 187 | float mp[4*4]; 188 | 189 | mp[0x0] = near/right; 190 | mp[0x1] = 0.0f; 191 | mp[0x2] = 0.0f; 192 | mp[0x3] = 0.0f; 193 | 194 | mp[0x4] = 0.0f; 195 | mp[0x5] = near/top; 196 | mp[0x6] = 0.0f; 197 | mp[0x7] = 0.0f; 198 | 199 | mp[0x8] = 0.0f; 200 | mp[0x9] = 0.0f; 201 | mp[0xA] = -(far+near)/(far-near); 202 | mp[0xB] = -2.0f*(far*near)/(far-near); 203 | 204 | mp[0xC] = 0.0f; 205 | mp[0xD] = 0.0f; 206 | mp[0xE] = -1.0f; 207 | mp[0xF] = 0.0f; 208 | 209 | float mp2[4*4]; 210 | loadIdentity44(mp2); 211 | mp2[0xA]=0.5; 212 | mp2[0xB]=-0.5; 213 | 214 | multMatrix44(mp2, mp, m); 215 | 216 | rotateMatrixZ(m, M_PI/2, false); //because framebuffer is sideways... 217 | } 218 | 219 | vect3Df_s getMatrixColumn(float* m, u8 i) 220 | { 221 | if(!m || i>=4)return vect3Df(0,0,0); 222 | return vect3Df(m[0+i*4],m[1+i*4],m[2+i*4]); 223 | } 224 | 225 | vect3Df_s getMatrixRow(float* m, u8 i) 226 | { 227 | if(!m || i>=4)return vect3Df(0,0,0); 228 | return vect3Df(m[i+0*4],m[i+1*4],m[i+2*4]); 229 | } 230 | 231 | vect4Df_s getMatrixColumn4(float* m, u8 i) 232 | { 233 | if(!m || i>=4)return vect4Df(0,0,0,0); 234 | return vect4Df(m[0+i*4],m[1+i*4],m[2+i*4],m[3+i*4]); 235 | } 236 | 237 | vect4Df_s getMatrixRow4(float* m, u8 i) 238 | { 239 | if(!m || i>=4)return vect4Df(0,0,0,0); 240 | return vect4Df(m[i+0*4],m[i+1*4],m[i+2*4],m[i+3*4]); 241 | } 242 | -------------------------------------------------------------------------------- /source/utils/math.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "utils/math.h" 5 | 6 | void loadIdentity44(float* m) 7 | { 8 | if(!m)return; 9 | 10 | memset(m, 0x00, 16*4); 11 | m[0]=m[5]=m[10]=m[15]=1.0f; 12 | } 13 | 14 | void loadIdentity33(float* m) 15 | { 16 | if(!m)return; 17 | 18 | memset(m, 0x00, 9*4); 19 | m[0]=m[4]=m[8]=1.0f; 20 | } 21 | 22 | void transposeMatrix33(float* m1, float* m2) //3x3 23 | { 24 | int i, j; 25 | for(i=0;i<3;i++)for(j=0;j<3;j++)m2[j+i*3]=m1[i+j*3]; 26 | } 27 | 28 | void multMatrix33(float* m1, float* m2, float* m) //3x3 29 | { 30 | int i, j; 31 | for(i=0;i<3;i++)for(j=0;j<3;j++)m[j+i*3]=(m1[0+i*3]*m2[j+0*3])+(m1[1+i*3]*m2[j+1*3])+(m1[2+i*3]*m2[j+2*3]); 32 | } 33 | 34 | void addMatrix33(float* m1, float* m2, float* m) //3x3 35 | { 36 | int i, j; 37 | for(i=0;i<3;i++)for(j=0;j<3;j++)m[j+i*3]=m1[j+i*3]+m2[j+i*3]; 38 | } 39 | 40 | void projectVectorPlane(vect3Df_s* v, vect3Df_s n) 41 | { 42 | if(!v)return; 43 | float r=vdotf(*v,n); 44 | *v=vsubf(*v,vmulf(n,r)); 45 | } 46 | 47 | void fixMatrix33(float* m) //3x3 48 | { 49 | if(!m)return; 50 | vect3Df_s x=vect3Df(m[0],m[3],m[6]); 51 | vect3Df_s y=vect3Df(m[1],m[4],m[7]); 52 | vect3Df_s z=vect3Df(m[2],m[5],m[8]); 53 | 54 | projectVectorPlane(&x,y); 55 | projectVectorPlane(&z,y); 56 | projectVectorPlane(&z,x); 57 | 58 | x=vnormf(x); 59 | y=vnormf(y); 60 | z=vnormf(z); 61 | 62 | m[0]=x.x;m[3]=x.y;m[6]=x.z; 63 | m[1]=y.x;m[4]=y.y;m[7]=y.z; 64 | m[2]=z.x;m[5]=z.y;m[8]=z.z; 65 | } 66 | 67 | void transposeMatrix44(float* m1, float* m2) //4x4 68 | { 69 | int i, j; 70 | for(i=0;i<4;i++)for(j=0;j<4;j++)m2[j+i*4]=m1[i+j*4]; 71 | } 72 | 73 | void multMatrix44(float* m1, float* m2, float* m) //4x4 74 | { 75 | int i, j; 76 | 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]); 77 | } 78 | 79 | vect3Df_s multMatrix44Vect3(float* m, vect3Df_s v, bool transpose) 80 | { 81 | if(!transpose) return vect3Df(vdotf(v, vect3Df(m[0+0*4], m[1+0*4], m[2+0*4])), vdotf(v, vect3Df(m[0+1*4], m[1+1*4], m[2+1*4])), vdotf(v, vect3Df(m[0+2*4], m[1+2*4], m[2+2*4]))); 82 | else return vect3Df(vdotf(v, vect3Df(m[0+0*4], m[0+1*4], m[0+2*4])), vdotf(v, vect3Df(m[1+0*4], m[1+1*4], m[1+2*4])), vdotf(v, vect3Df(m[2+0*4], m[2+1*4], m[2+2*4]))); 83 | } 84 | 85 | vect4Df_s multMatrix44Vect4(float* m, vect4Df_s v, bool transpose) 86 | { 87 | if(!transpose) return vect4Df(vdotf4(v, vect4Df(m[0+0*4], m[1+0*4], m[2+0*4], m[3+0*4])), vdotf4(v, vect4Df(m[0+1*4], m[1+1*4], m[2+1*4], m[3+1*4])), vdotf4(v, vect4Df(m[0+2*4], m[1+2*4], m[2+2*4], m[3+2*4])), vdotf4(v, vect4Df(m[0+3*4], m[1+3*4], m[2+3*4], m[3+3*4]))); 88 | else return vect4Df(vdotf4(v, vect4Df(m[0+0*4], m[0+1*4], m[0+2*4], m[0+3*4])), vdotf4(v, vect4Df(m[1+0*4], m[1+1*4], m[1+2*4], m[1+3*4])), vdotf4(v, vect4Df(m[2+0*4], m[2+1*4], m[2+2*4], m[2+3*4])), vdotf4(v, vect4Df(m[3+0*4], m[3+1*4], m[3+2*4], m[3+3*4]))); 89 | } 90 | 91 | void translateMatrix(float* tm, float x, float y, float z) 92 | { 93 | float rm[16], m[16]; 94 | 95 | loadIdentity44(rm); 96 | rm[3]=x; 97 | rm[7]=y; 98 | rm[11]=z; 99 | 100 | multMatrix44(tm,rm,m); 101 | memcpy(tm,m,16*sizeof(float)); 102 | } 103 | 104 | // 00 01 02 03 105 | // 04 05 06 07 106 | // 08 09 10 11 107 | // 12 13 14 15 108 | 109 | void rotateMatrixX(float* tm, float x, bool r) 110 | { 111 | float rm[16], m[16]; 112 | memset(rm, 0x00, 16*4); 113 | rm[0]=1.0f; 114 | rm[5]=cos(x); 115 | rm[6]=sin(x); 116 | rm[9]=-sin(x); 117 | rm[10]=cos(x); 118 | rm[15]=1.0f; 119 | if(!r)multMatrix44(tm,rm,m); 120 | else multMatrix44(rm,tm,m); 121 | memcpy(tm,m,16*sizeof(float)); 122 | } 123 | 124 | void rotateMatrixY(float* tm, float x, bool r) 125 | { 126 | float rm[16], m[16]; 127 | memset(rm, 0x00, 16*4); 128 | rm[0]=cos(x); 129 | rm[2]=sin(x); 130 | rm[5]=1.0f; 131 | rm[8]=-sin(x); 132 | rm[10]=cos(x); 133 | rm[15]=1.0f; 134 | if(!r)multMatrix44(tm,rm,m); 135 | else multMatrix44(rm,tm,m); 136 | memcpy(tm,m,16*sizeof(float)); 137 | } 138 | 139 | void rotateMatrixZ(float* tm, float x, bool r) 140 | { 141 | float rm[16], m[16]; 142 | memset(rm, 0x00, 16*4); 143 | rm[0]=cos(x); 144 | rm[1]=sin(x); 145 | rm[4]=-sin(x); 146 | rm[5]=cos(x); 147 | rm[10]=1.0f; 148 | rm[15]=1.0f; 149 | if(!r)multMatrix44(tm,rm,m); 150 | else multMatrix44(rm,tm,m); 151 | memcpy(tm,m,16*sizeof(float)); 152 | } 153 | 154 | void rotateMatrixAxis(float* tm, float x, vect3Df_s a, bool r) 155 | { 156 | float rm[16], m[16]; 157 | 158 | float cosval=cos(x); 159 | float sinval=sin(x); 160 | float onemcosval=1.0f-cosval; 161 | 162 | memset(rm, 0x00, sizeof(rm)); 163 | 164 | rm[0]=cosval + a.x*a.x*onemcosval; 165 | rm[1]=a.x*a.y*onemcosval-a.z*sinval; 166 | rm[2]=a.x*a.z*onemcosval + a.y*sinval; 167 | 168 | rm[4]=a.x*a.y*onemcosval + a.z*sinval; 169 | rm[5]=cosval + a.y*a.y*onemcosval; 170 | rm[6]=a.y*a.z*onemcosval-a.x*sinval; 171 | 172 | rm[8]=a.x*a.z*onemcosval-a.y*sinval; 173 | rm[9]=a.y*a.z*onemcosval + a.x*sinval; 174 | rm[10]=cosval + a.z*a.z*onemcosval; 175 | 176 | rm[15]=1.0f; 177 | 178 | if(r)multMatrix44(rm,tm,m); 179 | else multMatrix44(tm,rm,m); 180 | memcpy(tm,m,16*sizeof(float)); 181 | } 182 | 183 | void scaleMatrix(float* tm, float x, float y, float z) 184 | { 185 | tm[0]*=x; tm[4]*=x; tm[8]*=x; tm[12]*=x; 186 | tm[1]*=y; tm[5]*=y; tm[9]*=y; tm[13]*=y; 187 | tm[2]*=z; tm[6]*=z; tm[10]*=z; tm[14]*=z; 188 | } 189 | 190 | void initProjectionMatrix(float* m, float fovy, float aspect, float near, float far) 191 | { 192 | float top = near*tan(fovy/2); 193 | float right = (top*aspect); 194 | 195 | float mp[4*4]; 196 | 197 | mp[0x0] = near/right; 198 | mp[0x1] = 0.0f; 199 | mp[0x2] = 0.0f; 200 | mp[0x3] = 0.0f; 201 | 202 | mp[0x4] = 0.0f; 203 | mp[0x5] = near/top; 204 | mp[0x6] = 0.0f; 205 | mp[0x7] = 0.0f; 206 | 207 | mp[0x8] = 0.0f; 208 | mp[0x9] = 0.0f; 209 | mp[0xA] = -(far+near)/(far-near); 210 | mp[0xB] = -2.0f*(far*near)/(far-near); 211 | 212 | mp[0xC] = 0.0f; 213 | mp[0xD] = 0.0f; 214 | mp[0xE] = -1.0f; 215 | mp[0xF] = 0.0f; 216 | 217 | float mp2[4*4]; 218 | loadIdentity44(mp2); 219 | mp2[0xA]=0.5; 220 | mp2[0xB]=-0.5; 221 | 222 | multMatrix44(mp2, mp, m); 223 | 224 | rotateMatrixZ(m, M_PI/2, false); //because framebuffer is sideways... 225 | } 226 | 227 | vect3Df_s getMatrixColumn(float* m, u8 i) 228 | { 229 | if(!m || i>=4)return vect3Df(0,0,0); 230 | return vect3Df(m[0+i*4],m[1+i*4],m[2+i*4]); 231 | } 232 | 233 | vect3Df_s getMatrixRow(float* m, u8 i) 234 | { 235 | if(!m || i>=4)return vect3Df(0,0,0); 236 | return vect3Df(m[i+0*4],m[i+1*4],m[i+2*4]); 237 | } 238 | 239 | vect4Df_s getMatrixColumn4(float* m, u8 i) 240 | { 241 | if(!m || i>=4)return vect4Df(0,0,0,0); 242 | return vect4Df(m[0+i*4],m[1+i*4],m[2+i*4],m[3+i*4]); 243 | } 244 | 245 | vect4Df_s getMatrixRow4(float* m, u8 i) 246 | { 247 | if(!m || i>=4)return vect4Df(0,0,0,0); 248 | return vect4Df(m[i+0*4],m[i+1*4],m[i+2*4],m[i+3*4]); 249 | } 250 | -------------------------------------------------------------------------------- /include/utils/dictionary.h: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------------------*/ 3 | /** 4 | @file dictionary.h 5 | @author N. Devillard 6 | @date Sep 2007 7 | @version $Revision: 1.12 $ 8 | @brief Implements a dictionary for string variables. 9 | 10 | This module implements a simple dictionary object, i.e. a list 11 | of string/string associations. This object is useful to store e.g. 12 | informations retrieved from a configuration file (ini files). 13 | */ 14 | /*--------------------------------------------------------------------------*/ 15 | 16 | /* 17 | $Id: dictionary.h,v 1.12 2007-11-23 21:37:00 ndevilla Exp $ 18 | $Author: ndevilla $ 19 | $Date: 2007-11-23 21:37:00 $ 20 | $Revision: 1.12 $ 21 | */ 22 | 23 | #ifndef _DICTIONARY_H_ 24 | #define _DICTIONARY_H_ 25 | 26 | /*--------------------------------------------------------------------------- 27 | Includes 28 | ---------------------------------------------------------------------------*/ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | /*--------------------------------------------------------------------------- 36 | New types 37 | ---------------------------------------------------------------------------*/ 38 | 39 | 40 | /*-------------------------------------------------------------------------*/ 41 | /** 42 | @brief Dictionary object 43 | 44 | This object contains a list of string/string associations. Each 45 | association is identified by a unique string key. Looking up values 46 | in the dictionary is speeded up by the use of a (hopefully collision-free) 47 | hash function. 48 | */ 49 | /*-------------------------------------------------------------------------*/ 50 | typedef struct _dictionary_ { 51 | int n ; /** Number of entries in dictionary */ 52 | int size ; /** Storage size */ 53 | char ** val ; /** List of string values */ 54 | char ** key ; /** List of string keys */ 55 | unsigned * hash ; /** List of hash values for keys */ 56 | } dictionary ; 57 | 58 | 59 | /*--------------------------------------------------------------------------- 60 | Function prototypes 61 | ---------------------------------------------------------------------------*/ 62 | 63 | /*-------------------------------------------------------------------------*/ 64 | /** 65 | @brief Compute the hash key for a string. 66 | @param key Character string to use for key. 67 | @return 1 unsigned int on at least 32 bits. 68 | 69 | This hash function has been taken from an Article in Dr Dobbs Journal. 70 | This is normally a collision-free function, distributing keys evenly. 71 | The key is stored anyway in the struct so that collision can be avoided 72 | by comparing the key itself in last resort. 73 | */ 74 | /*--------------------------------------------------------------------------*/ 75 | unsigned dictionary_hash(char * key); 76 | 77 | /*-------------------------------------------------------------------------*/ 78 | /** 79 | @brief Create a new dictionary object. 80 | @param size Optional initial size of the dictionary. 81 | @return 1 newly allocated dictionary objet. 82 | 83 | This function allocates a new dictionary object of given size and returns 84 | it. If you do not know in advance (roughly) the number of entries in the 85 | dictionary, give size=0. 86 | */ 87 | /*--------------------------------------------------------------------------*/ 88 | dictionary * dictionary_new(int size); 89 | 90 | /*-------------------------------------------------------------------------*/ 91 | /** 92 | @brief Delete a dictionary object 93 | @param d dictionary object to deallocate. 94 | @return void 95 | 96 | Deallocate a dictionary object and all memory associated to it. 97 | */ 98 | /*--------------------------------------------------------------------------*/ 99 | void dictionary_del(dictionary * vd); 100 | 101 | /*-------------------------------------------------------------------------*/ 102 | /** 103 | @brief Get a value from a dictionary. 104 | @param d dictionary object to search. 105 | @param key Key to look for in the dictionary. 106 | @param def Default value to return if key not found. 107 | @return 1 pointer to internally allocated character string. 108 | 109 | This function locates a key in a dictionary and returns a pointer to its 110 | value, or the passed 'def' pointer if no such key can be found in 111 | dictionary. The returned character pointer points to data internal to the 112 | dictionary object, you should not try to free it or modify it. 113 | */ 114 | /*--------------------------------------------------------------------------*/ 115 | char * dictionary_get(dictionary * d, char * key, char * def); 116 | 117 | 118 | /*-------------------------------------------------------------------------*/ 119 | /** 120 | @brief Set a value in a dictionary. 121 | @param d dictionary object to modify. 122 | @param key Key to modify or add. 123 | @param val Value to add. 124 | @return int 0 if Ok, anything else otherwise 125 | 126 | If the given key is found in the dictionary, the associated value is 127 | replaced by the provided one. If the key cannot be found in the 128 | dictionary, it is added to it. 129 | 130 | It is Ok to provide a NULL value for val, but NULL values for the dictionary 131 | or the key are considered as errors: the function will return immediately 132 | in such a case. 133 | 134 | Notice that if you dictionary_set a variable to NULL, a call to 135 | dictionary_get will return a NULL value: the variable will be found, and 136 | its value (NULL) is returned. In other words, setting the variable 137 | content to NULL is equivalent to deleting the variable from the 138 | dictionary. It is not possible (in this implementation) to have a key in 139 | the dictionary without value. 140 | 141 | This function returns non-zero in case of failure. 142 | */ 143 | /*--------------------------------------------------------------------------*/ 144 | int dictionary_set(dictionary * vd, char * key, char * val); 145 | 146 | /*-------------------------------------------------------------------------*/ 147 | /** 148 | @brief Delete a key in a dictionary 149 | @param d dictionary object to modify. 150 | @param key Key to remove. 151 | @return void 152 | 153 | This function deletes a key in a dictionary. Nothing is done if the 154 | key cannot be found. 155 | */ 156 | /*--------------------------------------------------------------------------*/ 157 | void dictionary_unset(dictionary * d, char * key); 158 | 159 | 160 | /*-------------------------------------------------------------------------*/ 161 | /** 162 | @brief Dump a dictionary to an opened file pointer. 163 | @param d Dictionary to dump 164 | @param f Opened file pointer. 165 | @return void 166 | 167 | Dumps a dictionary onto an opened file pointer. Key pairs are printed out 168 | as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as 169 | output file pointers. 170 | */ 171 | /*--------------------------------------------------------------------------*/ 172 | void dictionary_dump(dictionary * d, FILE * out); 173 | 174 | #endif 175 | -------------------------------------------------------------------------------- /source/gfx/texture.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds.h> 4 | #include "gfx/texture.h" 5 | #include "gfx/lodepng.h" 6 | 7 | u8 tileOrder[] = {0,1,8,9,2,3,10,11,16,17,24,25,18,19,26,27,4,5,12,13,6,7,14,15,20,21,28,29,22,23,30,31,32,33,40,41,34,35,42,43,48,49,56,57,50,51,58,59,36,37,44,45,38,39,46,47,52,53,60,61,54,55,62,63}; 8 | 9 | texture_s textures[TEXTURES_NUM]; 10 | 11 | unsigned long htonl(unsigned long v) 12 | { 13 | u8* v2=(u8*)&v; 14 | return (v2[0]<<24)|(v2[1]<<16)|(v2[2]<<8)|(v2[3]); 15 | } 16 | int totaltextures; 17 | 18 | void textureInit() 19 | { 20 | int i; 21 | for(i=0; iused)return -1; 155 | if(mipmap < 0)return -1; 156 | 157 | totaltextures++; 158 | 159 | t->data=NULL; 160 | t->filename=NULL; 161 | t->format=GPU_RGBA8; 162 | 163 | u32* buffer; 164 | unsigned int error=lodepng_decode32_file((unsigned char**)&buffer, (unsigned int*)&t->width, (unsigned int*)&t->height, fn); 165 | if(error){printf("error %u: %s\n", error, lodepng_error_text(error)); return -2;} 166 | 167 | int l=0; for(l=0; !(t->height&(1<width&(1<l)mipmap=l; 170 | 171 | u32 size = 4*t->width*t->height; 172 | size = ((size - (size >> (2*(mipmap+1)))) * 4) / 3; //geometric progression 173 | t->data=linearMemAlign(size, 0x80); //textures need to be 0x80 byte aligned 174 | if(!t->data){free(buffer); return -3;} 175 | 176 | tileImage32(buffer, t->data, t->width, t->height); 177 | 178 | u32 offset = t->width*t->height; 179 | int level = 0; 180 | int w = t->width/2, h = t->height/2; 181 | for(level = 0; level < mipmap; level++) 182 | { 183 | downscaleImage((u8*)buffer, w, h); 184 | tileImage32(buffer, &t->data[offset], w, h); 185 | offset += w*h; 186 | w /= 2; h /= 2; 187 | } 188 | 189 | free(buffer); 190 | 191 | t->param=param; 192 | t->filename=malloc(strlen(fn)+1); 193 | if(t->filename)strcpy(t->filename, fn); 194 | 195 | t->mipmap=mipmap; 196 | t->used=true; 197 | 198 | printf("successfully read texture\n"); 199 | 200 | return 0; 201 | } 202 | 203 | int textureLoadBuffer(texture_s* t, u32* buffer, int width, int height, u32 param, int mipmap) 204 | { 205 | if(!buffer || !t || t->used)return -1; 206 | if(mipmap < 0)return -1; 207 | 208 | totaltextures++; 209 | 210 | t->data=NULL; 211 | t->filename=NULL; 212 | 213 | t->width = width; 214 | t->height = height; 215 | 216 | t->format = GPU_A8; 217 | 218 | int l=0; for(l=0; !(t->height&(1<width&(1<l)mipmap=l; 221 | 222 | u32 size = t->width*t->height; 223 | size = ((size - (size >> (2*(mipmap+1)))) * 4) / 3; //geometric progression 224 | // t->data=linearMemAlign(size, 0x80); //textures need to be 0x80 byte aligned 225 | t->data=linearMemAlign(size, 0x1000); //textures need to be 0x80 byte aligned (apparently not enough, likely depends on texture width, TODO : figure out alignment requirement) 226 | if(!t->data){return -3;} 227 | tileImage8(buffer, t->data, t->width, t->height); 228 | 229 | u32 offset = t->width*t->height; 230 | int level = 0; 231 | int w = t->width/2, h = t->height/2; 232 | for(level = 0; level < mipmap; level++) 233 | { 234 | downscaleImage8((u8*)buffer, w, h); 235 | tileImage8(buffer, &t->data[offset], w, h); 236 | offset += w*h; 237 | w /= 2; h /= 2; 238 | } 239 | 240 | t->param=param; 241 | 242 | t->mipmap=mipmap; 243 | t->used=true; 244 | 245 | printf("successfully made texture\n"); 246 | 247 | return 0; 248 | } 249 | 250 | void textureBind(texture_s* t, GPU_TEXUNIT unit) 251 | { 252 | if(!t)return; 253 | 254 | GPU_SetTexture(unit, (u32*)osConvertVirtToPhys((u32)t->data), t->width, t->height, t->param, t->format); 255 | GPUCMD_AddWrite(GPUREG_0084, t->mipmap<<16); 256 | } 257 | 258 | void textureFree(texture_s* t) 259 | { 260 | if(!t || !t->data)return; 261 | 262 | totaltextures--; 263 | 264 | linearFree(t->data); 265 | t->data = NULL; 266 | t->used = false; 267 | } 268 | --------------------------------------------------------------------------------