diff --git a/examples/loading/assign_transform_matrix/Makefile b/examples/loading/assign_transform_matrix/Makefile new file mode 100644 index 0000000..108ae50 --- /dev/null +++ b/examples/loading/assign_transform_matrix/Makefile @@ -0,0 +1,6 @@ +# This is a minimal makefile only used for the examples. If you want a makefile +# for your project, take one from the templates inside examples/templates. + +BINDIRS := data + +include ../../Makefile.example diff --git a/examples/loading/assign_transform_matrix/Makefile.dkp b/examples/loading/assign_transform_matrix/Makefile.dkp new file mode 100644 index 0000000..6242cae --- /dev/null +++ b/examples/loading/assign_transform_matrix/Makefile.dkp @@ -0,0 +1,220 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +include $(DEVKITARM)/ds_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +# DATA is a list of directories containing binary files embedded using bin2o +# GRAPHICS is a list of directories containing image files to be converted with grit +# AUDIO is a list of directories containing audio to be converted by maxmod +# ICON is the image used to create the game icon, leave blank to use default rule +# NITRO is a directory that will be accessible via NitroFS +#--------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR)) +BUILD := build +SOURCES := source +INCLUDES := include +DATA := +GRAPHICS := graphics +AUDIO := +ICON := + +# specify a directory which contains the nitro filesystem +# this is relative to the Makefile +NITRO := + +# These set the information text in the nds file +GAME_TITLE := $(shell basename $(CURDIR)) +GAME_SUBTITLE1 := Nitro Engine example +GAME_SUBTITLE2 := github.com/AntonioND/nitro-engine + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -marm -mthumb-interwork -march=armv5te -mtune=arm946e-s + +CFLAGS := -g -Wall -O3\ + $(ARCH) $(INCLUDE) -DARM9 +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions +ASFLAGS := -g $(ARCH) +LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project (order is important) +#--------------------------------------------------------------------------------- +LIBS := -lNE -lfat -lnds9 + +# automatigically add libraries for NitroFS +ifneq ($(strip $(NITRO)),) +LIBS := -lfilesystem -lfat $(LIBS) +endif +# automagically add maxmod library +ifneq ($(strip $(AUDIO)),) +LIBS := -lmm9 $(LIBS) +endif + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(LIBNDS) $(PORTLIBS) $(DEVKITPRO)/nitro-engine + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) + +export VPATH := $(CURDIR)/$(subst /,,$(dir $(ICON)))\ + $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))\ + $(foreach dir,$(DATA),$(CURDIR)/$(dir))\ + $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +# prepare NitroFS directory +ifneq ($(strip $(NITRO)),) + export NITRO_FILES := $(CURDIR)/$(NITRO) +endif + +# get audio list for maxmod +ifneq ($(strip $(AUDIO)),) + export MODFILES := $(foreach dir,$(notdir $(wildcard $(AUDIO)/*.*)),$(CURDIR)/$(AUDIO)/$(dir)) + + # place the soundbank file in NitroFS if using it + ifneq ($(strip $(NITRO)),) + export SOUNDBANK := $(NITRO_FILES)/soundbank.bin + + # otherwise, needs to be loaded from memory + else + export SOUNDBANK := soundbank.bin + BINFILES += $(SOUNDBANK) + endif +endif + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) + +export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export OFILES := $(PNGFILES:.png=.o) $(OFILES_BIN) $(OFILES_SOURCES) + +export HFILES := $(PNGFILES:.png=.h) $(addsuffix .h,$(subst .,_,$(BINFILES))) + +export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir))\ + $(foreach dir,$(LIBDIRS),-I$(dir)/include)\ + -I$(CURDIR)/$(BUILD) +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +ifeq ($(strip $(ICON)),) + icons := $(wildcard *.bmp) + + ifneq (,$(findstring $(TARGET).bmp,$(icons))) + export GAME_ICON := $(CURDIR)/$(TARGET).bmp + else + ifneq (,$(findstring icon.bmp,$(icons))) + export GAME_ICON := $(CURDIR)/icon.bmp + endif + endif +else + ifeq ($(suffix $(ICON)), .grf) + export GAME_ICON := $(CURDIR)/$(ICON) + else + export GAME_ICON := $(CURDIR)/$(BUILD)/$(notdir $(basename $(ICON))).grf + endif +endif + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.dkp + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(SOUNDBANK) + +#--------------------------------------------------------------------------------- +else + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).nds: $(OUTPUT).elf $(GAME_ICON) +$(OUTPUT).elf: $(OFILES) + +# source files depend on generated headers +$(OFILES_SOURCES) : $(HFILES) + +# need to build soundbank first +$(OFILES): $(SOUNDBANK) + +#--------------------------------------------------------------------------------- +# rule to build solution from music files +#--------------------------------------------------------------------------------- +$(SOUNDBANK) : $(MODFILES) +#--------------------------------------------------------------------------------- + mmutil $^ -d -o$@ -hsoundbank.h + +#--------------------------------------------------------------------------------- +%.bin.o %_bin.h : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +#--------------------------------------------------------------------------------- +# This rule creates assembly source files using grit +# grit takes an image file and a .grit describing how the file is to be processed +# add additional rules like this for each image extension +# you use in the graphics folders +#--------------------------------------------------------------------------------- +%.s %.h: %.png %.grit +#--------------------------------------------------------------------------------- + grit $< -fts -o$* + +#--------------------------------------------------------------------------------- +# Convert non-GRF game icon to GRF if needed +#--------------------------------------------------------------------------------- +$(GAME_ICON): $(notdir $(ICON)) +#--------------------------------------------------------------------------------- + @echo convert $(notdir $<) + @grit $< -g -gt -gB4 -gT FF00FF -m! -p -pe 16 -fh! -ftr + +-include $(DEPSDIR)/*.d + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/examples/loading/assign_transform_matrix/assets.sh b/examples/loading/assign_transform_matrix/assets.sh new file mode 100644 index 0000000..5dd2850 --- /dev/null +++ b/examples/loading/assign_transform_matrix/assets.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +NITRO_ENGINE=../../.. +ASSETS=$NITRO_ENGINE/examples/assets +TOOLS=$NITRO_ENGINE/tools +OBJ2DL=$TOOLS/obj2dl/obj2dl.py + +mkdir -p data + +python3 $OBJ2DL \ + --input $ASSETS/sphere.obj \ + --output data/sphere.bin \ + --texture 32 32 diff --git a/examples/loading/assign_transform_matrix/data/sphere.bin b/examples/loading/assign_transform_matrix/data/sphere.bin new file mode 100644 index 0000000..c6d11f8 Binary files /dev/null and b/examples/loading/assign_transform_matrix/data/sphere.bin differ diff --git a/examples/loading/assign_transform_matrix/source/main.c b/examples/loading/assign_transform_matrix/source/main.c new file mode 100644 index 0000000..96de07e --- /dev/null +++ b/examples/loading/assign_transform_matrix/source/main.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: CC0-1.0 +// +// SPDX-FileContributor: Antonio Niño Díaz, 2008-2024 +// +// This file is part of Nitro Engine + +// TODO + +#include + +#include "sphere_bin.h" + +typedef struct { + NE_Camera *Camera; + NE_Model *ModelWithoutMatrix; + NE_Model *ModelWithMatrix; +} SceneData; + +void Draw3DScene(void *arg) +{ + SceneData *Scene = arg; + + NE_CameraUse(Scene->Camera); + + NE_ModelDraw(Scene->ModelWithoutMatrix); + NE_ModelDraw(Scene->ModelWithMatrix); +} + +int main(int argc, char *argv[]) +{ + SceneData Scene = { 0 }; + + irqEnable(IRQ_HBLANK); + irqSet(IRQ_VBLANK, NE_VBLFunc); + irqSet(IRQ_HBLANK, NE_HBLFunc); + + // Init Nitro Engine. + NE_Init3D(); + // libnds uses VRAM_C for the text console, reserve A and B only + NE_TextureSystemReset(0, 0, NE_VRAM_AB); + // Init console in non-3D screen + consoleDemoInit(); + + // Allocate space for everything. + Scene.ModelWithoutMatrix = NE_ModelCreate(NE_Static); + Scene.ModelWithMatrix = NE_ModelCreate(NE_Static); + + Scene.Camera = NE_CameraCreate(); + + // Setup camera + NE_CameraSet(Scene.Camera, + 0, 0, 3, + 0, 0, 0, + 0, 1, 0); + + // Load models + NE_ModelLoadStaticMesh(Scene.ModelWithoutMatrix, sphere_bin); + NE_ModelLoadStaticMesh(Scene.ModelWithMatrix, sphere_bin); + + // Set up light + NE_LightSet(0, NE_Yellow, 0, -0.5, -0.5); + + // Set start coordinates/rotation of the models + NE_ModelSetCoord(Scene.ModelWithoutMatrix, -1, 0, 0); + + // Transformation matrix we are going to use for a model. Note that this + // matrix is transposed compared to what most 3D documentation describes. + m4x3 matrix = {{ + // 3x3 transformation + inttof32(1), 0, 0, + 0, inttof32(1), 0, + 0, 0, inttof32(1), + // Translation vector + inttof32(2), 0, 0 + }}; + + int translation = inttof32(2); + + printf("The right ball uses a matrix\n" + "assigned by the user, the left\n" + "one has rotation managed by\n" + "Nitro Engine."); + + while (1) + { + NE_WaitForVBL(0); + + // Rotate the first model + NE_ModelRotate(Scene.ModelWithoutMatrix, -1, 2, 1); + + // Update matrix manually + translation += floattof32(0.05); + if (translation > inttof32(3)) + translation = inttof32(1); + matrix.m[9] = translation; + + // Assign matrix again + NE_ModelSetMatrix(Scene.ModelWithMatrix, &matrix); + + // Draw scene + NE_ProcessArg(Draw3DScene, &Scene); + } + + return 0; +}