mirror of
https://github.com/AntonioND/nitro-engine.git
synced 2025-06-18 16:45:33 -04:00
examples: docs: Add example of NFlib and NE integration
https://github.com/knightfox75/nds_nflib
This commit is contained in:
parent
72dca60154
commit
bb04ea86a5
222
examples/templates/using_nflib/Makefile
Normal file
222
examples/templates/using_nflib/Makefile
Normal file
@ -0,0 +1,222 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>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 := data
|
||||
GRAPHICS :=
|
||||
AUDIO :=
|
||||
ICON :=
|
||||
|
||||
# specify a directory which contains the nitro filesystem
|
||||
# this is relative to the Makefile
|
||||
NITRO := nitrofiles
|
||||
|
||||
# These set the information text in the nds file
|
||||
GAME_TITLE := Nitro Engine example
|
||||
GAME_SUBTITLE1 := built with devkitARM
|
||||
GAME_SUBTITLE2 := http://devitpro.org
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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 -lnflib
|
||||
|
||||
# automatigically add libraries for NitroFS
|
||||
ifneq ($(strip $(NITRO)),)
|
||||
LIBS := $(LIBS) -lfilesystem -lfat
|
||||
endif
|
||||
# automagically add maxmod library
|
||||
ifneq ($(strip $(AUDIO)),)
|
||||
LIBS := $(LIBS) -lmm9
|
||||
endif
|
||||
|
||||
LIBS := $(LIBS) -lnds9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(LIBNDS) $(PORTLIBS) $(DEVKITPRO)/nitro-engine $(CURDIR)/nflib
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
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
|
||||
#---------------------------------------------------------------------------------------
|
124
examples/templates/using_nflib/nflib/Makefile
Normal file
124
examples/templates/using_nflib/nflib/Makefile
Normal file
@ -0,0 +1,124 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>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
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(shell basename $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -mthumb -mthumb-interwork
|
||||
|
||||
CFLAGS := -g -Wall -O2\
|
||||
-march=armv5te -mtune=arm946e-s \
|
||||
-fomit-frame-pointer -ffast-math \
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM9
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
|
||||
ASFLAGS := -g $(ARCH) -march=armv5te -mtune=arm946e-s
|
||||
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(LIBNDS)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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)/lib/lib$(TARGET).a
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
lib:
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
$(BUILD): lib
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) lib
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
$(OUTPUT) : $(OFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
139
examples/templates/using_nflib/nflib/include/nf_2d.h
Normal file
139
examples/templates/using_nflib/nflib/include/nf_2d.h
Normal file
@ -0,0 +1,139 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_2D_H__
|
||||
#define __NF_2D_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de funciones 2D comunes
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Set2D();
|
||||
void NF_Set2D(u8 screen, u8 mode);
|
||||
// Inicia el modo 2D seleccionado en la pantalla deseada
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ShowBg();
|
||||
void NF_ShowBg(u8 screen, u8 layer);
|
||||
// Haz visible el fondo de la capa y pantalla dados
|
||||
|
||||
|
||||
|
||||
// Funcion NF_HideBg();
|
||||
void NF_HideBg(u8 screen, u8 layer);
|
||||
// Oculta el fondo de la capa y pantalla dados
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ScrollBg();
|
||||
void NF_ScrollBg(u8 screen, u8 layer, s16 x, s16 y);
|
||||
// Mueve el fondo a las coordenadas especificadas.
|
||||
// Debes de indicar la pantalla, capa, y coordenadas X e Y
|
||||
// Si el mapa es mayor de 512 en alguna medida, debes de mantener el fondo en RAM
|
||||
|
||||
|
||||
|
||||
// Funcion NF_MoveSprite();
|
||||
void NF_MoveSprite(u8 screen, u8 id, s16 x, s16 y);
|
||||
// Mueve el Sprite a las coordenadas especificadas
|
||||
// Debes de indicar la pantalla, id de sprite y coordenadas
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteLayer();
|
||||
void NF_SpriteLayer(u8 screen, u8 id, u8 layer);
|
||||
// Define la capa sobre la que el sprite sera dibujado
|
||||
// Debes de indicar la pantalla, id del sprite y capa
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ShowSprite();
|
||||
void NF_ShowSprite(u8 screen, u8 id, bool show);
|
||||
// Muestra o oculta el sprite
|
||||
// Debes especificar la pantalla, id del sprite y el estado (true, false)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_HflipSprite();
|
||||
void NF_HflipSprite(u8 screen, u8 id, bool hflip);
|
||||
// Voltea el Sprite horizontalmente
|
||||
// Debes especificar la pantalla, id del sprite y el estado (true, false)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetSpriteHflip();
|
||||
extern bool NF_GetSpriteHflip(u8 screen, u8 id);
|
||||
// Devuelve el estado del volteado horizontal de un sprite
|
||||
// Debes especificar la pantalla y la id del sprite
|
||||
|
||||
|
||||
|
||||
// Funcion NF_VflipSprite();
|
||||
void NF_VflipSprite(u8 screen, u8 id, bool vflip);
|
||||
// Voltea el Sprite verticalmente
|
||||
// Debes especificar la pantalla, id del sprite y el estado (true, false)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetSpriteVflip();
|
||||
extern bool NF_GetSpriteVflip(u8 screen, u8 id);
|
||||
// Devuelve el estado del volteado vertical de un sprite
|
||||
// Debes especificar la pantalla y la id del sprite
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteFrame();
|
||||
void NF_SpriteFrame(u8 screen, u8 id, u16 frame);
|
||||
// Cambia el frame de un Sprite
|
||||
// Debes especificar la pantalla, el Id del sprite y el frame
|
||||
|
||||
|
||||
|
||||
// Funcion NF_EnableSpriteRotScale();
|
||||
void NF_EnableSpriteRotScale(u8 screen, u8 sprite, u8 id, bool doublesize);
|
||||
// Habilita el sprite como rotable y escalable
|
||||
// Debes especificar la pantalla, nº de sprite, id de rotacion y si
|
||||
// tiene que activarse el doublesize (tamaño x2)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DisableSpriteRotScale();
|
||||
void NF_DisableSpriteRotScale(u8 screen, u8 sprite);
|
||||
// Deshabilita un sprite como rotable y escalable
|
||||
// Debes especificar la pantalla y el nº de sprite
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteRotScale();
|
||||
void NF_SpriteRotScale(u8 screen, u8 id, s16 angle, u16 sx, u16 sy);
|
||||
// Define el angulo de rotacion y escala de los Sprites asociados a la Id.
|
||||
// El rango del angulo es desde -512 a 512, siendo 0 el valor central
|
||||
// El rango de escalado va de 0 a 512, siendo 256 el valor normal (100%)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
50
examples/templates/using_nflib/nflib/include/nf_3d.h
Normal file
50
examples/templates/using_nflib/nflib/include/nf_3d.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_3D_H__
|
||||
#define __NF_3D_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de funciones 3D
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Set3D();
|
||||
void NF_Set3D(u8 screen, u8 mode);
|
||||
// Inicia el modo 3D seleccionado en la pantalla deseada
|
||||
|
||||
|
||||
// Funcion NF_InitOpenGL();
|
||||
void NF_InitOpenGL(void);
|
||||
// Inicializa el OpenGL para la libreria
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetTextureSize();
|
||||
extern u16 NF_GetTextureSize(u16 textel);
|
||||
// Devuelve el tamaño del textel
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
106
examples/templates/using_nflib/nflib/include/nf_affinebg.h
Normal file
106
examples/templates/using_nflib/nflib/include/nf_affinebg.h
Normal file
@ -0,0 +1,106 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_AFFINEBG_H__
|
||||
#define __NF_AFFINEBG_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Includes de Fondos Affine
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Estructura para almacenar los parametros de los fondos Affine
|
||||
typedef struct {
|
||||
s32 x; // Posicion X
|
||||
s32 y; // Posicion Y
|
||||
s32 x_center; // Centro X
|
||||
s32 y_center; // Centro Y
|
||||
s32 x_scale; // Valor Zoom X (PA)
|
||||
s32 y_scale; // Valor Zoom Y (PD)
|
||||
s32 x_tilt; // Valor Inclinacion X (PB)
|
||||
s32 y_tilt; // Valor Inclinacion Y (PC)
|
||||
s32 angle; // Valor de la rotacion
|
||||
} NF_TYPE_AFFINE_BG;
|
||||
extern NF_TYPE_AFFINE_BG NF_AFFINE_BG[2][4];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitTiledBgSys();
|
||||
void NF_InitAffineBgSys(u8 screen);
|
||||
// Inicializa el sistema de fondos Affine. Solo puede usarse en las capas 2 y 3, los fondos en
|
||||
// la misma pantalla deben de compartir la paleta y no pueden tener mas de 256 tiles.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadAffineBg();
|
||||
void NF_LoadAffineBg(const char* file, const char* name, u16 width, u16 height);
|
||||
// Carga un fondo tileado desde FAT
|
||||
// Debes de especificar el archivo que se cargara (sin extension) y el nombre
|
||||
// que le quieres dar y las medidas en pixeles
|
||||
// Los buffers para fondos tileados deben estar inicializados antes de usar esta funcion
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadAffineBg();
|
||||
void NF_UnloadAffineBg(const char* name);
|
||||
// Borra de la RAM el fondo affine especificado. Es una simple llamada a la funcion NF_UnloadTiledBg();
|
||||
|
||||
|
||||
|
||||
// Funcion NF_CreateAffineBg();
|
||||
void NF_CreateAffineBg(u8 screen, u8 layer, const char* name, u8 wrap);
|
||||
// Crea un fondo con los parametros dados, indicale la pantalla, capa, nombre y si se activa la opcion
|
||||
// de WRAP arround (0 desactivado, 1 activado).
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DeleteAffineBg();
|
||||
void NF_DeleteAffineBg(u8 screen, u8 layer);
|
||||
// Borra el fondo Affine especificado
|
||||
|
||||
|
||||
|
||||
// Funcion NF_AffineBgTransform();
|
||||
void NF_AffineBgTransform(u8 screen, u8 layer, s32 x_scale, s32 y_scale, s32 x_tilt, s32 y_tilt);
|
||||
// Modifica los parametros de la matriz de transformacion del fondo affine
|
||||
|
||||
|
||||
|
||||
// Funcion NF_AffineBgMove();
|
||||
void NF_AffineBgMove(u8 screen, u8 layer, s32 x, s32 y, s32 angle);
|
||||
// Desplaza el fondo affine y rotalo (-2048 a 2048)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_AffineBgCenter();
|
||||
void NF_AffineBgCenter(u8 screen, u8 layer, s32 x, s32 y);
|
||||
// Define el centro de rotacion de un fondo affine
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
89
examples/templates/using_nflib/nflib/include/nf_basic.h
Normal file
89
examples/templates/using_nflib/nflib/include/nf_basic.h
Normal file
@ -0,0 +1,89 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_BASIC_H__
|
||||
#define __NF_BASIC_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de funciones basicas
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Define la variable global NF_ROOTFOLDER
|
||||
extern char NF_ROOTFOLDER[32];
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Error();
|
||||
void NF_Error(u16 code, const char* text, u32 value);
|
||||
// Errores para debug. Detiene el sistema e informa del error
|
||||
// 101: Fichero no encontrado
|
||||
// 102: Memoria insuficiente
|
||||
// 103: No quedan Slots libres
|
||||
// 104: Fondo no encontrado
|
||||
// 105: Fondo no creado
|
||||
// 106: Fuera de rango
|
||||
// 107: Insuficientes bloques contiguos en VRAM (Tiles)
|
||||
// 108: Insuficientes bloques contiguos en VRAM (Maps)
|
||||
// 109: Id ocupada (ya esta en uso)
|
||||
// 110: Id no cargada (en RAM)
|
||||
// 111: Id no en VRAM
|
||||
// 112: Sprite no creado
|
||||
// 113: Memoria VRAM insuficiente
|
||||
// 114: La capa de Texto no existe
|
||||
// 115: Medidas del fondo no compatibles (no son multiplos de 256)
|
||||
// 116: Archivo demasiado grande
|
||||
// 117: Medidas del fondo affine incorrectas
|
||||
// 118: Capa de creacion del fondo affine incorrecta
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SetRootFolder();
|
||||
void NF_SetRootFolder(const char* folder);
|
||||
// Define el nombre de la carpeta que se usara como "root" si se usa la FAT
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DmaMemCopy();
|
||||
void NF_DmaMemCopy(void* destination, const void* source, u32 size);
|
||||
// Copia un bloque de memoria usando DMA (canal 3, halfwords) y vaciando previamente
|
||||
// el cache. Con pruebas de bloques grandes (64kb o 128kb) he observado que memcpy();
|
||||
// sigue siendo mas rapida.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetLanguage();
|
||||
extern u8 NF_GetLanguage(void);
|
||||
// Devuelve el ID del idioma del usuario
|
||||
// 0 : Japanese
|
||||
// 1 : English
|
||||
// 2 : French
|
||||
// 3 : German
|
||||
// 4 : Italian
|
||||
// 5 : Spanish
|
||||
// 6 : Chinese
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
234
examples/templates/using_nflib/nflib/include/nf_bitmapbg.h
Normal file
234
examples/templates/using_nflib/nflib/include/nf_bitmapbg.h
Normal file
@ -0,0 +1,234 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_BITMAPBG_H__
|
||||
#define __NF_BITMAPBG_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de funciones de fondos en modo Bitmap
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
|
||||
// Define los slots maximos para los fondos de 16 bits
|
||||
#define NF_SLOTS_BG16B 16
|
||||
|
||||
// Define los slots maximos para los fondos de 8 bits
|
||||
#define NF_SLOTS_BG8B 16
|
||||
|
||||
// Define los Buffers para almacenar datos de 16 bits
|
||||
typedef struct {
|
||||
u16* buffer; // Buffer de datos
|
||||
u32 size; // Tamaño del buffer
|
||||
u16 width; // Ancho de la imagen (256 max)
|
||||
u16 height; // Altura de la imagen (256 max)
|
||||
bool inuse; // Esta en uso el buffer?
|
||||
} NF_TYPE_BG16B_INFO;
|
||||
extern NF_TYPE_BG16B_INFO NF_BG16B[NF_SLOTS_BG16B]; // Fondos RAW de 16 bits
|
||||
|
||||
// BackBuffer de 16 bits de cada pantalla
|
||||
extern u16* NF_16BITS_BACKBUFFER[2];
|
||||
|
||||
// Define los Buffers para almacenar datos de 8 bits
|
||||
typedef struct {
|
||||
u8* data; // Buffer de datos
|
||||
u32 data_size; // Tamaño del buffer de datos
|
||||
u16* pal; // Buffer para la paleta
|
||||
u32 pal_size; // Tamaño de la paleta
|
||||
bool inuse; // Esta en uso el buffer?
|
||||
} NF_TYPE_BG8B_INFO;
|
||||
extern NF_TYPE_BG8B_INFO NF_BG8B[NF_SLOTS_BG8B]; // Fondos indexados de 8 bits
|
||||
|
||||
// BackBuffer de 8 bits de cada pantalla
|
||||
typedef struct {
|
||||
u8* data;
|
||||
u16* pal;
|
||||
} NF_TYPE_BB8B_INFO;
|
||||
extern NF_TYPE_BB8B_INFO NF_8BITS_BACKBUFFER[2];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Init16bitsBgBuffers();
|
||||
void NF_Init16bitsBgBuffers(void);
|
||||
// Inicia los buffers para almacenar fondos de BITMAP 16 bits
|
||||
// Usalo UNA SOLA VEZ antes de usar los buffers
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Reset16bitsBgBuffers();
|
||||
void NF_Reset16bitsBgBuffers(void);
|
||||
// Reinicia los buffers para almacenar fondos de BITMAP 16 bits,
|
||||
// borrado su contenido
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Init16bitsBackBuffer();
|
||||
void NF_Init16bitsBackBuffer(u8 screen);
|
||||
// Inicia el backbuffer de la pantalla dada.
|
||||
// Usalo UNA SOLA VEZ antes de usar el backbuffer
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Enable16bitsBackBuffer();
|
||||
void NF_Enable16bitsBackBuffer(u8 screen);
|
||||
// Habilita el backbuffer de la pantalla indicada.
|
||||
// Si el buffer ya existe, la funcion borrara el contenido del mismo,
|
||||
// poniendo a 0 todos los bytes del buffer.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Disble16bitsBackBuffer();
|
||||
void NF_Disble16bitsBackBuffer(u8 screen);
|
||||
// Deshabilita el backbuffer de la pantalla indicada, liberando de la
|
||||
// RAM el espacio usado.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Flip16bitsBackBuffer();
|
||||
void NF_Flip16bitsBackBuffer(u8 screen);
|
||||
// Copia el contenido del backbuffer a la VRAM de la pantalla indicada.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitBitmapBgSys();
|
||||
void NF_InitBitmapBgSys(u8 screen, u8 mode);
|
||||
// Inicia el modo BITMAP en la pantalla especificada, con la profundidad de color
|
||||
// especificada. (0 -> 256 colores, 1 -> 16 bits)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Load16bitsBg();
|
||||
void NF_Load16bitsBg(const char* file, u8 slot);
|
||||
// Carga un Fondo BITMAP (en formato RAW) en el slot indicado,
|
||||
// de un tamaño maximo de 256x256 pixeles.
|
||||
// Debes especificar el nombre de archivo sin extension.
|
||||
// El archivo debe ser un binario con extension .img
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Load16bitsImage();
|
||||
void NF_Load16bitsImage(const char* file, u8 slot, u16 size_x, u16 size_y);
|
||||
// Carga una imagen BITMAP (en formato RAW) en el slot indicado,
|
||||
// de un tamaño maximo de 256x256 pixeles.
|
||||
// Debes especificar el nombre de archivo sin extension.
|
||||
// El archivo debe ser un binario con extension .img
|
||||
// Todos los pixeles Magenta de la imagen (0xFF00FF) seran transparentes.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Load16bImgData();
|
||||
void NF_Load16bImgData(const char* file, u8 slot, u16 x, u16 y, u8 type);
|
||||
// Funcion de uso interno, no documentar ni usar.
|
||||
// Cargador generico de datos de imagen de 16 bits a la RAM.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Unload16bitsBg();
|
||||
void NF_Unload16bitsBg(u8 slot);
|
||||
// Borra de la RAM los datos del buffer especificado
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Copy16bitsBuffer();
|
||||
void NF_Copy16bitsBuffer(u8 screen, u8 destination, u8 slot);
|
||||
// Copia los datos cargados en un Buffer de Bitmap a la VRAM o al BackBuffer
|
||||
// destination: 0 -> VRAM, 1 -> BackBuffer
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Draw16bitsImage();
|
||||
void NF_Draw16bitsImage(u8 screen, u8 slot, s16 x, s16 y, bool alpha);
|
||||
// Copia la imagen cargada en un Buffer de Bitmap al Backbuffer de la pantalla especificada
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Init8bitsBgBuffers();
|
||||
void NF_Init8bitsBgBuffers(void);
|
||||
// Inicializa los buffers necesarios para la carda de fondos en modo BITMAP de 8 bits.
|
||||
// Debes usar esta funcion antes de poder usar ninguno de los buffers.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Reset8bitsBgBuffers();
|
||||
void NF_Reset8bitsBgBuffers(void);
|
||||
// Reinicia los buffers de fondos de 8 bits, borrando todo el contenido de los buffers.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Load8bitsBg();
|
||||
void NF_Load8bitsBg(const char* file, u8 slot);
|
||||
// Carga los archivos necesarios de un fondo de 8 bits en el Slot indicado.
|
||||
// Debes especificar el nombre de archivo sin extension.
|
||||
// El archivo debe ser un binario con extension .img
|
||||
// La paleta debe tener la extension .pal
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Unload8bitsBg();
|
||||
void NF_Unload8bitsBg(u8 slot);
|
||||
// Borra de la RAM el fondo del slot indicado.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Copy8bitsBuffer();
|
||||
void NF_Copy8bitsBuffer(u8 screen, u8 destination, u8 slot);
|
||||
// Transfiere la imagen del buffer seleccionado a la pantalla y capas indicado o
|
||||
// al backbuffer.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Init8bitsBackBuffer();
|
||||
void NF_Init8bitsBackBuffer(u8 screen);
|
||||
// Inicializa los buffers del backbuffer para la pantalla indicada.
|
||||
// Debes usar esta funcion una vez antes de usar el backbuffer
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Enable8bitsBackBuffer();
|
||||
void NF_Enable8bitsBackBuffer(u8 screen);
|
||||
// Habilita el backbuffer de la pantalla indicada.
|
||||
// Si el buffer ya existe, la funcion borrara el contenido del mismo,
|
||||
// poniendo a 0 todos los bytes del buffer.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Disble8bitsBackBuffer();
|
||||
void NF_Disble8bitsBackBuffer(u8 screen);
|
||||
// Deshabilita el backbuffer de la pantalla indicada, liberando de la
|
||||
// RAM el espacio usado.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Flip8bitsBackBuffer();
|
||||
void NF_Flip8bitsBackBuffer(u8 screen, u8 destination);
|
||||
// Copia el contenido del backbuffer a la VRAM de la pantalla indicada.
|
||||
// Debes especificar la capa de destino:
|
||||
// 0 -> Capa 2
|
||||
// 1 -> Capa 3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
110
examples/templates/using_nflib/nflib/include/nf_colision.h
Normal file
110
examples/templates/using_nflib/nflib/include/nf_colision.h
Normal file
@ -0,0 +1,110 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_COLISION_H__
|
||||
#define __NF_COLISION_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de Colisiones
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Define los slots maximos para los mapas de colisiones
|
||||
#define NF_SLOTS_CMAP 32
|
||||
|
||||
// Define la estructura de control de mapas de colisiones
|
||||
typedef struct {
|
||||
char* tiles; // Buffer para almacenar los tiles
|
||||
char* map; // Buffer para almacenar el mapa
|
||||
char* pal; // Buffer para almacenar la paleta
|
||||
u32 tiles_size; // Tamaño de los archivos
|
||||
u32 map_size;
|
||||
u32 pal_size;
|
||||
u16 width; // Ancho del mapa (en pixeles)
|
||||
u16 height; // Alto del mapa (en pixeles)
|
||||
bool inuse; // Esta en uso el slot?
|
||||
} NF_TYPE_CMAP_INFO;
|
||||
extern NF_TYPE_CMAP_INFO NF_CMAP[NF_SLOTS_CMAP]; // Datos de los mapas de colision
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitCmapBuffers();
|
||||
void NF_InitCmapBuffers(void);
|
||||
// Inicializa los buffers que almacenaran los mapas de colision
|
||||
// Debes usar esta funcion una unica vez antes de cargar ningun mapa de colision
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ResetCmapBuffers();
|
||||
void NF_ResetCmapBuffers(void);
|
||||
// Reinicia los buffers y variables de los mapas de colisiones.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadColisionMap();
|
||||
void NF_LoadColisionMap(const char* file, u8 id, u16 width, u16 height);
|
||||
// Carga un mapa de colisiones en el slot indicado.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadColisionMap();
|
||||
void NF_UnloadColisionMap(u8 id);
|
||||
// Borra de la RAM el mapa de colisiones con el nº de slot indicado.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetTile();
|
||||
extern u16 NF_GetTile(u8 slot, s32 x, s32 y);
|
||||
// Devuelve el numero de tile de la posicion especificada.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SetTile();
|
||||
void NF_SetTile(u8 slot, s32 x, s32 y, u16 value);
|
||||
// Cambia el valor del tile en la posicion especificada.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadColisionBg();
|
||||
void NF_LoadColisionBg(const char* file, u8 id, u16 width, u16 height);
|
||||
// Carga un fondo de colisiones para pixel perfect
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadColisionBg();
|
||||
void NF_UnloadColisionBg(u8 id);
|
||||
// Descarga un fondo de colisiones para pixel perfect
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetPoint();
|
||||
extern u8 NF_GetPoint(u8 slot, s32 x, s32 y);
|
||||
// Obten el color del pixel de las coordenadas dadas
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
79
examples/templates/using_nflib/nflib/include/nf_defines.h
Normal file
79
examples/templates/using_nflib/nflib/include/nf_defines.h
Normal file
@ -0,0 +1,79 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_DEFINES_H__
|
||||
#define __NF_DEFINES_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Definiciones General
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Definicion de los datos del usuario
|
||||
// Informacion obtenida de PALIB source code
|
||||
// Referencias usadas de http://nds.metawiki.com/Firmware
|
||||
|
||||
/*
|
||||
|
||||
FW offset* RAM address Bytes Description
|
||||
0x000020 2 user settings offset / 8 (default 0x7FC0 => 0x3FE00)
|
||||
0x00002A 2 CRC16 (with initial value 0) of 0x2C with config length
|
||||
0x00002C 2 config length (0x138)
|
||||
0x000036 6 MAC address
|
||||
0x00003C 4 enabled channels
|
||||
0x000065 1 ?
|
||||
0x000082 1 ?
|
||||
0x000100 1 ?
|
||||
0x000146 14 ?
|
||||
0x000162 1 ?
|
||||
0x03Fx00 0x023FFC80 1 version (5)
|
||||
0x03Fx02 0x027FFC82 1 favorite color (0-15)
|
||||
0x03Fx03 0x027FFC83 1 birthday month (1-12)
|
||||
0x03Fx04 0x027FFC84 1 birthday day (1-31)
|
||||
0x03Fx06 0x027FFC86 20 name, UTF-16
|
||||
0x03Fx1A 0x027FFC9A 1/2 length of name in characters
|
||||
0x03Fx1C 0x027FFC9C 52 message, UTF-16
|
||||
0x03Fx50 0x027FFCD0 1/2 length of message in characters
|
||||
0x03Fx52 0x027FFCD2 1 alarm hour
|
||||
0x03Fx53 0x027FFCD3 1 alarm minute
|
||||
0x03Fx56 0x027FFCD6 1 0x80=enable alarm, bit 0..6=enable?
|
||||
0x027FFCD8 12 touch-screen calibration
|
||||
0x027FFCE4 bit 0..2 language
|
||||
0x027FFCE4 bit 3 GBA mode screen selection. 0=upper, 1=lower
|
||||
0x027FFCE4 bit 6 auto/manual mode. 0=manual, 1=auto
|
||||
WIFI power calibration
|
||||
0x03Fx70 1/2 update counter (used to check latest)
|
||||
0x03Fx72 CRC16 of 0x03FF00, 0x70 bytes
|
||||
|
||||
*/
|
||||
|
||||
#define NF_UDATA_COLOR *(u8*)(0x027FFC82)
|
||||
#define NF_UDATA_BDAY_MONTH *(u8*)(0x027FFC83)
|
||||
#define NF_UDATA_BDAY_DAY *(u8*)(0x027FFC84)
|
||||
#define NF_UDATA_ALARM_HOUR *(u8*)(0x027FFCD2)
|
||||
#define NF_UDATA_ALARM_MINUTE *(u8*)(0x027FFCD3)
|
||||
#define NF_UDATA_NAME *(u8*)(0x027FFC86)
|
||||
#define NF_UDATA_NAME_SIZE *(u8*)(0x027FFC9A)
|
||||
#define NF_UDATA_MSG *(u8*)(0x027FFC9C)
|
||||
#define NF_UDATA_MSG_SIZE *(u8*)(0x027FFCD0)
|
||||
#define NF_UDATA_LANG *(u8*)(0x027FFCE4)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
114
examples/templates/using_nflib/nflib/include/nf_lib.h
Normal file
114
examples/templates/using_nflib/nflib/include/nf_lib.h
Normal file
@ -0,0 +1,114 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_LIB_H__
|
||||
#define __NF_LIB_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include General
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Notas sobre BITSHIFT
|
||||
|
||||
(n >> x) Divide n / x
|
||||
(n << x) Multiplica n * x
|
||||
|
||||
Valores de X
|
||||
2 = 1
|
||||
4 = 2
|
||||
8 = 3
|
||||
16 = 4
|
||||
32 = 5
|
||||
64 = 6
|
||||
128 = 7
|
||||
256 = 8
|
||||
512 = 9
|
||||
1024 = 10
|
||||
2048 = 11
|
||||
4096 = 12
|
||||
8192 = 13
|
||||
16384 = 14
|
||||
32768 = 15
|
||||
65536 = 16
|
||||
|
||||
Dado que la DS no tiene unidad de coma flotante, siempre que dividas o
|
||||
multipliques por numeros de base 2, usa el bitshift
|
||||
Por ejemplo:
|
||||
a = (512 / 8);
|
||||
seria equivalente a
|
||||
a = (512 >> 3);
|
||||
Multiplicando
|
||||
b = (3 * 2048);
|
||||
seria con bitshift
|
||||
b = (3 << 11);
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
// Definiciones comunes
|
||||
#include "nf_defines.h"
|
||||
|
||||
// Libreria de funciones basicas y comunes
|
||||
#include "nf_basic.h"
|
||||
|
||||
// Libreria de funciones 2D comunes
|
||||
#include "nf_2d.h"
|
||||
|
||||
// Libreria de fondos con Tiles
|
||||
#include "nf_tiledbg.h"
|
||||
|
||||
// Libreria de fondos Affine
|
||||
#include "nf_affinebg.h"
|
||||
|
||||
// Libreria de fondos en modo Bitmap
|
||||
#include "nf_bitmapbg.h"
|
||||
|
||||
// Libreria de fondos en modo mixto (Tiled / Bitmap 8 bits)
|
||||
#include "nf_mixedbg.h"
|
||||
|
||||
// Libreria de sprites de 256 colores
|
||||
#include "nf_sprite256.h"
|
||||
|
||||
// Libreria de textos
|
||||
#include "nf_text.h"
|
||||
|
||||
// Libreria de textos de 16 pixeles
|
||||
#include "nf_text16.h"
|
||||
|
||||
// Libreria de colisiones
|
||||
#include "nf_colision.h"
|
||||
|
||||
// Libreria de sonido
|
||||
#include "nf_sound.h"
|
||||
|
||||
// Libreria de archivos multimedia
|
||||
#include "nf_media.h"
|
||||
|
||||
// Libreria 3D, funciones comunes
|
||||
#include "nf_3d.h"
|
||||
|
||||
// Libreria 3D, Sprites
|
||||
#include "nf_sprite3d.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
41
examples/templates/using_nflib/nflib/include/nf_media.h
Normal file
41
examples/templates/using_nflib/nflib/include/nf_media.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_MEDIA_H__
|
||||
#define __NF_MEDIA_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de funciones de carga de archivos multimedia
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadBMP();
|
||||
void NF_LoadBMP(const char* file, u8 slot);
|
||||
// Carga un archivo BMP de 8, 16 o 24 bits en un slot de imagenes de 16 bits.
|
||||
// Debes inicializar el modo 16 bits, el backbuffer y usar la funcion NF_Draw16bitsImage();
|
||||
// para mostrarlo.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
41
examples/templates/using_nflib/nflib/include/nf_mixedbg.h
Normal file
41
examples/templates/using_nflib/nflib/include/nf_mixedbg.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_MIXEDBG_H__
|
||||
#define __NF_MIXEDBG_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de Fondos mixtos (Tiled / Bitmap 8 bits)
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitMixedBgSys();
|
||||
void NF_InitMixedBgSys(u8 screen);
|
||||
// Inicializa el modo mixto para fondo (Tiled BG + Bitmap 8 bits)
|
||||
// Capas 0 a 2 - Tiled
|
||||
// Capa 3 - Bitmap 8 bits
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
96
examples/templates/using_nflib/nflib/include/nf_sound.h
Normal file
96
examples/templates/using_nflib/nflib/include/nf_sound.h
Normal file
@ -0,0 +1,96 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_SOUND_H__
|
||||
#define __NF_SOUND_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de funciones de sonido
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Define los Slots para archivos de audio
|
||||
#define NF_SLOTS_RAWSOUND 32
|
||||
|
||||
// Define los Buffers para almacenar los archivos de audio
|
||||
extern char* NF_BUFFER_RAWSOUND[NF_SLOTS_RAWSOUND];
|
||||
|
||||
// Define la estructura de datos de los buffers (Audio)
|
||||
typedef struct {
|
||||
bool available; // Disponibilidat del Slot
|
||||
u32 size; // Tamaño (en bytes) del sonido
|
||||
u16 freq; // Frecuencia del sample
|
||||
u8 format; // Formato del sample
|
||||
} NF_TYPE_RAWSOUND_INFO;
|
||||
extern NF_TYPE_RAWSOUND_INFO NF_RAWSOUND[NF_SLOTS_RAWSOUND]; // Datos de los sonidos cargado
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitRawSoundBuffers();
|
||||
void NF_InitRawSoundBuffers(void);
|
||||
// Iniciliaza los buffers y estructuras de datos para cargar sonidos en
|
||||
// formato RAW. Debes de ejecutar esta funcion una vez antes de cargar
|
||||
// ningun sonido en este formato
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ResetRawSoundBuffers();
|
||||
void NF_ResetRawSoundBuffers(void);
|
||||
// Reinicia todos los buffers de sonido. Esta funcion es util para vaciar todos los datos
|
||||
// en un cambio de pantalla, etc.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadRawSound();
|
||||
void NF_LoadRawSound(const char* file, u16 id, u16 freq, u8 format);
|
||||
// Carga un archivo RAW a la RAM desde la FAT o EFS
|
||||
// Debes especificar el nombre del archivo sin extension, el slot
|
||||
// donde lo guardaras (0 - 31), la frecuencia del sample (en Hz,
|
||||
// por ejemplo 11050) y el formato de datos
|
||||
// (0 - > 8 bits, 1 - > 16 bits, 2 -> ADPCM)
|
||||
|
||||
|
||||
|
||||
// Funcion UnloadRawSound();
|
||||
void NF_UnloadRawSound(u8 id);
|
||||
// Borra de la RAM el archivo cargado en el slot indicado.
|
||||
// Debes especificar el slot a borrar (0 - 31)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_PlayRawSound();
|
||||
extern u8 NF_PlayRawSound(u8 id, u8 volume, u8 pan, bool loop, u16 loopfrom);
|
||||
// Reproduce un archivo de sonido cargado en RAM.
|
||||
// Debes especificar el slot donde se ha cargado el sonido, el volumen (0 - 127),
|
||||
// el balance (0 Izquierda, 64 Centro, 127 Derecha), si se reproducira en bucle y
|
||||
// de ser asi, a partir de que sample se producira este.
|
||||
// Esta funcion devuelve el canal asignado a esta reproduccion
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
265
examples/templates/using_nflib/nflib/include/nf_sprite256.h
Normal file
265
examples/templates/using_nflib/nflib/include/nf_sprite256.h
Normal file
@ -0,0 +1,265 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_SPRITE256_H__
|
||||
#define __NF_SPRITE256_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de Sprites a 256 colores
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Define los Slots para sprites
|
||||
#define NF_SLOTS_SPR256GFX 256 // Almacena los graficos
|
||||
#define NF_SLOTS_SPR256PAL 64 // Almacena las paletas
|
||||
|
||||
// Define los Buffers para almacenar los Sprites
|
||||
extern char* NF_BUFFER_SPR256GFX[NF_SLOTS_SPR256GFX];
|
||||
extern char* NF_BUFFER_SPR256PAL[NF_SLOTS_SPR256PAL];
|
||||
|
||||
// Define la estructura de datos de los buffers (GFX)
|
||||
typedef struct {
|
||||
u32 size; // Tamaño (en bytes) del grafico (GFX)
|
||||
u16 width; // Ancho del Gfx
|
||||
u16 height; // Altura del Gfx
|
||||
bool available; // Disponibilidat del Slot
|
||||
} NF_TYPE_SPR256GFX_INFO;
|
||||
extern NF_TYPE_SPR256GFX_INFO NF_SPR256GFX[NF_SLOTS_SPR256GFX]; // Buffers de Graficos
|
||||
|
||||
// Define la estructura de datos de los buffers (PAL)
|
||||
typedef struct {
|
||||
u32 size; // Tamaño (en bytes) de la paleta (PAL)
|
||||
bool available; // Disponibilidat del Slot
|
||||
} NF_TYPE_SPR256PAL_INFO;
|
||||
extern NF_TYPE_SPR256PAL_INFO NF_SPR256PAL[NF_SLOTS_SPR256PAL]; // Buffers de Paletas
|
||||
|
||||
// Define la estructura de Gfx en VRAM
|
||||
typedef struct {
|
||||
u32 size; // Tamaño (en bytes) del Gfx
|
||||
u16 width; // Ancho del Gfx
|
||||
u16 height; // Altura del Gfx
|
||||
u32 address; // Posicion en la VRAM
|
||||
u16 ramid; // Numero de Slot en RAM del que provienes
|
||||
u16 framesize; // Tamaño del frame (en bytes)
|
||||
u16 lastframe; // Ultimo frame
|
||||
bool keepframes; // Si es un Sprite animado, debes de mantener los frames en RAM ?
|
||||
bool inuse; // Disponibilidat del Slot
|
||||
} NF_TYPE_SPR256VRAM_INFO;
|
||||
extern NF_TYPE_SPR256VRAM_INFO NF_SPR256VRAM[2][128];
|
||||
|
||||
// Datos de paletas de Sprites en VRAM (en uso, slot en ram, etc)
|
||||
typedef struct {
|
||||
bool inuse; // Slot en uso
|
||||
u8 ramslot; // Paleta original en RAM
|
||||
} NF_TYPE_SPRPALSLOT_INFO;
|
||||
extern NF_TYPE_SPRPALSLOT_INFO NF_SPRPALSLOT[2][16];
|
||||
|
||||
// Define la estructura de datos del OAM (Sprites)
|
||||
typedef struct {
|
||||
u8 index; // Numero de Sprite
|
||||
s16 x; // Coordenada X del Sprite
|
||||
s16 y; // Coordenada Y del Sprite
|
||||
u8 layer; // Prioridad en las capas
|
||||
u8 pal; // Paleta que usaras
|
||||
u32 size; // Tamaño del Sprite (macro)
|
||||
u32 color; // Modo de color (macro)
|
||||
u32* gfx; // Puntero al grafico usado
|
||||
s8 rot; // Id de rotacion (-1 ninguno) (0 - 31 Id de rotacion)
|
||||
bool doublesize; // Usar el "double size" al rotar ?
|
||||
bool hide; // Ocultar el Sprite
|
||||
bool vflip; // Volteado Vertical
|
||||
bool hflip; // Volteado Horizontal
|
||||
bool mosaic; // Mosaico
|
||||
u16 gfxid; // Id de Gfx usado
|
||||
u16 frame; // Frame actual
|
||||
u16 framesize; // Tamaño del frame (en bytes)
|
||||
u16 lastframe; // Ultimo frame
|
||||
bool created; // Esta creado este sprite ?
|
||||
} NF_TYPE_SPRITEOAM_INFO;
|
||||
extern NF_TYPE_SPRITEOAM_INFO NF_SPRITEOAM[2][128]; // 2 pantallas, 128 sprites
|
||||
|
||||
// Define la esturctura de control de la VRAM para Sprites
|
||||
typedef struct {
|
||||
s32 free; // Memoria VRAM libre
|
||||
u32 next; // Siguiente posicion libre
|
||||
u32 last; // Ultima posicion usada
|
||||
u32 pos[128]; // Posicion en VRAM para reusar despues de un borrado
|
||||
u32 size[128]; // Tamaño del bloque libre para reusar
|
||||
u16 deleted; // Numero de bloques borrados
|
||||
s32 fragmented; // Memoria VRAM fragmentada
|
||||
s32 inarow; // Memoria VRAM contigua
|
||||
s32 max; // Maxima memoria VRAM direccionable
|
||||
} NF_TYPE_SPRVRAM_INFO;
|
||||
extern NF_TYPE_SPRVRAM_INFO NF_SPRVRAM[2]; // Informacion VRAM de Sprites en ambas pantallas
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitSpriteBuffers()
|
||||
void NF_InitSpriteBuffers(void);
|
||||
// Inicializa los buffers y estructuras de datos de los Buffers para almacenar Sprites
|
||||
// Usala antes de cargar cualquier Sprites
|
||||
// No uses esta funcion mas de una vez en tu codigo
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ResetSpriteBuffers()
|
||||
void NF_ResetSpriteBuffers(void);
|
||||
// Reinicia los buffers y datos para almacenar Sprites
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitSpriteSys();
|
||||
void NF_InitSpriteSys(int screen, ...);
|
||||
// Inicializa las variables de control de Sprites y paletas
|
||||
// Asigna 128kb de RAM para Sprites
|
||||
// Activa el Soporte para Sprites
|
||||
// Se debe especificar la pantalla (0 o 1)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadSpriteGfx();
|
||||
void NF_LoadSpriteGfx(const char* file, u16 id, u16 width, u16 height);
|
||||
// Carga un grafico para usarlo despues en la creacion de Sprites
|
||||
// Especifica el archivo, ID exclusivo (0 - 255) y medidas del grafico
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadSpriteGfx();
|
||||
void NF_UnloadSpriteGfx(u16 id);
|
||||
// Borra de la RAM un Gfx cargado previamente con NF_LoadSpriteGfx();
|
||||
// Especifica la Id exclusiva (0 - 255) de grafico a borrar.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadSpritePal();
|
||||
void NF_LoadSpritePal(const char* file, u8 id);
|
||||
// Carga una paleta para usarla despues en la creacion de Sprites
|
||||
// Especifica el archivo y ID exclusivo (0 - 63)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadSpritePal();
|
||||
void NF_UnloadSpritePal(u8 id);
|
||||
// Borra de la RAM una Paleta cargada previamente con NF_LoadSpritePal();
|
||||
// Especifica la Id exclusiva (0 - 63) de la paleta a borrar.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_VramSpriteGfx();
|
||||
void NF_VramSpriteGfx(u8 screen, u16 ram, u16 vram, bool keepframes);
|
||||
// Transfiere un Grafico cargado para Sprites a la VRAM
|
||||
// Debes especificar la pantalla, el Id del Grafico en RAM (origen),
|
||||
// la Id del grafico en VRAM (destino) y si, en caso de estar animado,
|
||||
// debe de copiar a la VRAM todos los frames o solo el que este en uso
|
||||
|
||||
|
||||
|
||||
// Funcion NF_FreeSpriteGfx();
|
||||
void NF_FreeSpriteGfx(u8 screen, u16 id);
|
||||
// Borra de la VRAM el Grafico con la Id. especificada.
|
||||
// Cualquier Sprite que este usando ese Gfx, quedara corrupto.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_VramSpriteGfxDefrag();
|
||||
void NF_VramSpriteGfxDefrag(u8 screen);
|
||||
// Desfragmenta la VRAM de Sprites (Gfx) de la pantalla dada
|
||||
// Esta se realiza automaticamente al borrar un Gfx de la VRAM
|
||||
// si la memoria fragmentada es superior a la contigua libre.
|
||||
// Puedes consultar estos valores con las siguientes variables
|
||||
// NF_SPRVRAM[u8 screen].free <- Memoria VRAM de Sprites libre
|
||||
// NF_SPRVRAM[u8 screen].fragmented <- Memoria VRAM de sprites libre fragmentada
|
||||
// NF_SPRVRAM[u8 screen].inarow <- Memoria VRAM de sprites libre, ultimo bloque mas grande
|
||||
// NF_SPRVRAM[u8 screen].lost <- Memoria VRAM libre no usable por fragmentacion
|
||||
|
||||
|
||||
|
||||
// Funcion NF_VramSpritePal();
|
||||
void NF_VramSpritePal(u8 screen, u8 id, u8 slot);
|
||||
// Transfiere una Paleta cargada para Sprites a la VRAM
|
||||
// Debes especificar la pantalla, la Id de la Paleta a trasnferir
|
||||
// y el slot de destino (0 - 15)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_CreateSprite();
|
||||
void NF_CreateSprite(u8 screen, u8 id, u16 gfx, u8 pal, s16 x, s16 y);
|
||||
// Crea un sprite en la pantalla.
|
||||
// Debes especificar la pantalla, la ID del Sprite (0 - 127),
|
||||
// la ID del Grafico que usaras (0 - 255), el slot de paleta (0 - 15),
|
||||
// y las coordenadas donde lo crearas.
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DeleteSprite();
|
||||
void NF_DeleteSprite(u8 screen, u8 id);
|
||||
// Borra un sprite de la pantalla
|
||||
// Debes especificar la pantalla y la Id del Sprite a borrar
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteOamSet();
|
||||
void NF_SpriteOamSet(u8 screen);
|
||||
// Copia los datos del array propio de OAM al OAM real
|
||||
// Debes especificar la pantalla
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteSetPalColor();
|
||||
void NF_SpriteSetPalColor(u8 screen, u8 pal, u8 number, u8 r, u8 g, u8 b);
|
||||
// Cambia el valor de un color de la paleta de sprites especificada.
|
||||
// Debes especificar la pantalla, slot de la paleta en VRAM, numero de color
|
||||
// a cambiar dentro de la paleta y el nuevo valor a darle en formato RGB
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteEditPalColor();
|
||||
void NF_SpriteEditPalColor(u8 screen, u8 pal, u8 number, u8 r, u8 g, u8 b);
|
||||
// Modifica los valores de la paleta seleccionada. Las modificaciones se efectuan
|
||||
// sobre la copia en RAM, por lo que los cambios no seran visibles hasta que se
|
||||
// transfiera la paleta a la VRAM
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteUpdatePalette();
|
||||
void NF_SpriteUpdatePalette(u8 screen, u8 pal);
|
||||
// Actualiza la paleta en VRAM con la copia que se encuentra en la RAM
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteGetPalColor();
|
||||
void NF_SpriteGetPalColor(u8 screen, u8 pal, u8 number, u8* r, u8* g, u8* b);
|
||||
// Obtiene el valor de un color de la paleta que se encuentra en la RAM
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
243
examples/templates/using_nflib/nflib/include/nf_sprite3d.h
Normal file
243
examples/templates/using_nflib/nflib/include/nf_sprite3d.h
Normal file
@ -0,0 +1,243 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_SPRITE3D_H__
|
||||
#define __NF_SPRITE3D_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de funciones 3D
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Defines y variables globales //
|
||||
//////////////////////////////////
|
||||
|
||||
// Numero maximo de sprites en pantalla
|
||||
#define NF_3DSPRITES 256
|
||||
|
||||
// Estructura de control de los sprites 3d
|
||||
typedef struct {
|
||||
s16 x; // Coordenada X
|
||||
s16 y; // Coordenada Y
|
||||
s16 z; // Coordenada Z
|
||||
s16 rx; // Rotacion Eje X (-512/0/512) << 6
|
||||
s16 ry; // Rotacion Eje Y (-512/0/512) << 6
|
||||
s16 rz; // Rotacion Eje Z (-512/0/512) << 6
|
||||
bool rot; // Rotacion en uso
|
||||
u16 sx; // Escala X (0/64/512) << 6
|
||||
u16 sy; // Escala Y (0/64/512) << 6
|
||||
bool scale; // Escalado en uso
|
||||
s16 width; // Ancho del sprite
|
||||
s16 height; // Alto del sprite
|
||||
bool inuse; // Esta en uso?
|
||||
bool show; // Debe mostrarse el sprite?
|
||||
u32 gfx_tex_format; // Guarda el formato de la textura
|
||||
u32 gfx; // Direccion donde esta almacenado el grafico en VRAM
|
||||
u16 gfxid; // Id de Gfx usado
|
||||
u16 frame; // Frame actual
|
||||
u16 newframe; // Frame al que cambiar
|
||||
u16 framesize; // Tamaño del frame (en bytes)
|
||||
u16 lastframe; // Ultimo frame
|
||||
u32 gfx_pal_format; // Guarda el formato de la paleta
|
||||
u32 pal; // Direccion donde esta almacenada la paleta en VRAM
|
||||
u16 palid; // Id de la paleta usada
|
||||
u16 prio; // Prioridad de dibujado del sprite
|
||||
u8 poly_id; // Identificador unico para el Alpha (0 por defecto, 63 prohibido)
|
||||
u8 alpha; // Nivel de alpha (0 - 31) (31 por defecto)
|
||||
} NF_TYPE_3DSPRITE_INFO;
|
||||
extern NF_TYPE_3DSPRITE_INFO NF_3DSPRITE[NF_3DSPRITES];
|
||||
|
||||
// Estructura de control Texturas en VRAM
|
||||
typedef struct {
|
||||
u32 size; // Tamaño (en bytes) del Gfx
|
||||
u16 width; // Ancho del Gfx
|
||||
u16 height; // Altura del Gfx
|
||||
u32 address; // Posicion en la VRAM
|
||||
u16 ramid; // Numero de Slot en RAM del que provienes
|
||||
u16 framesize; // Tamaño del frame (en bytes)
|
||||
u16 lastframe; // Ultimo frame
|
||||
bool keepframes; // Si es un Sprite animado, debes de mantener los frames en RAM ?
|
||||
bool inuse; // Disponibilidat del Slot
|
||||
} NF_TYPE_TEX256VRAM_INFO;
|
||||
extern NF_TYPE_TEX256VRAM_INFO NF_TEX256VRAM[NF_3DSPRITES];
|
||||
|
||||
// Estructura de control de las paletas en VRAM
|
||||
typedef struct {
|
||||
bool inuse; // Slot en uso
|
||||
u8 ramslot; // Paleta original en RAM
|
||||
} NF_TYPE_3DSPRPALSLOT_INFO;
|
||||
extern NF_TYPE_3DSPRPALSLOT_INFO NF_TEXPALSLOT[32];
|
||||
|
||||
// Define la esturctura de control de la VRAM para Sprites 3d
|
||||
typedef struct {
|
||||
s32 free; // Memoria VRAM libre
|
||||
u32 next; // Siguiente posicion libre
|
||||
u32 last; // Ultima posicion usada
|
||||
u32 pos[NF_3DSPRITES]; // Posicion en VRAM para reusar despues de un borrado
|
||||
u32 size[NF_3DSPRITES]; // Tamaño del bloque libre para reusar
|
||||
u16 deleted; // Numero de bloques borrados
|
||||
s32 fragmented; // Memoria VRAM fragmentada
|
||||
s32 inarow; // Memoria VRAM contigua
|
||||
} NF_TYPE_TEXVRAM_INFO;
|
||||
extern NF_TYPE_TEXVRAM_INFO NF_TEXVRAM; // Informacion VRAM de texturas
|
||||
|
||||
|
||||
// Define la estructura de control de los sprites 3d creados
|
||||
typedef struct {
|
||||
s16 total; // Numero de sprites creados
|
||||
u16 id[NF_3DSPRITES]; // ID del Sprite
|
||||
u16 bck[NF_3DSPRITES]; // Backup del ID
|
||||
} NF_TYPE_CREATED_3DSPRITE_INFO;
|
||||
extern NF_TYPE_CREATED_3DSPRITE_INFO NF_CREATED_3DSPRITE;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Init3dSpriteSys();
|
||||
void NF_Init3dSpriteSys(void);
|
||||
// Inicializa el sistema de Sprites en 3D
|
||||
|
||||
|
||||
// Funcion NF_Vram3dSpriteGfx();
|
||||
void NF_Vram3dSpriteGfx(u16 ram, u16 vram, bool keepframes);
|
||||
// Transfiere un grafico de la RAM a la VRAM
|
||||
|
||||
|
||||
// Funcion NF_Free3dSpriteGfx();
|
||||
void NF_Free3dSpriteGfx(u16 id);
|
||||
// Elimina de la VRAM un grafico de texturas y desfragmenta la VRAM si es necesario
|
||||
|
||||
|
||||
// Funcion NF_Vram3dSpriteGfxDefrag();
|
||||
void NF_Vram3dSpriteGfxDefrag(void);
|
||||
// Desfragmenta la VRAM usada para texturas
|
||||
|
||||
|
||||
// Funcion NF_Vram3dSpritePal();
|
||||
void NF_Vram3dSpritePal(u8 id, u8 slot);
|
||||
// Copia una paleta a la VRAM
|
||||
|
||||
|
||||
// Funcion NF_Create3dSprite();
|
||||
void NF_Create3dSprite(u16 id, u16 gfx, u16 pal, s16 x, s16 y);
|
||||
// Crea un Sprite 3D en las coordenadas indicadas
|
||||
|
||||
|
||||
// Funcion NF_Delete3dSprite();
|
||||
void NF_Delete3dSprite(u16 id);
|
||||
// Borra el Sprite con la ID indicada
|
||||
|
||||
|
||||
// Funcion NF_Sort3dSprites();
|
||||
void NF_Sort3dSprites(void);
|
||||
// Reordena la cola de Sprites 3D creados de menor a mayor segun su ID
|
||||
// Los Sprites con numeros mas bajos tienen prioridad.
|
||||
|
||||
|
||||
// Funcion NF_Set3dSpritePriority();
|
||||
void NF_Set3dSpritePriority(u16 id, u16 prio);
|
||||
// Cambia la prioridad del Sprite
|
||||
|
||||
|
||||
// Funcion NF_Swap3dSpritePriority();
|
||||
void NF_Swap3dSpritePriority(u16 id_a, u16 id_b);
|
||||
// Intercambia la prioridad de dos Sprites
|
||||
|
||||
|
||||
// Funcion NF_Move3dSprite();
|
||||
void NF_Move3dSprite(u16 id, s16 x, s16 y);
|
||||
// Mueve el Sprite seleccionado a las coordenadas dadas
|
||||
|
||||
|
||||
// Funcion NF_Show3dSprite();
|
||||
void NF_Show3dSprite(u16 id, bool show);
|
||||
// Muestra u oculta el sprite con la id indicada
|
||||
|
||||
|
||||
// Funcion NF_Set3dSpriteFrame();
|
||||
void NF_Set3dSpriteFrame(u16 id, u16 frame);
|
||||
// Cambia el frame visible del sprite indicado
|
||||
|
||||
|
||||
// Funcion NF_Draw3dSprites();
|
||||
void NF_Draw3dSprites(void);
|
||||
// Dibuja en pantalla todos los sprites creados
|
||||
|
||||
|
||||
// Funcion NF_Update3dSpritesGfx();
|
||||
void NF_Update3dSpritesGfx(void);
|
||||
// Actualiza si es necesario las texturas de los sprites animados
|
||||
|
||||
|
||||
// Funcion NF_Rotate3dSprite();
|
||||
void NF_Rotate3dSprite(u16 id, s16 x, s16 y, s16 z);
|
||||
// Rota el Sprite sobre los ejes indicados (-512/0/512)
|
||||
|
||||
|
||||
// Funcion NF_Scale3dSprite();
|
||||
void NF_Scale3dSprite(u16 id, u16 x, u16 y);
|
||||
// Escala el sprite al tamaño indicado (0/64/512)
|
||||
|
||||
|
||||
// Funcion NF_Blend3dSprite();
|
||||
void NF_Blend3dSprite(u8 sprite, u8 poly_id, u8 alpha);
|
||||
// Habilita y cambia el nivel de alpha de el sprite 3d indicado. Para que la transparencia
|
||||
// sea efectiva entre Sprites, debes especificar un poly_id diferente para cada sprite
|
||||
// (entre 1 y 62). El rango de alpha es de 0 a 31, siendo 31 opaco. Para eliminar la
|
||||
// transparencia, selecciona un valor para alpha de 31 o especifica como poly_id el nº 0.
|
||||
|
||||
|
||||
// Funcion NF_3dSpritesLayer();
|
||||
void NF_3dSpritesLayer(u8 layer);
|
||||
// Selecciona la capa en la que se dibujaran los Sprites 3D. (0 - 3)
|
||||
// En realidad los Sprites 3D siempre se dibujan sobre la CAPA 0, esta funcion solo cambia
|
||||
// la prioridad de esta capa sobre las demas.
|
||||
|
||||
|
||||
// Funcion NF_3dSpriteEditPalColor();
|
||||
void NF_3dSpriteEditPalColor(u8 pal, u8 number, u8 r, u8 g, u8 b);
|
||||
// Modifica los valores de la paleta seleccionada. Las modificaciones se efectuan
|
||||
// sobre la copia en RAM, por lo que los cambios no seran visibles hasta que se
|
||||
// transfiera la paleta a la VRAM
|
||||
|
||||
|
||||
// Funcion NF_3dSpriteUpdatePalette();
|
||||
void NF_3dSpriteUpdatePalette(u8 pal);
|
||||
// Actualiza la paleta en VRAM con la copia que se encuentra en la RAM
|
||||
|
||||
|
||||
// Funcion NF_3dSpriteGetPalColor();
|
||||
void NF_3dSpriteGetPalColor(u8 pal, u8 number, u8* r, u8* g, u8* b);
|
||||
// Obtiene el valor de un color de la paleta que se encuentra en la RAM
|
||||
|
||||
|
||||
// Funcion NF_3dSpriteSetDeep();
|
||||
void NF_3dSpriteSetDeep(u8 id, s16 z);
|
||||
// Cambia la profuncidad de dibujado (z) del sprite (-512/0/512),
|
||||
// siendo -512 el punto mas cercano, 0 el centro por defecto
|
||||
// y 512 el punto mas lejano.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
124
examples/templates/using_nflib/nflib/include/nf_text.h
Normal file
124
examples/templates/using_nflib/nflib/include/nf_text.h
Normal file
@ -0,0 +1,124 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_TEXT_H__
|
||||
#define __NF_TEXT_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de Textos
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
// Define el nº de caracteres que tiene la fuente
|
||||
#define NF_TEXT_FONT_CHARS 127
|
||||
#define NF_TEXT_FONT_LAST_VALID_CHAR 113
|
||||
|
||||
|
||||
// Define la estructura de control de textos
|
||||
typedef struct {
|
||||
u16 width; // Ultimo tile de la fila (0 - x) 32 tiles serian 0 - 31
|
||||
u16 height; // Ultimo tile de la columna (0 - y)
|
||||
u8 rotation; // Rotacion del texto
|
||||
u8 slot; // Slot donde esta cargado el tileset de esta capa de texto
|
||||
u8 pal; // Paleta que usara el texto (0 por defecto)
|
||||
bool exist; // Existe la capa de texto?
|
||||
bool update; // Tienes que actualizar la capa?
|
||||
} NF_TYPE_TEXT_INFO;
|
||||
extern NF_TYPE_TEXT_INFO NF_TEXT[2][4]; // Datos de las capas de texto
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitTextSys();
|
||||
void NF_InitTextSys(u8 screen);
|
||||
// Inicializa el sistema de Texto para la pantalla dada
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadTextFont();
|
||||
void NF_LoadTextFont(const char* file, const char* name, u16 width, u16 height, u8 rotation);
|
||||
// Carga una fuente para usar como texto
|
||||
// La fuente se cargara en un slot libre de fondos tileados
|
||||
// Debes especificar el archivos sin extension y un nombre para referenciarla
|
||||
// En caso de que la fuente tenga los sets de rotacion a izquierda y derecha,
|
||||
// especificar 1 o 2 en el parametro "rot". 0 carga la fuente sin rotacion
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadTextFont();
|
||||
void NF_UnloadTextFont(const char* name);
|
||||
// Borra un fuente cargada en RAM
|
||||
// Esta funcion simplemente llama a NF_UnloadTiledBg(); para su borrado
|
||||
|
||||
|
||||
|
||||
// Funcion NF_CreateTextLayer();
|
||||
void NF_CreateTextLayer(u8 screen, u8 layer, u8 rotation, const char* name);
|
||||
// Crea un fondo tileado para usarlo con texto
|
||||
// Esta funcion simplemente llama a NF_CreateTiledBg(); para su creacion
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DeleteTextLayer();
|
||||
void NF_DeleteTextLayer(u8 screen, u8 layer);
|
||||
// Borra un fondo usado como capa de texto y sus buffers y variables asociadas
|
||||
|
||||
|
||||
|
||||
// Funcion NF_WriteText();
|
||||
void NF_WriteText(u8 screen, u8 layer, u16 x, u16 y, const char* text);
|
||||
// Escribe un texto en el buffer de texto de la pantalla y capa seleccionada
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UpdateTextLayers();
|
||||
void NF_UpdateTextLayers(void);
|
||||
// Copia el buffer de texto a la VRAM en las capas que sea necesario
|
||||
// realizar una actualizacion
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ClearTextLayer();
|
||||
void NF_ClearTextLayer(u8 screen, u8 layer);
|
||||
// Borra el contanido de la capa de texto seleccionada
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DefineTextColor();
|
||||
void NF_DefineTextColor(u8 screen, u8 layer, u8 color, u8 r, u8 g, u8 b);
|
||||
// Define uno de los 16 colores disponibles para texto, en formato RGB
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Function NF_SetTextColor();
|
||||
void NF_SetTextColor(u8 screen, u8 layer, u8 color);
|
||||
// Selecciona con que color definido se escribira el texto (no cambia el color del texto ya escrito)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
64
examples/templates/using_nflib/nflib/include/nf_text16.h
Normal file
64
examples/templates/using_nflib/nflib/include/nf_text16.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_TEXT16_H__
|
||||
#define __NF_TEXT16_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de Textos de 16 pixels
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
// Define el nº de caracteres que tiene la fuente
|
||||
#define NF_TEXT_FONT_CHARS_16 127
|
||||
#define NF_TEXT_FONT_LAST_VALID_CHAR_16 113
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadTextFont16();
|
||||
void NF_LoadTextFont16(const char* file, const char* name, u16 width, u16 height, u8 rotation);
|
||||
// Carga una fuente para texto de 16 pixeles de altura
|
||||
|
||||
|
||||
|
||||
// Funcion NF_CreateTextLayer16();
|
||||
void NF_CreateTextLayer16(u8 screen, u8 layer, u8 rotation, const char* name);
|
||||
// Crea una capa de texto para fuentes de 16 pixeles
|
||||
|
||||
|
||||
|
||||
// Funcion NF_WriteText16();
|
||||
void NF_WriteText16(u8 screen, u8 layer, u16 x, u16 y, const char* text);
|
||||
// Escribe un texto en la capa y pantalla especificados
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ClearTextLayer16();
|
||||
void NF_ClearTextLayer16(u8 screen, u8 layer);
|
||||
// Limpia la capa de texto especificada
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
320
examples/templates/using_nflib/nflib/include/nf_tiledbg.h
Normal file
320
examples/templates/using_nflib/nflib/include/nf_tiledbg.h
Normal file
@ -0,0 +1,320 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __NF_TILEDBG_H__
|
||||
#define __NF_TILEDBG_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NightFox LIB - Include de Fondos con tiles
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Define los slots maximos para los fondos
|
||||
#define NF_SLOTS_TBG 64 // Datos de los fondos
|
||||
#define NF_SLOTS_EXBGPAL 128 // Paletas extendidas (maximo 16 paletas por fondo)
|
||||
|
||||
// Define el numero maximo de bancos para tiles y mapas
|
||||
#define NF_MAX_BANKS_TILES 8
|
||||
#define NF_MAX_BANKS_MAPS 16
|
||||
|
||||
// Define el numero de bancos de Mapas y Tiles
|
||||
extern u8 NF_BANKS_TILES[2]; // (1 banks = 16kb) Cada banco de tiles puede alvergar 8 bancos de Mapas
|
||||
extern u8 NF_BANKS_MAPS[2]; // (1 bank = 2kb) Usar multiplos de 8. Cada set de 8 bancos consume 1 banco de tiles
|
||||
|
||||
// Define los Buffers para almacenar los fondos
|
||||
extern char* NF_BUFFER_BGTILES[NF_SLOTS_TBG];
|
||||
extern char* NF_BUFFER_BGMAP[NF_SLOTS_TBG];
|
||||
extern char* NF_BUFFER_BGPAL[NF_SLOTS_TBG];
|
||||
|
||||
|
||||
// Define estructura para almacenar la info de los fondos
|
||||
typedef struct {
|
||||
char name[32]; // Nombre del fondo
|
||||
u32 tilesize; // Tamaño del Tileset
|
||||
u32 mapsize; // Tamaño del Map
|
||||
u32 palsize; // Tamaño de la Paleta
|
||||
u16 width; // Ancho del fondo
|
||||
u16 height; // Altura del fondo
|
||||
bool available; // Disponibilidat del Slot
|
||||
} NF_TYPE_TBG_INFO;
|
||||
extern NF_TYPE_TBG_INFO NF_TILEDBG[NF_SLOTS_TBG]; // Datos de los fondos
|
||||
|
||||
// Define la estructura para almacenar la info y datos de las paletas extendidas
|
||||
typedef struct {
|
||||
char* buffer; // Buffer para almacenar la paleta
|
||||
u32 palsize; // Tamaño de la paleta
|
||||
bool inuse; // Slot libre o en uso
|
||||
} NF_TYPE_EXBGPAL_INFO;
|
||||
extern NF_TYPE_EXBGPAL_INFO NF_EXBGPAL[NF_SLOTS_EXBGPAL]; // Datos de las paletas extendidas
|
||||
|
||||
// Define estructura para almacenar la info de los fondos en pantalla
|
||||
typedef struct {
|
||||
u8 tilebase; // Bloque de inicio en VRAM del Tileset
|
||||
u8 tileblocks; // Bloques usados por el Tileset
|
||||
u8 mapbase; // Bloque de inicio en VRAM del Map
|
||||
u8 mapblocks; // Bloques usados por el Map
|
||||
u16 bgwidth; // Ancho del fondo
|
||||
u16 bgheight; // Altura del fondo
|
||||
u16 mapwidth; // Ancho del mapa
|
||||
u16 mapheight; // Altura del mapa
|
||||
u8 bgtype; // Tipo de mapa
|
||||
u8 bgslot; // Buffer de graficos usado (NF_BUFFER_BGMAP)
|
||||
u8 blockx; // Bloque de mapa (horizontal)
|
||||
u8 blocky; // bloque de mapa (vertical)
|
||||
bool created; // Flag de si esta creado
|
||||
} NF_TYPE_TBGLAYERS_INFO;
|
||||
// El hardware de la DS no permite mapas mayores de 512x512
|
||||
// Asi que informaremos si nuestor mapa lo gestionara el hardware si es menor o
|
||||
// igual a 512x512, o usaremos nuestro motor de Tile Swaping
|
||||
// bgtype 0: Normal (maximo 512 x 512)
|
||||
// bgtype 1: >512 x 256
|
||||
// bgtype 2: 256 x >512
|
||||
// bgtype 3: >512 x >512
|
||||
extern NF_TYPE_TBGLAYERS_INFO NF_TILEDBG_LAYERS[2][4]; //[screen][layer]
|
||||
|
||||
|
||||
|
||||
// Define el array de bloques libres
|
||||
extern u8 NF_TILEBLOCKS[2][NF_MAX_BANKS_TILES];
|
||||
extern u8 NF_MAPBLOCKS[2][NF_MAX_BANKS_MAPS];
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitTiledBgBuffers();
|
||||
void NF_InitTiledBgBuffers(void);
|
||||
// Inicializa los buffers y estructuras de control para usar los fondos "tileados"
|
||||
// Se debe usar antes de cargar o usar cualquier fondo
|
||||
// No uses esta funcion mas de una vez en tu codigo
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ResetTiledBgBuffers();
|
||||
void NF_ResetTiledBgBuffers(void);
|
||||
// Borra todos los buffers y reinicia las estructuras de fondos "tileados"
|
||||
// Usala para los cambios de nivel y similares
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitTiledBgSys();
|
||||
void NF_InitTiledBgSys(u8 screen);
|
||||
// Inicializa las variables de control de tiles, mapas y paletas
|
||||
// Asigna 128kb de RAM para fondos tileados
|
||||
// Se debe especificar la pantalla (0 o 1)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadTiledBg();
|
||||
void NF_LoadTiledBg(const char* file, const char* name, u16 width, u16 height);
|
||||
// Carga un fondo tileado desde FAT
|
||||
// Debes de especificar el archivo que se cargara (sin extension) y el nombre
|
||||
// que le quieres dar y las medidas en pixeles
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadTilesForBg();
|
||||
void NF_LoadTilesForBg(const char* file, const char* name, u16 width, u16 height, u16 tile_start, u16 tile_end);
|
||||
// Carga desde la FAT los tiles especificados y su paleta
|
||||
// Ademas, crea un mapa vacio de la medida especificada
|
||||
// Esta funcion es util para cargar varios tiles y despues generar fondos
|
||||
// modificando el MAP desde cogido (Generador de escenarios, animaciones, etc)
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadTiledBg();
|
||||
void NF_UnloadTiledBg(const char* name);
|
||||
// Borra de la RAM un fondo cargado con NF_LoadTiledBg();
|
||||
// Debes especificar el nombre que le diste al fondo
|
||||
|
||||
|
||||
|
||||
// Funcion NF_CreateTiledBg();
|
||||
void NF_CreateTiledBg(u8 screen, u8 layer, const char* name);
|
||||
// Crea un fondo con los parametros dados, indicale la pantalla, capa y nombre
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DeleteTiledBg();
|
||||
void NF_DeleteTiledBg(u8 screen, u8 layer);
|
||||
// Borra un fondo de la memoria VRAM
|
||||
// Debes especificar la pantalla y numero de capa
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetTileMapAddress();
|
||||
extern u32 NF_GetTileMapAddress(u8 screen, u8 layer, u16 tile_x, u16 tile_y);
|
||||
// Funcion de uso interno de la libreria
|
||||
// Devuelve la direccion en el buffer de un tile concreto
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetTileOfMap();
|
||||
extern u16 NF_GetTileOfMap(u8 screen, u8 layer, u16 tile_x, u16 tile_y);
|
||||
// Obten el valor del tile del mapa indicado en las coordenadas (en tiles) indicadas.
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SetTileOfMap();
|
||||
void NF_SetTileOfMap(u8 screen, u8 layer, u16 tile_x, u16 tile_y, u16 tile);
|
||||
// Cambia el valor del tile del mapa indicado en las coordenadas (en tiles) indicadas.
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UpdateVramMap();
|
||||
void NF_UpdateVramMap(u8 screen, u8 layer);
|
||||
// Actualiza en VRAM el contenido del mapa seleccionado.
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_BgSetPalColor();
|
||||
void NF_BgSetPalColor(u8 screen, u8 layer, u8 number, u8 r, u8 g, u8 b);
|
||||
// Cambia al momento el valor de un color de la paleta
|
||||
// Cuidado! Funcion Muy lenta, usar solo para 2 o 3 colores por ciclo
|
||||
// Cambia el color directamente en la VRAM
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_BgEditPalColor();
|
||||
void NF_BgEditPalColor(u8 screen, u8 layer, u8 number, u8 r, u8 g, u8 b);
|
||||
// Edita un color de la paleta seleccionada.
|
||||
// El color se edita en el buffer de RAM, para que sea efectivo,
|
||||
// mandala a la VRAM con NF_UpdatePalette();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_BgUpdatePalette();
|
||||
void NF_BgUpdatePalette(u8 screen, u8 layer);
|
||||
// Actualiza la paleta en VRAM con la que se encuentra en el buffer de RAM
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_BgGetPalColor();
|
||||
void NF_BgGetPalColor(u8 screen, u8 layer, u8 number, u8* r, u8* g, u8* b);
|
||||
// Obtiene el valor de un color de la paleta que se encuentra en la RAM
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetTilePal();
|
||||
extern u8 NF_GetTilePal(u8 screen, u8 layer, u16 tile_x, u16 tile_y);
|
||||
// Devuelve que numero de paleta (0 - 15) esta usando el tile del fondo especificado.
|
||||
// Por defecto, todos los tiles usan la paleta del Slot nº0
|
||||
// Los datos se obtienen de la compia en RAM del mapa del fondo.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SetTilePal();
|
||||
void NF_SetTilePal(u8 screen, u8 layer, u16 tile_x, u16 tile_y, u8 pal);
|
||||
// Cambia el numero de paleta (0 - 15) que usara el tile del fondo especificado.
|
||||
// Por defecto, todos los tiles usan la paleta del Slot nº0
|
||||
// Los datos se escriben de la compia en RAM del mapa del fondo, por lo que no seran
|
||||
// visibles hasta que ejecutes la funcion NF_UpdateVramMap();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadExBgPal();
|
||||
void NF_LoadExBgPal(const char* file, u8 slot);
|
||||
// Carga en el buffer de RAM correspondiente una paleta de fondos, para poderla usar
|
||||
// mas tarde como paleta extendida.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadExBgPal();
|
||||
void NF_UnloadExBgPal(u8 slot);
|
||||
// Borra de la RAM la paleta del slot especificado.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_VramExBgPal();
|
||||
void NF_VramExBgPal(u8 screen, u8 layer, u8 id, u8 slot);
|
||||
// Transfiere a la VRAM una paleta extendida en el slot de la pantalla y
|
||||
// fondo especificados.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SetExBgPal();
|
||||
void NF_SetExBgPal(u8 screen, u8 layer, u8 pal);
|
||||
// Cambia la paleta extendida que usara un fondo.
|
||||
// La paleta debe de estar transferida en la VRAM previamente
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SetTileHflip();
|
||||
void NF_SetTileHflip(u8 screen, u8 layer, u16 tile_x, u16 tile_y);
|
||||
// Invierte horizontalmente el estado actual del tile seleccionado
|
||||
// Los cambios no seran visibles hasta que actualices el mapa
|
||||
// con la funcion NF_UpdateVramMap();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SetTileVflip();
|
||||
void NF_SetTileVflip(u8 screen, u8 layer, u16 tile_x, u16 tile_y);
|
||||
// Invierte verticalmente el estado actual del tile seleccionado
|
||||
// Los cambios no seran visibles hasta que actualices el mapa
|
||||
// con la funcion NF_UpdateVramMap();
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_RotateTileGfx();
|
||||
void NF_RotateTileGfx(u8 slot, u16 tile, u8 rotation);
|
||||
// Rota el grafico de un tile especificado. Rota el tile almacenado en un buffer de fondos
|
||||
// que se encuentra en RAM. Debes especificar el SLOT del buffer, numero de tile en el buffer
|
||||
// y el angulo de la rotacion.
|
||||
// 1 - 90º a la derecha
|
||||
// 2 - 90º a la izquierda
|
||||
// 3 - 180º
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
511
examples/templates/using_nflib/nflib/source/nf_2d.c
Normal file
511
examples/templates/using_nflib/nflib/source/nf_2d.c
Normal file
@ -0,0 +1,511 @@
|
||||
|
||||
// NightFox LIB - Funciones 2D comunes
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_basic.h"
|
||||
#include "nf_2d.h"
|
||||
#include "nf_tiledbg.h"
|
||||
#include "nf_sprite256.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Set2D();
|
||||
void NF_Set2D(u8 screen, u8 mode) {
|
||||
|
||||
if (screen == 0) { // Pantalla Superior
|
||||
|
||||
switch (mode) { // Selecciona modo
|
||||
case 0:
|
||||
videoSetMode(MODE_0_2D);
|
||||
break;
|
||||
case 2:
|
||||
videoSetMode(MODE_2_2D);
|
||||
break;
|
||||
case 5:
|
||||
videoSetMode(MODE_5_2D);
|
||||
break;
|
||||
}
|
||||
|
||||
} else { // Pantalla inferior
|
||||
|
||||
switch (mode) { // Seleccion modo
|
||||
case 0:
|
||||
videoSetModeSub(MODE_0_2D);
|
||||
break;
|
||||
case 2:
|
||||
videoSetModeSub(MODE_2_2D);
|
||||
break;
|
||||
case 5:
|
||||
videoSetModeSub(MODE_5_2D);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ShowBg();
|
||||
void NF_ShowBg(u8 screen, u8 layer) {
|
||||
|
||||
if (screen == 0) { // Pantalla Superior
|
||||
|
||||
switch (layer) { // Segun la capa
|
||||
case 0:
|
||||
REG_DISPCNT |= (DISPLAY_BG0_ACTIVE);
|
||||
break;
|
||||
case 1:
|
||||
REG_DISPCNT |= (DISPLAY_BG1_ACTIVE);
|
||||
break;
|
||||
case 2:
|
||||
REG_DISPCNT |= (DISPLAY_BG2_ACTIVE);
|
||||
break;
|
||||
case 3:
|
||||
REG_DISPCNT |= (DISPLAY_BG3_ACTIVE);
|
||||
break;
|
||||
}
|
||||
|
||||
} else { // Pantalla Inferior
|
||||
|
||||
switch (layer) { // Segun la capa
|
||||
case 0:
|
||||
REG_DISPCNT_SUB |= (DISPLAY_BG0_ACTIVE);
|
||||
break;
|
||||
case 1:
|
||||
REG_DISPCNT_SUB |= (DISPLAY_BG1_ACTIVE);
|
||||
break;
|
||||
case 2:
|
||||
REG_DISPCNT_SUB |= (DISPLAY_BG2_ACTIVE);
|
||||
break;
|
||||
case 3:
|
||||
REG_DISPCNT_SUB |= (DISPLAY_BG3_ACTIVE);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_HideBg();
|
||||
void NF_HideBg(u8 screen, u8 layer) {
|
||||
|
||||
if (screen == 0) { // Pantalla Superior
|
||||
|
||||
switch (layer) { // Segun la capa
|
||||
case 0:
|
||||
REG_DISPCNT &= ~(DISPLAY_BG0_ACTIVE);
|
||||
break;
|
||||
case 1:
|
||||
REG_DISPCNT &= ~(DISPLAY_BG1_ACTIVE);
|
||||
break;
|
||||
case 2:
|
||||
REG_DISPCNT &= ~(DISPLAY_BG2_ACTIVE);
|
||||
break;
|
||||
case 3:
|
||||
REG_DISPCNT &= ~(DISPLAY_BG3_ACTIVE);
|
||||
break;
|
||||
}
|
||||
|
||||
} else { // Pantalla Inferior
|
||||
|
||||
switch (layer) { // Segun la capa
|
||||
case 0:
|
||||
REG_DISPCNT_SUB &= ~(DISPLAY_BG0_ACTIVE);
|
||||
break;
|
||||
case 1:
|
||||
REG_DISPCNT_SUB &= ~(DISPLAY_BG1_ACTIVE);
|
||||
break;
|
||||
case 2:
|
||||
REG_DISPCNT_SUB &= ~(DISPLAY_BG2_ACTIVE);
|
||||
break;
|
||||
case 3:
|
||||
REG_DISPCNT_SUB &= ~(DISPLAY_BG3_ACTIVE);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ScrollBg();
|
||||
void NF_ScrollBg(u8 screen, u8 layer, s16 x, s16 y) {
|
||||
|
||||
// Variables temporales
|
||||
s16 sx = x;
|
||||
s16 sy = y;
|
||||
|
||||
// Si el mapa es infinito... > 512
|
||||
if (NF_TILEDBG_LAYERS[screen][layer].bgtype > 0) {
|
||||
|
||||
// Variables temporales de Fondos infinitos
|
||||
u32 address = 0; // Puntero a la VRAM
|
||||
u16 blockx = 0; // Nº de bloque en pantalla
|
||||
u16 blocky = 0;
|
||||
u32 mapmovex = 0; // Desplazamiento de la copia de datos (block x 2048)
|
||||
u32 mapmovey = 0;
|
||||
u16 rowsize = 0; // Calcula el espacio ocupado en RAM por cada fila
|
||||
|
||||
// Calcula la direccion base del mapa
|
||||
if (screen == 0) { // (VRAM_A)
|
||||
address = (0x6000000) + (NF_TILEDBG_LAYERS[screen][layer].mapbase << 11);
|
||||
} else { // (VRAM_C)
|
||||
address = (0x6200000) + (NF_TILEDBG_LAYERS[screen][layer].mapbase << 11);
|
||||
}
|
||||
|
||||
// Ajusta el valor maximo de las variables a los limites del scroll
|
||||
if (sx < 0) {
|
||||
sx = 0;
|
||||
}
|
||||
if (sx > (NF_TILEDBG_LAYERS[screen][layer].bgwidth - 256)) {
|
||||
sx = (NF_TILEDBG_LAYERS[screen][layer].bgwidth - 256);
|
||||
}
|
||||
if (sy < 0) {
|
||||
sy = 0;
|
||||
}
|
||||
if (sy > (NF_TILEDBG_LAYERS[screen][layer].bgheight - 192)) {
|
||||
sy = (NF_TILEDBG_LAYERS[screen][layer].bgheight - 192);
|
||||
}
|
||||
|
||||
// Segun el tipo de mapa...
|
||||
switch (NF_TILEDBG_LAYERS[screen][layer].bgtype) {
|
||||
|
||||
case 1: // 512x256 - Bloque A y B (32x32) + (32x32) (2kb x 2 = 4kb)
|
||||
// Calcula el bloque
|
||||
blockx = (x >> 8);
|
||||
// Si has cambiado de bloque...
|
||||
if (NF_TILEDBG_LAYERS[screen][layer].blockx != blockx) {
|
||||
// Calcula el desplazamiento de datos
|
||||
mapmovex = (blockx << 11);
|
||||
// Copias los Bloques A y B (32x32) + (32x32) (2kb x 2 = 4kb)
|
||||
NF_DmaMemCopy((void*)address, (NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovex), 4096);
|
||||
// Y actualiza el bloque actual
|
||||
NF_TILEDBG_LAYERS[screen][layer].blockx = blockx;
|
||||
}
|
||||
// Calcula la X del fondo
|
||||
sx = x - (blockx << 8);
|
||||
break;
|
||||
|
||||
case 2: // 256x512 - Bloque A (32x64) (2kb x 2 = 4kb)
|
||||
// Calcula el bloque
|
||||
blocky = (y >> 8);
|
||||
// Si has cambiado de bloque...
|
||||
if (NF_TILEDBG_LAYERS[screen][layer].blocky != blocky) {
|
||||
// Calcula el desplazamiento de datos
|
||||
mapmovey = (blocky << 11);
|
||||
// Copias los Bloques A y B (32x32) + (32x32) (2kb x 2 = 4kb)
|
||||
NF_DmaMemCopy((void*)address, (NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovey), 4096);
|
||||
// Y actualiza el bloque actual
|
||||
NF_TILEDBG_LAYERS[screen][layer].blocky = blocky;
|
||||
}
|
||||
// Calcula la X del fondo
|
||||
sy = y - (blocky << 8);
|
||||
break;
|
||||
|
||||
case 3: // >512x>512
|
||||
rowsize = (((((NF_TILEDBG_LAYERS[screen][layer].bgwidth - 1) >> 8)) + 1) << 11);
|
||||
// Calcula los bloques
|
||||
blockx = (x >> 8);
|
||||
blocky = (y >> 8);
|
||||
if ( // Si se ha cambiado de bloque en alguna direccion...
|
||||
(NF_TILEDBG_LAYERS[screen][layer].blockx != blockx)
|
||||
||
|
||||
(NF_TILEDBG_LAYERS[screen][layer].blocky != blocky)
|
||||
) {
|
||||
// Y el desplazamiento de datos
|
||||
mapmovex = (blocky * rowsize) + (blockx << 11);
|
||||
mapmovey = mapmovex + rowsize;
|
||||
// Bloque A y B (32x32) + (32x32) (2kb x 2 = 4kb)
|
||||
NF_DmaMemCopy((void*)address, (NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovex), 4096);
|
||||
// Bloque (+4096) C y D (32x32) + (32x32) (2kb x 2 = 4kb)
|
||||
NF_DmaMemCopy((void*)(address + 4096), (NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovey), 4096);
|
||||
// Y actualiza el bloque actual
|
||||
NF_TILEDBG_LAYERS[screen][layer].blockx = blockx;
|
||||
NF_TILEDBG_LAYERS[screen][layer].blocky = blocky;
|
||||
}
|
||||
// Calcula la X e Y del fondo
|
||||
sx = x - (blockx << 8);
|
||||
sy = y - (blocky << 8);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Mueve el fondo usando los registros
|
||||
if (screen == 0) { // Pantalla Superior
|
||||
|
||||
switch (layer) { // Segun la capa
|
||||
case 0:
|
||||
REG_BG0HOFS = sx;
|
||||
REG_BG0VOFS = sy;
|
||||
break;
|
||||
case 1:
|
||||
REG_BG1HOFS = sx;
|
||||
REG_BG1VOFS = sy;
|
||||
break;
|
||||
case 2:
|
||||
REG_BG2HOFS = sx;
|
||||
REG_BG2VOFS = sy;
|
||||
break;
|
||||
case 3:
|
||||
REG_BG3HOFS = sx;
|
||||
REG_BG3VOFS = sy;
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
switch (layer) { // Segun la capa
|
||||
case 0:
|
||||
REG_BG0HOFS_SUB = sx;
|
||||
REG_BG0VOFS_SUB = sy;
|
||||
break;
|
||||
case 1:
|
||||
REG_BG1HOFS_SUB = sx;
|
||||
REG_BG1VOFS_SUB = sy;
|
||||
break;
|
||||
case 2:
|
||||
REG_BG2HOFS_SUB = sx;
|
||||
REG_BG2VOFS_SUB = sy;
|
||||
break;
|
||||
case 3:
|
||||
REG_BG3HOFS_SUB = sx;
|
||||
REG_BG3VOFS_SUB = sy;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_MoveSprite();
|
||||
void NF_MoveSprite(u8 screen, u8 id, s16 x, s16 y) {
|
||||
|
||||
NF_SPRITEOAM[screen][id].x = x; // Coordenada X
|
||||
NF_SPRITEOAM[screen][id].y = y; // Coordenada Y
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteLayer();
|
||||
void NF_SpriteLayer(u8 screen, u8 id, u8 layer) {
|
||||
|
||||
NF_SPRITEOAM[screen][id].layer = layer; // Capa sobre la que esta el sprite
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ShowSprite();
|
||||
void NF_ShowSprite(u8 screen, u8 id, bool show) {
|
||||
|
||||
NF_SPRITEOAM[screen][id].hide = !show; // Muestra o oculta el sprite
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_HflipSprite();
|
||||
void NF_HflipSprite(u8 screen, u8 id, bool hflip) {
|
||||
|
||||
NF_SPRITEOAM[screen][id].hflip = hflip; // Volteado horizontal;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetSpriteHflip();
|
||||
bool NF_GetSpriteHflip(u8 screen, u8 id) {
|
||||
return NF_SPRITEOAM[screen][id].hflip;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_VflipSprite();
|
||||
void NF_VflipSprite(u8 screen, u8 id, bool vflip) {
|
||||
|
||||
NF_SPRITEOAM[screen][id].vflip = vflip; // Volteado vertical;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetSpriteVflip();
|
||||
bool NF_GetSpriteVflip(u8 screen, u8 id) {
|
||||
return NF_SPRITEOAM[screen][id].vflip;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteFrame();
|
||||
void NF_SpriteFrame(u8 screen, u8 id, u16 frame) {
|
||||
|
||||
// Verifica el rango de Id's de Sprites
|
||||
if ((id < 0) || (id > 127)) {
|
||||
NF_Error(106, "Sprite", 127);
|
||||
}
|
||||
|
||||
// Verifica el rango de frames del Sprite
|
||||
if (frame > NF_SPRITEOAM[screen][id].lastframe) {
|
||||
NF_Error(106, "Sprite frame", NF_SPRITEOAM[screen][id].lastframe);
|
||||
}
|
||||
|
||||
|
||||
// Verifica si el frame necesita ser actualizado
|
||||
if (NF_SPRITEOAM[screen][id].frame != frame) {
|
||||
|
||||
// Si debes de copiar el nuevo frame desde la RAM a la VRAM...
|
||||
if (NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].keepframes) {
|
||||
|
||||
// Variables temporales
|
||||
char* source; // Puntero de origen
|
||||
u32 destination = 0; // Puntero de destino
|
||||
u16 ramid = 0; // Slot de RAM donde se encuentra el Gfx
|
||||
|
||||
// Calcula el origen y destino del nuevo frame a copiar
|
||||
ramid = NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].ramid;
|
||||
source = NF_BUFFER_SPR256GFX[ramid] + (NF_SPRITEOAM[screen][id].framesize * frame);
|
||||
destination = NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].address;
|
||||
|
||||
// Copialo
|
||||
NF_DmaMemCopy((void*)destination, source, NF_SPRITEOAM[screen][id].framesize);
|
||||
|
||||
} else { // Si todos los frames ya estan en VRAM...
|
||||
|
||||
// Calcula la direccion del Gfx del frame
|
||||
u32 address = 0;
|
||||
address = NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].address + (NF_SPRITEOAM[screen][id].framesize * frame);
|
||||
NF_SPRITEOAM[screen][id].gfx = (u32*)address;
|
||||
|
||||
}
|
||||
|
||||
// Almacena el frame actual
|
||||
NF_SPRITEOAM[screen][id].frame = frame;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_EnableSpriteRotScale();
|
||||
void NF_EnableSpriteRotScale(u8 screen, u8 sprite, u8 id, bool doublesize) {
|
||||
|
||||
// Verifica el rango de Id's de Sprites
|
||||
if ((sprite < 0) || (sprite > 127)) {
|
||||
NF_Error(106, "Sprite", 127);
|
||||
}
|
||||
|
||||
// Verifica el rango de Id's de Rotacion
|
||||
if ((id < 0) || (id > 31)) {
|
||||
NF_Error(106, "RotScale", 127);
|
||||
}
|
||||
|
||||
// Verifica si el Sprite esta creado
|
||||
if (!NF_SPRITEOAM[screen][sprite].created) {
|
||||
char text[4];
|
||||
sprintf(text, "%d", screen);
|
||||
NF_Error(112, text, sprite);
|
||||
}
|
||||
|
||||
NF_SPRITEOAM[screen][sprite].rot = id; // Id de rotacion (-1 ninguno) (0 - 31 Id de rotacion)
|
||||
NF_SPRITEOAM[screen][sprite].doublesize = doublesize; // Usar el "double size" al rotar ? ("NO" por defecto)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DisableSpriteRotScale();
|
||||
void NF_DisableSpriteRotScale(u8 screen, u8 sprite) {
|
||||
|
||||
// Verifica el rango de Id's de Sprites
|
||||
if ((sprite < 0) || (sprite > 127)) {
|
||||
NF_Error(106, "Sprite", 127);
|
||||
}
|
||||
|
||||
// Verifica si el Sprite esta creado
|
||||
if (!NF_SPRITEOAM[screen][sprite].created) {
|
||||
char text[4];
|
||||
sprintf(text, "%d", screen);
|
||||
NF_Error(112, text, sprite);
|
||||
}
|
||||
|
||||
NF_SPRITEOAM[screen][sprite].rot = -1; // Id de rotacion (-1 ninguno) (0 - 31 Id de rotacion)
|
||||
NF_SPRITEOAM[screen][sprite].doublesize = false; // Usar el "double size" al rotar ? ("NO" por defecto)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteRotScale();
|
||||
void NF_SpriteRotScale(u8 screen, u8 id, s16 angle, u16 sx, u16 sy) {
|
||||
|
||||
// Variables temporales
|
||||
s16 in = 0; // Angulo dado
|
||||
s16 out = 0; // Angulo convertido
|
||||
|
||||
in = angle;
|
||||
|
||||
// Limites del angulo
|
||||
if (in < -512) {
|
||||
in += 512;
|
||||
}
|
||||
if (in > 512) {
|
||||
in -= 512;
|
||||
}
|
||||
// Limites del factor X
|
||||
if (sx < 0) {
|
||||
sx = 0;
|
||||
}
|
||||
if (sx > 512) {
|
||||
sx = 512;
|
||||
}
|
||||
// Limites del factor Y
|
||||
if (sy < 0) {
|
||||
sy = 0;
|
||||
}
|
||||
if (sy > 512) {
|
||||
sy = 512;
|
||||
}
|
||||
|
||||
// Si es un numero negativo...
|
||||
if (in < 0) {
|
||||
in = -in; // Pasa a positivo (para poder hacer el bitshift)
|
||||
out = (in << 6); // (in * 64); Pasa de base 512 a base 32768
|
||||
// Dejalo en positivo para que <0 gire a la izquierda
|
||||
} else {
|
||||
out = (in << 6);
|
||||
out = -out; // Pasalo a negativo para que >0 gire a la derecha
|
||||
}
|
||||
|
||||
// Actualiza el RotScale del OAM
|
||||
if (screen == 0) {
|
||||
oamRotateScale(&oamMain, id, out, (512 - sx), (512 - sy));
|
||||
} else {
|
||||
oamRotateScale(&oamSub, id, out, (512 - sx), (512 - sy));
|
||||
}
|
||||
|
||||
}
|
133
examples/templates/using_nflib/nflib/source/nf_3d.c
Normal file
133
examples/templates/using_nflib/nflib/source/nf_3d.c
Normal file
@ -0,0 +1,133 @@
|
||||
|
||||
// NightFox LIB - Funciones 2D comunes
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_basic.h"
|
||||
#include "nf_3d.h"
|
||||
#include "nf_2d.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Set3D();
|
||||
void NF_Set3D(u8 screen, u8 mode) {
|
||||
|
||||
// Especifica en que pantalla estara el main engine (unico que puede usar 3D)
|
||||
if (screen == 0) {
|
||||
lcdMainOnTop();
|
||||
} else {
|
||||
lcdMainOnBottom();
|
||||
}
|
||||
|
||||
// Selecciona modo 3D
|
||||
switch (mode) {
|
||||
case 0:
|
||||
videoSetMode(MODE_0_3D);
|
||||
break;
|
||||
case 2:
|
||||
videoSetMode(MODE_2_3D);
|
||||
break;
|
||||
case 5:
|
||||
videoSetMode(MODE_5_3D);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitOpenGL();
|
||||
void NF_InitOpenGL(void) {
|
||||
|
||||
// Inicializa el OpenGL de Libnds
|
||||
glInit();
|
||||
|
||||
// Define el tamaño de la ventana 3D (toda la pantalla)
|
||||
glViewport(0, 0, 255, 191);
|
||||
|
||||
// Configura la matriz de proyeccion
|
||||
glMatrixMode(GL_PROJECTION); // Selecciona la matriz
|
||||
glLoadIdentity(); // Y reseteala
|
||||
|
||||
// Ajusta OpenGL para proyeccion Ortografica
|
||||
glOrthof32(0, 256, 192, 0, 1024, -1024);
|
||||
|
||||
// Configura la matriz de visualizacion de modelos
|
||||
glMatrixMode(GL_MODELVIEW); // Selecciona la matriz
|
||||
glLoadIdentity(); // Y reseteala
|
||||
|
||||
// Por defecto, todos los poligonos son opacos
|
||||
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
|
||||
|
||||
// Configura el fondo
|
||||
glClearColor(0, 0, 0, 0); // Fondo transparente
|
||||
glClearDepth(0x7FFF); // Define la distancia de vision
|
||||
|
||||
// Configura la iluminacion global
|
||||
glColor(RGB15(31, 31, 31));
|
||||
|
||||
// Habilita las texturas
|
||||
glEnable(GL_TEXTURE_2D | GL_BLEND);
|
||||
|
||||
// Habilita la capa de dibujado
|
||||
NF_ShowBg(0, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetTextureSize();
|
||||
u16 NF_GetTextureSize(u16 textel) {
|
||||
|
||||
// Variables
|
||||
u16 size = 0;
|
||||
|
||||
// Devuelve el tamaño del textel, segun su base2
|
||||
switch (textel) {
|
||||
case 8:
|
||||
size = 0;
|
||||
break;
|
||||
case 16:
|
||||
size = 1;
|
||||
break;
|
||||
case 32:
|
||||
size = 2;
|
||||
break;
|
||||
case 64:
|
||||
size = 3;
|
||||
break;
|
||||
case 128:
|
||||
size = 4;
|
||||
break;
|
||||
case 256:
|
||||
size = 5;
|
||||
break;
|
||||
case 512:
|
||||
size = 6;
|
||||
break;
|
||||
case 1024:
|
||||
size = 7;
|
||||
break;
|
||||
default:
|
||||
size = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
// Devuelve el valor
|
||||
return size;
|
||||
|
||||
}
|
674
examples/templates/using_nflib/nflib/source/nf_affinebg.c
Normal file
674
examples/templates/using_nflib/nflib/source/nf_affinebg.c
Normal file
@ -0,0 +1,674 @@
|
||||
|
||||
// NightFox LIB - Funciones de Fondos Affine
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
#include <filesystem.h>
|
||||
#include <fat.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_basic.h"
|
||||
#include "nf_2d.h"
|
||||
#include "nf_tiledbg.h"
|
||||
#include "nf_affinebg.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Estructura para almacenar los parametros de los fondos Affine
|
||||
NF_TYPE_AFFINE_BG NF_AFFINE_BG[2][4];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitTiledBgSys();
|
||||
void NF_InitAffineBgSys(u8 screen) {
|
||||
|
||||
// Variables
|
||||
u8 n = 0;
|
||||
|
||||
// Define los bancos de Mapas y Tiles
|
||||
NF_BANKS_TILES[screen] = 8; // (1 banks = 16kb) Cada banco de tiles puede alvergar 8 bancos de Mapas
|
||||
NF_BANKS_MAPS[screen] = 16; // (1 bank = 2kb) Usar multiplos de 8. Cada set de 8 bancos consume 1 banco de tiles
|
||||
// Por defecto Tiles = 8, Mapas = 16
|
||||
// Esto nos deja 6 bancos de 16kb para tiles
|
||||
// y 16 bancos de 2kb para mapas
|
||||
|
||||
// Inicializa el array de bloques libres de Tiles
|
||||
for (n = 0; n < NF_BANKS_TILES[screen]; n ++) {
|
||||
NF_TILEBLOCKS[screen][n] = 0;
|
||||
}
|
||||
|
||||
// Inicializa el array de bloques libres de Mapas
|
||||
for (n = 0; n < NF_BANKS_MAPS[screen]; n ++) {
|
||||
NF_MAPBLOCKS[screen][n] = 0;
|
||||
}
|
||||
|
||||
// Inicializa el array de informacion de fondos en pantalla
|
||||
for (n = 0; n < 4; n ++) {
|
||||
NF_TILEDBG_LAYERS[screen][n].tilebase = 0; // Base del Tileset
|
||||
NF_TILEDBG_LAYERS[screen][n].tileblocks = 0; // Bloques usados por el Tileset
|
||||
NF_TILEDBG_LAYERS[screen][n].mapbase = 0; // Base del Map
|
||||
NF_TILEDBG_LAYERS[screen][n].mapblocks = 0; // Bloques usados por el Map
|
||||
NF_TILEDBG_LAYERS[screen][n].bgwidth = 0; // Ancho del fondo
|
||||
NF_TILEDBG_LAYERS[screen][n].bgheight = 0; // Altura del fondo
|
||||
NF_TILEDBG_LAYERS[screen][n].mapwidth = 0; // Ancho del mapa
|
||||
NF_TILEDBG_LAYERS[screen][n].mapheight = 0; // Altura del mapa
|
||||
NF_TILEDBG_LAYERS[screen][n].bgtype = 0; // Tipo de mapa
|
||||
NF_TILEDBG_LAYERS[screen][n].bgslot = 0; // Buffer de graficos usado
|
||||
NF_TILEDBG_LAYERS[screen][n].blockx = 0; // Bloque de mapa actual (horizontal)
|
||||
NF_TILEDBG_LAYERS[screen][n].blocky = 0; // Bloque de mapa actual (vertical)
|
||||
NF_TILEDBG_LAYERS[screen][n].created = false; // Esta creado ?
|
||||
}
|
||||
|
||||
// Ahora reserva los bancos necesarios de VRAM para mapas
|
||||
// Cada bloque de 16kb (1 banco de tiles) permite 8 bancos de mapas (de 2kb cada uno)
|
||||
u8 r_banks;
|
||||
r_banks = ((NF_BANKS_MAPS[screen] - 1) >> 3) + 1; // Calcula los bancos de Tiles a reservar para Maps
|
||||
for (n = 0; n < r_banks; n ++) {
|
||||
NF_TILEBLOCKS[screen][n] = 128; // Marca que bancos de VRAM son para MAPS
|
||||
}
|
||||
|
||||
if (screen == 0) {
|
||||
// Si es la pantalla 0 (Superior, Main engine)
|
||||
vramSetBankA(VRAM_A_MAIN_BG); // Banco A de la VRAM para fondos (128kb)
|
||||
memset((void*)0x06000000, 0, 131072); // Borra el contenido del banco A
|
||||
for (n = 0; n < 4; n ++) { // Oculta todas las 4 capas
|
||||
NF_HideBg(0, n);
|
||||
}
|
||||
} else {
|
||||
// Si es la pantalla 1 (Inferior, Sub engine)
|
||||
vramSetBankC(VRAM_C_SUB_BG); // Banco C de la VRAM para fondos (128kb)
|
||||
memset((void*)0x06200000, 0, 131072); // Borra el contenido del banco C
|
||||
for (n = 0; n < 4; n ++) { // Oculta todas las 4 capas
|
||||
NF_HideBg(1, n);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadAffineBg();
|
||||
void NF_LoadAffineBg(const char* file, const char* name, u16 width, u16 height) {
|
||||
|
||||
// Verifica si el fondo cumple las medidas correctas
|
||||
if (((width == 256) && (height == 256)) || ((width == 512) && (height == 512))) {
|
||||
// Medida Ok
|
||||
} else {
|
||||
// Error de tamaño
|
||||
NF_Error(117, name, 0);
|
||||
}
|
||||
|
||||
// Variable temporal del tamaño de la paleta
|
||||
u32 pal_size = 0;
|
||||
|
||||
// Busca un slot libre
|
||||
u8 n = 0;
|
||||
u8 slot = 255;
|
||||
for (n = 0; n < NF_SLOTS_TBG; n ++) { // Busca en todos los slots
|
||||
if (NF_TILEDBG[n].available) { // Si esta libre
|
||||
NF_TILEDBG[n].available = false; // Marcalo como en uso
|
||||
slot = n; // Guarda el slot a usar
|
||||
n = NF_SLOTS_TBG; // Deja de buscar
|
||||
}
|
||||
}
|
||||
// Si no hay ningun slot libre, error
|
||||
if (slot == 255) {
|
||||
NF_Error(103, "Tiled Bg", NF_SLOTS_TBG);
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_BUFFER_BGMAP[slot]); // Buffer para los mapas
|
||||
NF_BUFFER_BGMAP[slot] = NULL;
|
||||
free(NF_BUFFER_BGTILES[slot]); // Buffer para los tiles
|
||||
NF_BUFFER_BGTILES[slot] = NULL;
|
||||
free(NF_BUFFER_BGPAL[slot]); // Buffer para los paletas
|
||||
NF_BUFFER_BGPAL[slot] = NULL;
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
|
||||
// Carga el archivo .IMG
|
||||
sprintf(filename, "%s/%s.img", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
NF_TILEDBG[slot].tilesize = ftell(file_id);
|
||||
rewind(file_id);
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGTILES[slot] = (char*) calloc (NF_TILEDBG[slot].tilesize, sizeof(char));
|
||||
if (NF_BUFFER_BGTILES[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].tilesize);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BUFFER_BGTILES[slot], 1, NF_TILEDBG[slot].tilesize, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
// swiWaitForVBlank(); // Espera al cierre del archivo (Usar en caso de corrupcion de datos)
|
||||
|
||||
// Verifica el tamaño del tileset (Menos de 256 tiles)
|
||||
if (NF_TILEDBG[slot].tilesize > 16384) NF_Error(117, name, 0);
|
||||
|
||||
|
||||
// Carga el archivo .MAP
|
||||
sprintf(filename, "%s/%s.map", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
NF_TILEDBG[slot].mapsize = ((((ftell(file_id) - 1) >> 10) + 1) << 10); // Ajusta el tamaño a bloques de 1kb
|
||||
rewind(file_id);
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGMAP[slot] = (char*) calloc (NF_TILEDBG[slot].mapsize, sizeof(char));
|
||||
if (NF_BUFFER_BGMAP[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].mapsize);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BUFFER_BGMAP[slot], 1, NF_TILEDBG[slot].mapsize, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
// swiWaitForVBlank(); // Espera al cierre del archivo (Usar en caso de corrupcion de datos)
|
||||
|
||||
// Carga el archivo .PAL
|
||||
sprintf(filename, "%s/%s.pal", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
pal_size = ftell(file_id);
|
||||
NF_TILEDBG[slot].palsize = pal_size;
|
||||
rewind(file_id);
|
||||
// Si el tamaño es inferior a 512 bytes, ajustalo
|
||||
if (NF_TILEDBG[slot].palsize < 512) NF_TILEDBG[slot].palsize = 512;
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGPAL[slot] = (char*) calloc (NF_TILEDBG[slot].palsize, sizeof(char));
|
||||
if (NF_BUFFER_BGPAL[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].palsize);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BUFFER_BGPAL[slot], 1, pal_size, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
|
||||
// Guarda el nombre del Fondo
|
||||
sprintf(NF_TILEDBG[slot].name, "%s", name);
|
||||
|
||||
// Y las medidas
|
||||
NF_TILEDBG[slot].width = width;
|
||||
NF_TILEDBG[slot].height = height;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadAffineBg();
|
||||
void NF_UnloadAffineBg(const char* name) {
|
||||
NF_UnloadTiledBg(name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_CreateAffineBg();
|
||||
void NF_CreateAffineBg(u8 screen, u8 layer, const char* name, u8 wrap) {
|
||||
|
||||
// Variables
|
||||
u8 n = 0; // Bucle
|
||||
u8 slot = 255; // Slot seleccionado
|
||||
char bg[32]; // Nombre
|
||||
|
||||
// Verifica la capa de destino
|
||||
if ((layer != 2) && (layer != 3)) NF_Error(118, name, 0);
|
||||
|
||||
// Busca el fondo solicitado
|
||||
sprintf(bg, "%s", name); // Obten el nombre del fondo a buscar
|
||||
for (n = 0; n < NF_SLOTS_TBG; n ++) { // Busca en todos los slots
|
||||
if (strcmp(bg, NF_TILEDBG[n].name) == 0) { // Si lo encuentras
|
||||
slot = n; // Guarda el slot a usar
|
||||
n = NF_SLOTS_TBG; // Deja de buscar
|
||||
}
|
||||
}
|
||||
// Si no se encuentra, error
|
||||
if (slot == 255) {
|
||||
NF_Error(104, name, 0);
|
||||
}
|
||||
|
||||
// Si ya hay un fondo existente en esta pantalla y capa, borralo antes
|
||||
if (NF_TILEDBG_LAYERS[screen][layer].created) {
|
||||
NF_DeleteTiledBg(screen, layer);
|
||||
}
|
||||
|
||||
// Variables de control de Tiles
|
||||
u8 counter = 0;
|
||||
u8 start = 255;
|
||||
u8 tilesblocks = 0;
|
||||
u8 basetiles = 0;
|
||||
|
||||
// Transfiere el tamaño del fondo
|
||||
NF_TILEDBG_LAYERS[screen][layer].bgwidth = NF_TILEDBG[slot].width; // Ancho del fondo
|
||||
NF_TILEDBG_LAYERS[screen][layer].bgheight = NF_TILEDBG[slot].height; // Altura del fondo
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapwidth = NF_TILEDBG[slot].width; // Ancho del mapa
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapheight = NF_TILEDBG[slot].height; // Altura del mapa
|
||||
NF_TILEDBG_LAYERS[screen][layer].bgtype = 0; // Tipo de fondo
|
||||
NF_TILEDBG_LAYERS[screen][layer].bgslot = slot; // Buffer de graficos usado
|
||||
|
||||
// Calcula el tipo y tamaño del mapa
|
||||
n = 0;
|
||||
// ( 256 x 256 )
|
||||
if ((NF_TILEDBG[slot].width == 256) && (NF_TILEDBG[slot].height == 256)) {
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapwidth = 256;
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapheight = 256;
|
||||
NF_TILEDBG_LAYERS[screen][layer].bgtype = 11;
|
||||
n = 1;
|
||||
}
|
||||
// ( 512 x 512 )
|
||||
if ((NF_TILEDBG[slot].width == 512) && (NF_TILEDBG[slot].height == 512)) {
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapwidth = 512;
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapheight = 512;
|
||||
NF_TILEDBG_LAYERS[screen][layer].bgtype = 12;
|
||||
n = 1;
|
||||
}
|
||||
|
||||
// Verifica el tamaño del tileset (Menos de 256 tiles)
|
||||
if (NF_TILEDBG[slot].tilesize > 16384) n = 0;
|
||||
|
||||
// Si el fondo es de una medida incorrecta...
|
||||
if (n == 0) NF_Error(117, name, 0);
|
||||
|
||||
// Busca un los bloques libres para almacenar los Tiles en VRAM
|
||||
tilesblocks = ((NF_TILEDBG[slot].tilesize - 1) >> 14) + 1; // Bloques necesarios para el Tileset
|
||||
|
||||
for (n = 0; n < NF_BANKS_TILES[screen]; n ++) {
|
||||
if (NF_TILEBLOCKS[screen][n] == 0) { // Si esta libre
|
||||
if (counter == 0) { // Y el contador esta a 0
|
||||
start = n; // Marca la posicion de inicio
|
||||
}
|
||||
counter ++;
|
||||
if (counter == tilesblocks) { // Si ya tienes suficientes bloques libres
|
||||
n = NF_BANKS_TILES[screen]; // Termina de buscar
|
||||
}
|
||||
} else { // Si el bloque no esta libre
|
||||
start = 255; // Borra el marcador
|
||||
counter = 0; // Y resetea el contador
|
||||
}
|
||||
}
|
||||
|
||||
// Si no se han encontrado bloques libres
|
||||
if ((start == 255) || (counter < tilesblocks)) {
|
||||
NF_Error(107, name, tilesblocks);
|
||||
} else {
|
||||
basetiles = start; // Guarda donde empiezan los bloques libres
|
||||
}
|
||||
|
||||
// Marca los bancos de Tiles usados por este fondo
|
||||
for (n = basetiles; n < (basetiles + tilesblocks); n ++) {
|
||||
NF_TILEBLOCKS[screen][n] = 255; // Marca los bloques usados por tiles
|
||||
}
|
||||
|
||||
// Variables de control de Maps
|
||||
u8 mapblocks = 0;
|
||||
u8 basemap = 0;
|
||||
counter = 0;
|
||||
start = 255;
|
||||
|
||||
// Calcula los bloques para mapas necesarios
|
||||
mapblocks = ((NF_TILEDBG[slot].mapsize - 1) >> 11) + 1;
|
||||
|
||||
for (n = 0; n < NF_BANKS_MAPS[screen]; n ++) {
|
||||
if (NF_MAPBLOCKS[screen][n] == 0) { // Si esta libre
|
||||
if (counter == 0) { // Y el contador esta a 0
|
||||
start = n; // Marca la posicion de inicio
|
||||
}
|
||||
counter ++;
|
||||
if (counter == mapblocks) { // Si ya tienes suficientes bloques libres
|
||||
n = NF_BANKS_MAPS[screen]; // Termina de buscar
|
||||
}
|
||||
} else { // Si el bloque no esta libre
|
||||
start = 255; // Borra el marcador
|
||||
counter = 0; // Y resetea el contador
|
||||
}
|
||||
}
|
||||
|
||||
// Si no se han encontrado bloques libres
|
||||
if ((start == 255) || (counter < mapblocks)) {
|
||||
NF_Error(108, name, mapblocks);
|
||||
} else {
|
||||
basemap = start; // Guarda donde empiezan los bloques libres
|
||||
}
|
||||
|
||||
// Marca los bancos de Mapa usados por este fondo
|
||||
for (n = basemap; n < (basemap + mapblocks); n ++) {
|
||||
NF_MAPBLOCKS[screen][n] = 255; // Marca los bloques usados por mapas
|
||||
}
|
||||
|
||||
|
||||
// Obten el tamaño del fondo
|
||||
s32 bg_size = 0;
|
||||
// 256x256
|
||||
if ((NF_TILEDBG_LAYERS[screen][layer].mapwidth == 256) && (NF_TILEDBG_LAYERS[screen][layer].mapheight == 256)) {
|
||||
bg_size = BG_RS_32x32;
|
||||
}
|
||||
// 512x512
|
||||
if ((NF_TILEDBG_LAYERS[screen][layer].mapwidth == 512) && (NF_TILEDBG_LAYERS[screen][layer].mapheight == 512)) {
|
||||
bg_size = BG_RS_64x64;
|
||||
}
|
||||
|
||||
// Decide si se activa o no el WRAP
|
||||
u32 wrap_mode = 0;
|
||||
if (wrap == 0) {
|
||||
wrap_mode = BG_WRAP_OFF;
|
||||
} else {
|
||||
wrap_mode = BG_WRAP_ON;
|
||||
}
|
||||
|
||||
|
||||
// Crea el fondo segun la pantalla, capa y demas caracteristicas dadas
|
||||
// REG_BG0CNT <- Carracteristicas del fondo
|
||||
if (screen == 0) {
|
||||
switch (layer) {
|
||||
case 2:
|
||||
REG_BG2CNT = BgType_Rotation | bg_size | BG_PRIORITY_2 | BG_COLOR_256 | BG_TILE_BASE(basetiles) | BG_MAP_BASE(basemap) | wrap_mode;
|
||||
break;
|
||||
case 3:
|
||||
REG_BG3CNT = BgType_Rotation | bg_size | BG_PRIORITY_3 | BG_COLOR_256 | BG_TILE_BASE(basetiles) | BG_MAP_BASE(basemap) | wrap_mode;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (layer) {
|
||||
case 2:
|
||||
REG_BG2CNT_SUB = BgType_Rotation | bg_size | BG_PRIORITY_2 | BG_COLOR_256 | BG_TILE_BASE(basetiles) | BG_MAP_BASE(basemap) | wrap_mode;
|
||||
break;
|
||||
case 3:
|
||||
REG_BG3CNT_SUB = BgType_Rotation | bg_size | BG_PRIORITY_3 | BG_COLOR_256 | BG_TILE_BASE(basetiles) | BG_MAP_BASE(basemap) | wrap_mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u32 address; // Variable de direccion de VRAM;
|
||||
|
||||
// Transfiere el Tileset a VRAM
|
||||
if (screen == 0) { // (VRAM_A)
|
||||
address = (0x6000000) + (basetiles << 14);
|
||||
} else { // (VRAM_C)
|
||||
address = (0x6200000) + (basetiles << 14);
|
||||
}
|
||||
NF_DmaMemCopy((void*)address, NF_BUFFER_BGTILES[slot], NF_TILEDBG[slot].tilesize);
|
||||
|
||||
|
||||
// Transfiere el Mapa a VRAM
|
||||
if (screen == 0) { // (VRAM_A)
|
||||
address = (0x6000000) + (basemap << 11);
|
||||
} else { // (VRAM_C)
|
||||
address = (0x6200000) + (basemap << 11);
|
||||
}
|
||||
NF_DmaMemCopy((void*)address, NF_BUFFER_BGMAP[slot], NF_TILEDBG[slot].mapsize);
|
||||
|
||||
|
||||
// Tranfiere la Paleta a VRAM
|
||||
if (screen == 0) {
|
||||
address = (0x05000000);
|
||||
NF_DmaMemCopy((void*)address, NF_BUFFER_BGPAL[slot], NF_TILEDBG[slot].palsize);
|
||||
} else { // Paletas de la pantalla 1 (VRAM_H)
|
||||
address = (0x05000400);
|
||||
NF_DmaMemCopy((void*)address, NF_BUFFER_BGPAL[slot], NF_TILEDBG[slot].palsize);
|
||||
}
|
||||
|
||||
// Registra los datos del fondos en pantalla
|
||||
NF_TILEDBG_LAYERS[screen][layer].tilebase = basetiles; // Base del Tileset
|
||||
NF_TILEDBG_LAYERS[screen][layer].tileblocks = tilesblocks; // Bloques usados por el Tileset
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapbase = basemap; // Base del Map
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapblocks = mapblocks; // Bloques usados por el Map
|
||||
NF_TILEDBG_LAYERS[screen][layer].created = true; // Esta creado ?
|
||||
|
||||
// Resetea los parametros del affine
|
||||
NF_AffineBgTransform(screen, layer, 256, 256, 0, 0);
|
||||
NF_AffineBgMove(screen, layer, 0, 0, 0);
|
||||
|
||||
// Haz visible el fondo creado
|
||||
NF_ShowBg(screen, layer);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DeleteAffineBg();
|
||||
void NF_DeleteAffineBg(u8 screen, u8 layer) {
|
||||
|
||||
// Verifica que el fondo esta creado
|
||||
if (!NF_TILEDBG_LAYERS[screen][layer].created) {
|
||||
char text[32];
|
||||
sprintf(text, "%d", screen);
|
||||
NF_Error(105, text, layer); // Si no existe, error
|
||||
}
|
||||
|
||||
// Esconde el fondo creado
|
||||
NF_HideBg(screen, layer);
|
||||
|
||||
// Variables de uso general
|
||||
u32 address; // Direccion de VRAM;
|
||||
u8 n; // Uso general
|
||||
u16 basetiles = 0; // Base del Tileset
|
||||
u16 basemap = 0; // Base del Map
|
||||
u16 tilesize = 0; // Tamaño del Tileset
|
||||
u16 mapsize = 0; // Tamaño del Map
|
||||
|
||||
// Borra el Tileset de la VRAM
|
||||
basetiles = NF_TILEDBG_LAYERS[screen][layer].tilebase;
|
||||
tilesize = (NF_TILEDBG_LAYERS[screen][layer].tileblocks << 14);
|
||||
if (screen == 0) { // (VRAM_A)
|
||||
address = (0x6000000) + (basetiles << 14);
|
||||
} else { // (VRAM_C)
|
||||
address = (0x6200000) + (basetiles << 14);
|
||||
}
|
||||
memset((void*)address, 0, tilesize); // Pon a 0 todos los bytes de la area de VRAM
|
||||
|
||||
// Borra el Mapa de la VRAM
|
||||
basemap = NF_TILEDBG_LAYERS[screen][layer].mapbase;
|
||||
mapsize = (NF_TILEDBG_LAYERS[screen][layer].mapblocks << 11);
|
||||
if (screen == 0) { // (VRAM_A)
|
||||
address = (0x6000000) + (basemap << 11);
|
||||
} else { // (VRAM_C)
|
||||
address = (0x6200000) + (basemap << 11);
|
||||
}
|
||||
memset((void*)address, 0, mapsize); // Pon a 0 todos los bytes de la area de VRAM
|
||||
|
||||
// Marca como libres los bancos de Tiles usados por este fondo
|
||||
tilesize = (basetiles + NF_TILEDBG_LAYERS[screen][layer].tileblocks);
|
||||
for (n = basetiles; n < tilesize; n ++) {
|
||||
NF_TILEBLOCKS[screen][n] = 0;
|
||||
}
|
||||
|
||||
// Marca como libres los bancos de Mapa usados por este fondo
|
||||
mapsize = (basemap + NF_TILEDBG_LAYERS[screen][layer].mapblocks);
|
||||
for (n = basemap; n < mapsize; n ++) {
|
||||
NF_MAPBLOCKS[screen][n] = 0;
|
||||
}
|
||||
|
||||
// Borra los datos del fondos en pantalla
|
||||
NF_TILEDBG_LAYERS[screen][layer].tilebase = 0; // Base del Tileset
|
||||
NF_TILEDBG_LAYERS[screen][layer].tileblocks = 0; // Bloques usados por el Tileset
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapbase = 0; // Base del Map
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapblocks = 0; // Bloques usados por el Map
|
||||
NF_TILEDBG_LAYERS[screen][layer].bgwidth = 0; // Ancho del fondo
|
||||
NF_TILEDBG_LAYERS[screen][layer].bgheight = 0; // Altura del fondo
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapwidth = 0; // Ancho del mapa
|
||||
NF_TILEDBG_LAYERS[screen][layer].mapheight = 0; // Altura del mapa
|
||||
NF_TILEDBG_LAYERS[screen][layer].bgtype = 0; // Tipo de mapa
|
||||
NF_TILEDBG_LAYERS[screen][layer].bgslot = 0; // Buffer de graficos usado
|
||||
NF_TILEDBG_LAYERS[screen][layer].blockx = 0; // Bloque de mapa actual (horizontal)
|
||||
NF_TILEDBG_LAYERS[screen][layer].blocky = 0; // Bloque de mapa actual (vertical)
|
||||
NF_TILEDBG_LAYERS[screen][layer].created = false; // Esta creado ?
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_AffineBgTransform();
|
||||
void NF_AffineBgTransform(u8 screen, u8 layer, s32 x_scale, s32 y_scale, s32 x_tilt, s32 y_tilt) {
|
||||
|
||||
if (screen == 0) {
|
||||
switch (layer) {
|
||||
case 2:
|
||||
REG_BG2PA = x_scale;
|
||||
REG_BG2PB = x_tilt;
|
||||
REG_BG2PC = y_tilt;
|
||||
REG_BG2PD = y_scale;
|
||||
break;
|
||||
case 3:
|
||||
REG_BG3PA = x_scale;
|
||||
REG_BG3PB = x_tilt;
|
||||
REG_BG3PC = y_tilt;
|
||||
REG_BG3PD = y_scale;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (layer) {
|
||||
case 2:
|
||||
REG_BG2PA_SUB = x_scale;
|
||||
REG_BG2PB_SUB = x_tilt;
|
||||
REG_BG2PC_SUB = y_tilt;
|
||||
REG_BG2PD_SUB = y_scale;
|
||||
break;
|
||||
case 3:
|
||||
REG_BG3PA_SUB = x_scale;
|
||||
REG_BG3PB_SUB = x_tilt;
|
||||
REG_BG3PC_SUB = y_tilt;
|
||||
REG_BG3PD_SUB = y_scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Registra los valores asignados
|
||||
NF_AFFINE_BG[screen][layer].x_scale = x_scale;
|
||||
NF_AFFINE_BG[screen][layer].x_tilt = x_tilt;
|
||||
NF_AFFINE_BG[screen][layer].y_tilt = y_tilt;
|
||||
NF_AFFINE_BG[screen][layer].y_scale = y_scale;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_AffineBgMove();
|
||||
void NF_AffineBgMove(u8 screen, u8 layer, s32 x, s32 y, s32 angle) {
|
||||
|
||||
// Funcion de rotacion basada en la original de Libnds
|
||||
// creada por Dovoto y Wintermute.
|
||||
|
||||
// Variables
|
||||
s32 pa = 0; // x_scale
|
||||
s32 pb = 0; // x_tilt
|
||||
s32 pc = 0; // y_tilt;
|
||||
s32 pd = 0; // y_scale;
|
||||
s16 angle_sin = 0; // Seno
|
||||
s16 angle_cos = 0; // Coseno
|
||||
s16 in = 0; // Angulo dado
|
||||
s16 out = 0; // Angulo convertido
|
||||
s32 pos_x = 0; // Posicion X del fondo
|
||||
s32 pos_y = 0; // Posicion Y del fondo
|
||||
|
||||
in = angle;
|
||||
|
||||
// Limites del angulo
|
||||
if (in < -2048) {
|
||||
in += 2048;
|
||||
}
|
||||
if (in > 2048) {
|
||||
in -= 2048;
|
||||
}
|
||||
|
||||
// Si es un numero negativo...
|
||||
if (in < 0) {
|
||||
in = -in; // Pasa a positivo (para poder hacer el bitshift)
|
||||
out = (in << 4); // (in * 16); Pasa de base 2048 a base 32768
|
||||
// Dejalo en positivo para que <0 gire a la izquierda
|
||||
} else {
|
||||
out = (in << 4);
|
||||
out = -out; // Pasalo a negativo para que >0 gire a la derecha
|
||||
}
|
||||
|
||||
// Calcula los senos y cosenos
|
||||
angle_sin = sinLerp(out);
|
||||
angle_cos = cosLerp(out);
|
||||
|
||||
// Calcula la matriz de transformacion
|
||||
pa = ( angle_cos * NF_AFFINE_BG[screen][layer].x_scale ) >> 12;
|
||||
pb = (-angle_sin * NF_AFFINE_BG[screen][layer].x_scale ) >> 12;
|
||||
pc = ( angle_sin * NF_AFFINE_BG[screen][layer].y_scale ) >> 12;
|
||||
pd = ( angle_cos * NF_AFFINE_BG[screen][layer].y_scale ) >> 12;
|
||||
|
||||
// Aplica los parametros de tranformacion
|
||||
NF_AffineBgTransform(screen, layer, pa, pd, pb, pc);
|
||||
|
||||
// Ahora calcula la posicion del fondo
|
||||
pos_x = ((x << 8) - (((pa * (NF_AFFINE_BG[screen][layer].x_center << 8)) + (pb * (NF_AFFINE_BG[screen][layer].y_center << 8))) >> 8));
|
||||
pos_y = ((y << 8) - (((pc * (NF_AFFINE_BG[screen][layer].x_center << 8)) + (pd * (NF_AFFINE_BG[screen][layer].y_center << 8))) >> 8));
|
||||
|
||||
// Aplica la posicion del centro
|
||||
if (screen == 0) {
|
||||
switch (layer) {
|
||||
case 2:
|
||||
REG_BG2X = pos_x;
|
||||
REG_BG2Y = pos_y;
|
||||
break;
|
||||
case 3:
|
||||
REG_BG3X = pos_x;
|
||||
REG_BG3Y = pos_y;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (layer) {
|
||||
case 2:
|
||||
REG_BG2X_SUB = pos_x;
|
||||
REG_BG2Y_SUB = pos_y;
|
||||
break;
|
||||
case 3:
|
||||
REG_BG3X_SUB = pos_x;
|
||||
REG_BG3Y_SUB = pos_y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Guarda los parametros
|
||||
NF_AFFINE_BG[screen][layer].angle = out;
|
||||
NF_AFFINE_BG[screen][layer].x = x;
|
||||
NF_AFFINE_BG[screen][layer].y = y;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_AffineBgCenter();
|
||||
void NF_AffineBgCenter(u8 screen, u8 layer, s32 x, s32 y) {
|
||||
|
||||
NF_AFFINE_BG[screen][layer].x_center = x;
|
||||
NF_AFFINE_BG[screen][layer].y_center = y;
|
||||
|
||||
}
|
||||
|
303
examples/templates/using_nflib/nflib/source/nf_basic.c
Normal file
303
examples/templates/using_nflib/nflib/source/nf_basic.c
Normal file
@ -0,0 +1,303 @@
|
||||
|
||||
// NightFox LIB - Funciones basicas y de Debug
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
#include <filesystem.h>
|
||||
#include <fat.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_basic.h"
|
||||
#include "nf_defines.h"
|
||||
|
||||
|
||||
|
||||
// Define la variable global NF_ROOTFOLDER
|
||||
char NF_ROOTFOLDER[32];
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Error();
|
||||
void NF_Error(u16 code, const char* text, u32 value) {
|
||||
|
||||
consoleDemoInit(); // Inicializa la consola de texto
|
||||
consoleClear(); // Borra la pantalla
|
||||
setBrightness(3, 0); // Restaura el brillo
|
||||
|
||||
u32 n = 0; // Variables de uso general
|
||||
|
||||
// Captura el codigo de error
|
||||
switch (code) {
|
||||
|
||||
case 101: // Fichero no encontrado
|
||||
iprintf("File %s not found.\n", text);
|
||||
break;
|
||||
|
||||
case 102: // Memoria insuficiente
|
||||
iprintf("Out of memory.\n");
|
||||
iprintf("%d bytes\n", (int)value);
|
||||
iprintf("can't be allocated.\n");
|
||||
break;
|
||||
|
||||
case 103: // No quedan Slots libres
|
||||
iprintf("Out of %s slots.\n", text);
|
||||
iprintf("All %d slots are in use.\n", (int)value);
|
||||
break;
|
||||
|
||||
case 104: // Fondo no encontrado
|
||||
iprintf("Tiled Bg %s\n", text);
|
||||
iprintf("not found.\n");
|
||||
break;
|
||||
|
||||
case 105: // Fondo no creado
|
||||
iprintf("Background number %d\n", (int)value);
|
||||
iprintf("on screen %s is\n", text);
|
||||
iprintf("not created.\n");
|
||||
break;
|
||||
|
||||
case 106: // Fuera de rango
|
||||
iprintf("%s Id out\n", text);
|
||||
iprintf("of range (%d max).\n", (int)value);
|
||||
break;
|
||||
|
||||
case 107: // Insuficientes bloques contiguos en VRAM (Tiles)
|
||||
n = (int)((value * 16384) / 1024);
|
||||
iprintf("Can't allocate %d\n", (int)value);
|
||||
iprintf("blocks of tiles for\n");
|
||||
iprintf("%s background\n", text);
|
||||
iprintf("Free %dkb of VRAM or try to\n", (int)n);
|
||||
iprintf("reload all Bg's again\n");
|
||||
break;
|
||||
|
||||
case 108: // Insuficientes bloques contiguos en VRAM (Maps)
|
||||
n = (int)((value * 2048) / 1024);
|
||||
iprintf("Can't allocate %d\n", (int)value);
|
||||
iprintf("blocks of maps for\n");
|
||||
iprintf("%s background\n", text);
|
||||
iprintf("Free %dkb of VRAM or try to\n", (int)n);
|
||||
iprintf("reload all Bg's again\n");
|
||||
break;
|
||||
|
||||
case 109: // Id ocupada
|
||||
iprintf("%s Id.%d\n", text, (int)value);
|
||||
iprintf("is already in use.\n");
|
||||
break;
|
||||
|
||||
case 110: // Id no cargada
|
||||
iprintf("%s\n", text);
|
||||
iprintf("%d not loaded.\n", (int)value);
|
||||
break;
|
||||
|
||||
case 111: // Id no en VRAM
|
||||
iprintf("%s\n", text);
|
||||
iprintf("%d not in VRAM.\n", (int)value);
|
||||
break;
|
||||
|
||||
case 112: // Sprite no creado
|
||||
iprintf("Sprite number %d\n", (int)value);
|
||||
iprintf("on screen %s is\n", text);
|
||||
iprintf("not created.\n");
|
||||
break;
|
||||
|
||||
case 113: // Memoria VRAM insuficiente
|
||||
iprintf("Out of VRAM.\n");
|
||||
iprintf("%d bytes for %s\n", (int)value, text);
|
||||
iprintf("can't be allocated.\n");
|
||||
break;
|
||||
|
||||
case 114: // La capa de Texto no existe
|
||||
iprintf("Text layer on screen\n");
|
||||
iprintf("nº %d don't exist.\n", (int)value);
|
||||
break;
|
||||
|
||||
case 115: // Medidas del fondo no compatibles (no son multiplos de 256)
|
||||
iprintf("Tiled Bg %s\n", text);
|
||||
iprintf("has wrong size.\n");
|
||||
iprintf("Your bg sizes must be\n");
|
||||
iprintf("dividable by 256 pixels.\n");
|
||||
break;
|
||||
|
||||
case 116: // Archivo demasiado grande
|
||||
iprintf("File %s\n", text);
|
||||
iprintf("is too big.\n");
|
||||
iprintf("Max size for\n");
|
||||
iprintf("file is %dkb.\n", (int)(value >> 10));
|
||||
break;
|
||||
|
||||
case 117: // Medidas del fondo affine no compatibles (Solo se admiten 256x256 y 512x512)
|
||||
iprintf("Affine Bg %s\n", text);
|
||||
iprintf("has wrong size.\n");
|
||||
iprintf("Your bg sizes must be\n");
|
||||
iprintf("256x256 or 512x512 and\n");
|
||||
iprintf("with 256 tiles or less.\n");
|
||||
break;
|
||||
|
||||
case 118: // Medidas del fondo affine no compatibles (Solo se admiten 256x256 y 512x512)
|
||||
iprintf("Affine Bg %s\n", text);
|
||||
iprintf("only can be created\n");
|
||||
iprintf("on layers 2 or 3.\n");
|
||||
break;
|
||||
|
||||
case 119: // Tamaño de la textura ilegal.
|
||||
iprintf("Texture id.%d illegal size.\n", (int)value);
|
||||
iprintf("Only power of 2 sizes can\n");
|
||||
iprintf("be used (8 to 1024).\n");
|
||||
break;
|
||||
|
||||
case 120: // Tamaño de la Sprite ilegal.
|
||||
iprintf("Sprite id.%d illegal size.\n", (int)value);
|
||||
iprintf("8x8 Sprites can't be used\n");
|
||||
iprintf("in 1D_128 mode.\n");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
iprintf("Error code %d.\n", (int)code); // Imprime el codigo de error
|
||||
|
||||
// Deten la ejecucion del programa
|
||||
while (1) {
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SetRootFolder();
|
||||
void NF_SetRootFolder(const char* folder) {
|
||||
|
||||
if (strcmp(folder, "NITROFS") == 0) { // Si se debe iniciar el modo NitroFS y FAT
|
||||
|
||||
// Define NitroFS como la carpeta inicial
|
||||
sprintf(NF_ROOTFOLDER, "%s", "");
|
||||
// Intenta inicializar NitroFS
|
||||
if(nitroFSInit(NULL)) {
|
||||
// NitroFS ok
|
||||
// Si es correcto, cambia al ROOT del NitroFS
|
||||
chdir("nitro:/");
|
||||
} else {
|
||||
// Fallo. Deten el programa
|
||||
consoleDemoInit(); // Inicializa la consola de texto
|
||||
if (NF_GetLanguage() == 5) {
|
||||
iprintf("Error iniciando NitroFS.\n");
|
||||
iprintf("Programa detenido.\n\n");
|
||||
iprintf("Verifica que tu flashcard\n");
|
||||
iprintf("es compatible con Argv.\n");
|
||||
iprintf("Si no lo es, intenta usar el\n");
|
||||
iprintf("Homebrew Menu para ejecutarla.\n\n");
|
||||
} else {
|
||||
iprintf("NitroFS Init Error.\n");
|
||||
iprintf("Abnormal termination.\n\n");
|
||||
iprintf("Check if your flashcard is\n");
|
||||
iprintf("Argv compatible.\n");
|
||||
iprintf("If not, try to launch the ROM\n");
|
||||
iprintf("using the Homebrew Menu.\n\n");
|
||||
}
|
||||
iprintf("http://sourceforge.net/projects/devkitpro/files/hbmenu/");
|
||||
// Bucle infinito. Fin del programa
|
||||
while(1) {
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
}
|
||||
|
||||
} else { // Si se debe iniciar solo la FAT
|
||||
|
||||
// Define la carpeta inicial de la FAT
|
||||
sprintf(NF_ROOTFOLDER, "%s", folder);
|
||||
// Intenta inicializar la FAT
|
||||
if (fatInitDefault()) {
|
||||
// Si es correcto, cambia al ROOT del FAT
|
||||
chdir("fat:/");
|
||||
} else {
|
||||
// Fallo. Deten el programa
|
||||
consoleDemoInit(); // Inicializa la consola de texto
|
||||
if (NF_GetLanguage() == 5) {
|
||||
iprintf("Error iniciando FAT.\n");
|
||||
iprintf("Programa detenido.\n\n");
|
||||
iprintf("Verifica que tu flashcard es\n");
|
||||
iprintf("compatible con DLDI y la ROM\n");
|
||||
iprintf("este parcheada correctamente.\n");
|
||||
} else {
|
||||
iprintf("FAT Init Error.\n");
|
||||
iprintf("Abnormal termination.\n\n");
|
||||
iprintf("Check if your flashcard is\n");
|
||||
iprintf("DLDI compatible and the ROM\n");
|
||||
iprintf("is correctly patched.\n");
|
||||
}
|
||||
// Bucle infinito. Fin del programa
|
||||
while(1) {
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DmaMemCopy();
|
||||
void NF_DmaMemCopy(void* destination, const void* source, u32 size) {
|
||||
|
||||
// Funcion basada en la documentacion de Coranac
|
||||
// http://www.coranac.com/2009/05/dma-vs-arm9-fight/
|
||||
|
||||
// Datos de origen y destino
|
||||
u32 src = (u32)source;
|
||||
u32 dst = (u32)destination;
|
||||
|
||||
// Verifica si los datos estan correctamente alineados
|
||||
if ((src | dst) & 1) {
|
||||
|
||||
// No estan alineados para un DMA copy
|
||||
// Se realiza un copia con el memcpy();
|
||||
memcpy(destination, source, size);
|
||||
|
||||
} else {
|
||||
|
||||
// Estan alineados correctamente
|
||||
|
||||
// Espera a que el canal 3 de DMA este libre
|
||||
while (dmaBusy(3));
|
||||
|
||||
// Manda el cache a la memoria
|
||||
DC_FlushRange(source, size);
|
||||
|
||||
// Dependiendo de la alineacion de datos, selecciona el metodo de copia
|
||||
if ((src | dst | size) & 3) {
|
||||
// Copia de 16 bits
|
||||
dmaCopyHalfWords(3, source, destination, size);
|
||||
} else {
|
||||
// Copia de 32 bits
|
||||
dmaCopyWords(3, source, destination, size);
|
||||
}
|
||||
|
||||
// Evita que el destino sea almacenado en cache
|
||||
DC_InvalidateRange(destination, size);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetLanguage();
|
||||
u8 NF_GetLanguage(void) {
|
||||
|
||||
// Asegurate que el valor devuelto corresponde a los
|
||||
// contenidos en los BITS 0, 1 y 2 de la direccion de memoria
|
||||
return (NF_UDATA_LANG & 0x07);
|
||||
|
||||
}
|
603
examples/templates/using_nflib/nflib/source/nf_bitmapbg.c
Normal file
603
examples/templates/using_nflib/nflib/source/nf_bitmapbg.c
Normal file
@ -0,0 +1,603 @@
|
||||
|
||||
// NightFox LIB - Include de funciones de fondos en modo Bitmap
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
#include <filesystem.h>
|
||||
#include <fat.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_bitmapbg.h"
|
||||
#include "nf_basic.h"
|
||||
#include "nf_2d.h"
|
||||
|
||||
|
||||
|
||||
// Define los Buffers para almacenar datos de 16 bits
|
||||
NF_TYPE_BG16B_INFO NF_BG16B[NF_SLOTS_BG16B]; // Fondos RAW de 16 bits
|
||||
|
||||
// Backbuffer de 16 bits de cada pantalla
|
||||
u16* NF_16BITS_BACKBUFFER[2];
|
||||
|
||||
// Define los Buffers para almacenar datos de 8 bits
|
||||
NF_TYPE_BG8B_INFO NF_BG8B[NF_SLOTS_BG8B]; // Fondos indexados de 8 bits
|
||||
|
||||
// Backbuffer de 8 bits de cada pantalla
|
||||
NF_TYPE_BB8B_INFO NF_8BITS_BACKBUFFER[2];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Init16bitsBgBuffers();
|
||||
void NF_Init16bitsBgBuffers(void) {
|
||||
// Variables locales
|
||||
u8 n = 0;
|
||||
for (n = 0; n < NF_SLOTS_BG16B; n ++) {
|
||||
NF_BG16B[n].buffer = NULL;
|
||||
NF_BG16B[n].size = 0;
|
||||
NF_BG16B[n].inuse = false;
|
||||
NF_BG16B[n].width = 0;
|
||||
NF_BG16B[n].height = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Reset16bitsBgBuffers();
|
||||
void NF_Reset16bitsBgBuffers(void) {
|
||||
// Variables locales
|
||||
u8 n = 0;
|
||||
// Libera la RAM
|
||||
for (n = 0; n < NF_SLOTS_BG16B; n ++) {
|
||||
free(NF_BG16B[n].buffer);
|
||||
}
|
||||
// Reinicia los datos
|
||||
NF_Init16bitsBgBuffers();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Init16bitsBackBuffer();
|
||||
void NF_Init16bitsBackBuffer(u8 screen) {
|
||||
u8 scr = screen;
|
||||
if (scr > 1) scr = 1;
|
||||
NF_16BITS_BACKBUFFER[scr] = NULL;
|
||||
}
|
||||
|
||||
|
||||
// Funcion NF_Enable16bitsBackBuffer();
|
||||
void NF_Enable16bitsBackBuffer(u8 screen) {
|
||||
u8 scr = screen;
|
||||
if (scr > 1) scr = 1;
|
||||
// Resetea el buffer
|
||||
free(NF_16BITS_BACKBUFFER[scr]);
|
||||
NF_16BITS_BACKBUFFER[scr] = NULL;
|
||||
// Asignale 128kb de memoria
|
||||
NF_16BITS_BACKBUFFER[scr] = (u16*) calloc(65536, sizeof(u16));
|
||||
// Devuelve error si no hay suficiente memoria
|
||||
if (NF_16BITS_BACKBUFFER[scr] == NULL) NF_Error(102, NULL, 131072);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Disble16bitsBackBuffer();
|
||||
void NF_Disble16bitsBackBuffer(u8 screen) {
|
||||
u8 scr = screen;
|
||||
if (scr > 1) scr = 1;
|
||||
// Resetea el buffer
|
||||
free(NF_16BITS_BACKBUFFER[scr]);
|
||||
NF_16BITS_BACKBUFFER[scr] = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Flip16bitsBackBuffer();
|
||||
void NF_Flip16bitsBackBuffer(u8 screen) {
|
||||
// Copia el contenido del Backbuffer a la VRAM
|
||||
// de la pantalla solicitada
|
||||
if (screen == 0) {
|
||||
NF_DmaMemCopy((void*)0x06000000, NF_16BITS_BACKBUFFER[0], 131072);
|
||||
} else {
|
||||
NF_DmaMemCopy((void*)0x06200000, NF_16BITS_BACKBUFFER[1], 131072);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitBitmapBgSys();
|
||||
void NF_InitBitmapBgSys(u8 screen, u8 mode) {
|
||||
|
||||
// Habilita la capa 3 de la pantalla indicada en modo BITMAP
|
||||
|
||||
// Variables locales
|
||||
u8 n = 0;
|
||||
|
||||
// Inicializa la VRAM
|
||||
if (screen == 0) {
|
||||
vramSetBankA(VRAM_A_MAIN_BG); // Banco A de la VRAM para fondos (128kb)
|
||||
memset((void*)0x06000000, 0, 131072); // Borra el contenido del banco A
|
||||
// Oculta todas las capas
|
||||
for (n = 0; n < 4; n ++) { // Oculta todas las 4 capas
|
||||
NF_HideBg(0, n);
|
||||
}
|
||||
} else {
|
||||
vramSetBankC(VRAM_C_SUB_BG); // Banco C de la VRAM para fondos (128kb)
|
||||
memset((void*)0x06200000, 0, 131072); // Borra el contenido del banco C
|
||||
// Oculta todas las capas
|
||||
for (n = 0; n < 4; n ++) { // Oculta todas las 4 capas
|
||||
NF_HideBg(1, n);
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializa la capa de dibujado
|
||||
if (screen == 0) {
|
||||
if (mode == 0) { // Modo 8 bits (Capas 1 y 3)
|
||||
REG_BG3CNT = BG_PRIORITY_3 | BG_BMP_BASE(4) | BG_BMP8_256x256;
|
||||
REG_BG2CNT = BG_PRIORITY_2 | BG_BMP_BASE(0) | BG_BMP8_256x256;
|
||||
} else { // Modo 16 bits
|
||||
REG_BG3CNT = BG_PRIORITY_3 | BG_BMP_BASE(0) | BG_BMP16_256x256;
|
||||
}
|
||||
// Resetea los registros de RotScale (Capa 3)
|
||||
REG_BG3PA = (1 << 8);
|
||||
REG_BG3PB = 0;
|
||||
REG_BG3PC = 0;
|
||||
REG_BG3PD = (1 << 8);
|
||||
NF_ScrollBg(0, 3, 0, 0); // Posicionala en 0, 0
|
||||
NF_ShowBg(0, 3); // Muestra la capa 3
|
||||
// Resetea los registros de RotScale (Capa 2)
|
||||
if (mode == 0) {
|
||||
REG_BG2PA = (1 << 8);
|
||||
REG_BG2PB = 0;
|
||||
REG_BG2PC = 0;
|
||||
REG_BG2PD = (1 << 8);
|
||||
NF_ScrollBg(0, 2, 0, 0); // Posicionala en 0, 0
|
||||
NF_ShowBg(0, 2); // Muestra la capa 2
|
||||
}
|
||||
} else {
|
||||
if (mode == 0) { // Modo 8 bits (Capas 2 y 3)
|
||||
REG_BG3CNT_SUB = BG_PRIORITY_3 | BG_BMP_BASE(4) | BG_BMP8_256x256;
|
||||
REG_BG2CNT_SUB = BG_PRIORITY_2 | BG_BMP_BASE(0) | BG_BMP8_256x256;
|
||||
} else { // Modo 16 bits
|
||||
REG_BG3CNT_SUB = BG_PRIORITY_3 | BG_BMP_BASE(0) | BG_BMP16_256x256;
|
||||
}
|
||||
// Resetea los registros de RotScale (Capa 3)
|
||||
REG_BG3PA_SUB = (1 << 8);
|
||||
REG_BG3PB_SUB = 0;
|
||||
REG_BG3PC_SUB = 0;
|
||||
REG_BG3PD_SUB = (1 << 8);
|
||||
NF_ScrollBg(1, 3, 0, 0); // Posicionala en 0, 0
|
||||
NF_ShowBg(1, 3); // Muestra la capa 3
|
||||
// Resetea los registros de RotScale (Capa 2)
|
||||
if (mode == 0) {
|
||||
REG_BG2PA_SUB = (1 << 8);
|
||||
REG_BG2PB_SUB = 0;
|
||||
REG_BG2PC_SUB = 0;
|
||||
REG_BG2PD_SUB = (1 << 8);
|
||||
NF_ScrollBg(1, 2, 0, 0); // Posicionala en 0, 0
|
||||
NF_ShowBg(1, 2); // Muestra la capa 2
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Load16bitsBg();
|
||||
void NF_Load16bitsBg(const char* file, u8 slot) {
|
||||
// Llama a la funcion de carga de datos de imagen de 16bits
|
||||
NF_Load16bImgData(file, slot, 256, 256, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Load16bitsImage();
|
||||
void NF_Load16bitsImage(const char* file, u8 slot, u16 size_x, u16 size_y) {
|
||||
// Llama a la funcion de carga de datos de imagen de 16bits
|
||||
NF_Load16bImgData(file, slot, size_x, size_y, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Load16bImgData();
|
||||
void NF_Load16bImgData(const char* file, u8 slot, u16 x, u16 y, u8 type) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((slot < 0) || (slot >= NF_SLOTS_BG16B)) {
|
||||
if (type == 0) {
|
||||
NF_Error(106, "16 Bits Bg's", NF_SLOTS_BG16B);
|
||||
} else {
|
||||
NF_Error(106, "16 Bits Image", NF_SLOTS_BG16B);
|
||||
}
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_BG16B[slot].buffer);
|
||||
NF_BG16B[slot].buffer = NULL;
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
|
||||
// Variable para el tamaño de archivo
|
||||
u32 size = 0;
|
||||
|
||||
// Carga el archivo .IMG
|
||||
sprintf(filename, "%s/%s.img", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
size = ftell(file_id);
|
||||
rewind(file_id);
|
||||
// Si excede del tamaño maximo (128kb), error
|
||||
if (size > 131072) NF_Error(116, filename, 131072);
|
||||
// Reserva el espacio en RAM
|
||||
NF_BG16B[slot].buffer = (u16*) calloc ((size >> 1), sizeof(u16));
|
||||
if (NF_BG16B[slot].buffer == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, size);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BG16B[slot].buffer, 1, size, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
|
||||
// Asegurate que el alpha bit (BIT 15) esta marcado
|
||||
u32 n = 0;
|
||||
for (n = 0; n < (size >> 1); n ++) {
|
||||
NF_BG16B[slot].buffer[n] |= BIT(15);
|
||||
}
|
||||
|
||||
// Guarda los parametros del fondo
|
||||
NF_BG16B[slot].size = size; // Guarda el tamaño
|
||||
NF_BG16B[slot].width = x; // Ancho del fondo
|
||||
NF_BG16B[slot].height = y; // Altura del fondo
|
||||
NF_BG16B[slot].inuse = true; // Marca que esta en uso
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Unload16bitsBg();
|
||||
void NF_Unload16bitsBg(u8 slot) {
|
||||
|
||||
// Verifica si el buffer contiene datos
|
||||
if (!NF_BG16B[slot].inuse) NF_Error(110, "16 Bits Bg", slot);
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_BG16B[slot].buffer);
|
||||
NF_BG16B[slot].buffer = NULL;
|
||||
|
||||
NF_BG16B[slot].size = 0; // Tamaño a 0
|
||||
NF_BG16B[slot].inuse = false; // Marca que esta libre
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Copy16bitsBuffer();
|
||||
void NF_Copy16bitsBuffer(u8 screen, u8 destination, u8 slot) {
|
||||
|
||||
// Verifica si el buffer contiene datos
|
||||
if (!NF_BG16B[slot].inuse) NF_Error(110, "16 Bits Bg", slot);
|
||||
|
||||
if (destination == 0) { // Si el destino es la VRAM
|
||||
// Dependiendo de la pantalla
|
||||
if (screen == 0) {
|
||||
NF_DmaMemCopy((void*)0x06000000, NF_BG16B[slot].buffer, NF_BG16B[slot].size);
|
||||
} else {
|
||||
NF_DmaMemCopy((void*)0x06200000, NF_BG16B[slot].buffer, NF_BG16B[slot].size);
|
||||
}
|
||||
} else { // Si el destino es el BackBuffer
|
||||
// Dependiendo de la pantalla
|
||||
if (screen == 0) {
|
||||
memcpy(NF_16BITS_BACKBUFFER[0], NF_BG16B[slot].buffer, NF_BG16B[slot].size);
|
||||
} else {
|
||||
memcpy(NF_16BITS_BACKBUFFER[1], NF_BG16B[slot].buffer, NF_BG16B[slot].size);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Draw16bitsImage();
|
||||
void NF_Draw16bitsImage(u8 screen, u8 slot, s16 x, s16 y, bool alpha) {
|
||||
|
||||
// Verifica si el buffer contiene datos
|
||||
if (!NF_BG16B[slot].inuse) NF_Error(110, "16 Bits Image", slot);
|
||||
|
||||
// Variables locales
|
||||
u16 img_x = 0;
|
||||
u16 img_y = 0;
|
||||
s16 buff_x = 0;
|
||||
s16 buff_y = 0;
|
||||
u32 buff_idx = 0;
|
||||
u16 data = 0;
|
||||
|
||||
// Filtro de pantalla
|
||||
u8 scr = screen;
|
||||
if (scr > 1) scr = 1;
|
||||
|
||||
// Si el destino es el BackBuffer
|
||||
for (img_y = 0; img_y < NF_BG16B[slot].height; img_y ++) {
|
||||
for (img_x = 0; img_x < NF_BG16B[slot].width; img_x ++ ) {
|
||||
// Calcula donde se escribira el pixel
|
||||
buff_x = (img_x + x);
|
||||
buff_y = (img_y + y);
|
||||
// Si esta dentro de la pantalla, dibujalo
|
||||
if (
|
||||
(buff_x >= 0)
|
||||
&&
|
||||
(buff_x <= 255)
|
||||
&&
|
||||
(buff_y >= 0)
|
||||
&&
|
||||
(buff_y <= 255)
|
||||
) {
|
||||
// Calcula el offset dentro del buffer
|
||||
buff_idx = ((buff_y << 8) + buff_x);
|
||||
// Valor del Pixel
|
||||
data = NF_BG16B[slot].buffer[((img_y * NF_BG16B[slot].width) + img_x)];
|
||||
// Si el pixel NO es magenta !(RGB15(31, 0, 31) | BIT(15))
|
||||
if ((data != 0xFC1F) || (!alpha)) {
|
||||
// Escribe el pixel en el BackBuffer
|
||||
*(NF_16BITS_BACKBUFFER[scr] + buff_idx) = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Init8bitsBgBuffers();
|
||||
void NF_Init8bitsBgBuffers(void) {
|
||||
// Variables locales
|
||||
u8 n = 0;
|
||||
for (n = 0; n < NF_SLOTS_BG8B; n ++) {
|
||||
NF_BG8B[n].data = NULL;
|
||||
NF_BG8B[n].pal = NULL;
|
||||
NF_BG8B[n].data_size = 0;
|
||||
NF_BG8B[n].pal_size = 0;
|
||||
NF_BG8B[n].inuse = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Reset8bitsBgBuffers();
|
||||
void NF_Reset8bitsBgBuffers(void) {
|
||||
// Variables locales
|
||||
u8 n = 0;
|
||||
// Libera la RAM usada
|
||||
for (n = 0; n < NF_SLOTS_BG8B; n ++) {
|
||||
free(NF_BG8B[n].data);
|
||||
free(NF_BG8B[n].pal);
|
||||
}
|
||||
// Reinicia los datos
|
||||
NF_Init8bitsBgBuffers();
|
||||
}
|
||||
|
||||
|
||||
// Funcion NF_Load8bitsBg();
|
||||
void NF_Load8bitsBg(const char* file, u8 slot) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((slot < 0) || (slot >= NF_SLOTS_BG8B)) {
|
||||
NF_Error(106, "8 Bits Bg's", NF_SLOTS_BG8B);
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_BG8B[slot].data);
|
||||
NF_BG8B[slot].data = NULL;
|
||||
free(NF_BG8B[slot].pal);
|
||||
NF_BG8B[slot].pal = NULL;
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
|
||||
// Variable para el tamaño de archivo
|
||||
u32 size = 0;
|
||||
|
||||
// Carga el archivo .IMG
|
||||
sprintf(filename, "%s/%s.img", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
size = ftell(file_id);
|
||||
rewind(file_id);
|
||||
// Si excede del tamaño maximo (64kb), error
|
||||
if (size > 65536) NF_Error(116, filename, 65536);
|
||||
// Reserva el espacio en RAM
|
||||
NF_BG8B[slot].data = (u8*) calloc (size, sizeof(u8));
|
||||
if (NF_BG8B[slot].data == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, size);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BG8B[slot].data, 1, size, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
NF_BG8B[slot].data_size = size; // Guarda el tamaño del buffer
|
||||
|
||||
// Carga el archivo .PAL
|
||||
sprintf(filename, "%s/%s.pal", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
size = ftell(file_id);
|
||||
rewind(file_id);
|
||||
// Si la paleta tiene un tamaño inferior a 512, ajusta el tamaño
|
||||
if (size < 512) size = 512;
|
||||
// Reserva el espacio en RAM
|
||||
NF_BG8B[slot].pal = (u16*) calloc ((size >> 1), sizeof(u16));
|
||||
if (NF_BG8B[slot].pal == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, size);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BG8B[slot].pal, 1, size, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
NF_BG8B[slot].pal_size = size; // Guarda el tamaño del buffer
|
||||
|
||||
// Marca el slot como que esta en uso
|
||||
NF_BG8B[slot].inuse = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Unload8bitsBg();
|
||||
void NF_Unload8bitsBg(u8 slot) {
|
||||
|
||||
// Verifica si el buffer contiene datos
|
||||
if (!NF_BG8B[slot].inuse) NF_Error(110, "8 Bits Bg", slot);
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_BG8B[slot].data);
|
||||
NF_BG8B[slot].data = NULL;
|
||||
NF_BG8B[slot].data_size = 0;
|
||||
free(NF_BG8B[slot].pal);
|
||||
NF_BG8B[slot].pal = NULL;
|
||||
NF_BG8B[slot].pal_size = 0;
|
||||
|
||||
NF_BG8B[slot].inuse = false; // Marca que esta libre
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Copy8bitsBuffer();
|
||||
void NF_Copy8bitsBuffer(u8 screen, u8 destination, u8 slot) {
|
||||
|
||||
// Verifica si el buffer contiene datos
|
||||
if (!NF_BG8B[slot].inuse) NF_Error(110, "8 Bits Bg", slot);
|
||||
|
||||
u8 scr = screen;
|
||||
if (scr > 1) scr = 1;
|
||||
|
||||
// Si el destino es la VRAM
|
||||
if (destination < 2) {
|
||||
|
||||
// Segun la pantalla...
|
||||
u32 data = 0;
|
||||
u32 pal = 0;
|
||||
if (screen == 0) {
|
||||
data = (0x06000000); // Direccion en VRAM para los datos
|
||||
pal = (0x05000000); // Direccion en VRAM para la paleta
|
||||
} else {
|
||||
data = (0x06200000); // Direccion en VRAM para los datos
|
||||
pal = (0x05000400); // Direccion en VRAM para la paleta
|
||||
}
|
||||
// Segun la capa
|
||||
if (destination == 1) data += 65536;
|
||||
// Copia los datos a la VRAM
|
||||
NF_DmaMemCopy((void*)data, NF_BG8B[slot].data, NF_BG8B[slot].data_size);
|
||||
NF_DmaMemCopy((void*)pal, NF_BG8B[slot].pal, NF_BG8B[slot].pal_size);
|
||||
|
||||
} else {
|
||||
|
||||
// Copia los datos al BackBuffer
|
||||
memcpy(NF_8BITS_BACKBUFFER[scr].data, NF_BG8B[slot].data, NF_BG8B[slot].data_size);
|
||||
memcpy(NF_8BITS_BACKBUFFER[scr].pal, NF_BG8B[slot].pal, NF_BG8B[slot].pal_size);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Init8bitsBackBuffer();
|
||||
void NF_Init8bitsBackBuffer(u8 screen) {
|
||||
u8 scr = screen;
|
||||
if (scr > 1) scr = 1;
|
||||
NF_8BITS_BACKBUFFER[scr].data = NULL;
|
||||
NF_8BITS_BACKBUFFER[scr].pal = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Enable8bitsBackBuffer();
|
||||
void NF_Enable8bitsBackBuffer(u8 screen) {
|
||||
u8 scr = screen;
|
||||
if (scr > 1) scr = 1;
|
||||
// Resetea el buffer
|
||||
free(NF_8BITS_BACKBUFFER[scr].data);
|
||||
free(NF_8BITS_BACKBUFFER[scr].pal);
|
||||
NF_8BITS_BACKBUFFER[scr].data = NULL;
|
||||
NF_8BITS_BACKBUFFER[scr].pal = NULL;
|
||||
// Asignale 64kb de memoria para datos
|
||||
NF_8BITS_BACKBUFFER[scr].data = (u8*) calloc(65536, sizeof(u8));
|
||||
if (NF_8BITS_BACKBUFFER[scr].data == NULL) NF_Error(102, NULL, 65536);
|
||||
// Asignale 512 bytes de memoria para paletas
|
||||
NF_8BITS_BACKBUFFER[scr].pal = (u16*) calloc(256, sizeof(u16));
|
||||
if (NF_8BITS_BACKBUFFER[scr].pal == NULL) NF_Error(102, NULL, 512);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Disble8bitsBackBuffer();
|
||||
void NF_Disble8bitsBackBuffer(u8 screen) {
|
||||
u8 scr = screen;
|
||||
if (scr > 1) scr = 1;
|
||||
// Resetea el buffer
|
||||
free(NF_8BITS_BACKBUFFER[scr].data);
|
||||
free(NF_8BITS_BACKBUFFER[scr].pal);
|
||||
NF_8BITS_BACKBUFFER[scr].data = NULL;
|
||||
NF_8BITS_BACKBUFFER[scr].pal = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_Flip8bitsBackBuffer();
|
||||
void NF_Flip8bitsBackBuffer(u8 screen, u8 destination) {
|
||||
|
||||
// Copia el contenido del Backbuffer a la VRAM
|
||||
// de la pantalla solicitada
|
||||
u8 scr = screen;
|
||||
if (scr > 1) scr = 1;
|
||||
|
||||
// Segun la pantalla...
|
||||
u32 data = 0;
|
||||
u32 pal = 0;
|
||||
if (scr == 0) {
|
||||
data = (0x06000000); // Direccion en VRAM para los datos
|
||||
pal = (0x05000000); // Direccion en VRAM para la paleta
|
||||
} else {
|
||||
data = (0x06200000); // Direccion en VRAM para los datos
|
||||
pal = (0x05000400); // Direccion en VRAM para la paleta
|
||||
}
|
||||
|
||||
// Segun la capa
|
||||
if (destination == 1) data += 65536;
|
||||
|
||||
// Copia los datos a la VRAM
|
||||
NF_DmaMemCopy((void*)data, NF_8BITS_BACKBUFFER[scr].data, 65536);
|
||||
NF_DmaMemCopy((void*)pal, NF_8BITS_BACKBUFFER[scr].pal, 512);
|
||||
|
||||
}
|
365
examples/templates/using_nflib/nflib/source/nf_colision.c
Normal file
365
examples/templates/using_nflib/nflib/source/nf_colision.c
Normal file
@ -0,0 +1,365 @@
|
||||
|
||||
// NightFox LIB - Funciones de Colisiones
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
#include <filesystem.h>
|
||||
#include <fat.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_basic.h"
|
||||
#include "nf_colision.h"
|
||||
|
||||
|
||||
|
||||
|
||||
// Define los buffers y estructuras de control de los mapas de colision
|
||||
NF_TYPE_CMAP_INFO NF_CMAP[NF_SLOTS_CMAP];
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitCmapBuffers();
|
||||
void NF_InitCmapBuffers(void) {
|
||||
u8 n = 0;
|
||||
for (n = 0; n < NF_SLOTS_CMAP; n ++) {
|
||||
NF_CMAP[n].tiles = NULL; // Inicializa los punteros de los buffers
|
||||
NF_CMAP[n].map = NULL;
|
||||
NF_CMAP[n].tiles_size = 0; // Tamaño de archivo
|
||||
NF_CMAP[n].map_size = 0;
|
||||
NF_CMAP[n].width = 0; // Ancho del mapa
|
||||
NF_CMAP[n].height = 0; // Alto del mapa
|
||||
NF_CMAP[n].inuse = false; // Esta en uso el slot?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ResetCmapBuffers();
|
||||
void NF_ResetCmapBuffers(void) {
|
||||
u8 n = 0;
|
||||
for (n = 0; n < NF_SLOTS_CMAP; n ++) {
|
||||
free(NF_CMAP[n].tiles); // Vacia los buffers
|
||||
free(NF_CMAP[n].map);
|
||||
}
|
||||
NF_InitCmapBuffers(); // Y reinicia todas las variables
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadColisionMap();
|
||||
void NF_LoadColisionMap(const char* file, u8 id, u16 width, u16 height) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_CMAP)) {
|
||||
NF_Error(106, "Colision Map", NF_SLOTS_CMAP);
|
||||
}
|
||||
|
||||
// Verifica si la Id esta libre
|
||||
if (NF_CMAP[id].inuse) {
|
||||
NF_Error(109, "Colision Map", id);
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_CMAP[id].map);
|
||||
NF_CMAP[id].map = NULL;
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
|
||||
// Carga el archivo .CMP
|
||||
sprintf(filename, "%s/%s.cmp", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
NF_CMAP[id].map_size = ftell(file_id);
|
||||
rewind(file_id);
|
||||
// Reserva el espacio en RAM
|
||||
NF_CMAP[id].map = (char*) calloc (NF_CMAP[id].map_size, sizeof(char));
|
||||
if (NF_CMAP[id].map == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_CMAP[id].map_size);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_CMAP[id].map, 1, NF_CMAP[id].map_size, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
|
||||
// Guarda las medidas
|
||||
NF_CMAP[id].width = width;
|
||||
NF_CMAP[id].height = height;
|
||||
|
||||
// Y marca esta ID como usada
|
||||
NF_CMAP[id].inuse = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadColisionMap();
|
||||
void NF_UnloadColisionMap(u8 id) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_CMAP)) {
|
||||
NF_Error(106, "Colision Map", NF_SLOTS_CMAP);
|
||||
}
|
||||
|
||||
// Verifica si la Id esta libre
|
||||
if (!NF_CMAP[id].inuse) {
|
||||
NF_Error(110, "Colision Map", id);
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_CMAP[id].map);
|
||||
NF_CMAP[id].map = NULL;
|
||||
|
||||
// Y marca esta ID como usada
|
||||
NF_CMAP[id].inuse = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetTile();
|
||||
u16 NF_GetTile(u8 slot, s32 x, s32 y) {
|
||||
|
||||
// Si la coordenada esta fuera de rango, devuelve 0
|
||||
if (
|
||||
(x < 0)
|
||||
||
|
||||
(y < 0)
|
||||
||
|
||||
(x >= NF_CMAP[slot].width)
|
||||
||
|
||||
(y >= NF_CMAP[slot].height)
|
||||
) {
|
||||
// Devuelve 0
|
||||
return 0;
|
||||
|
||||
} else { // Si la coordenada esta dentro del rango...
|
||||
|
||||
// Calcula el ancho en tiles del mapa
|
||||
u16 columns = (NF_CMAP[slot].width >> 3); // (width / 8);
|
||||
|
||||
// Calcula los tiles de posicion (x / 8); (y / 8);
|
||||
u16 tile_x = (x >> 3);
|
||||
u16 tile_y = (y >> 3) + 1; // +1, por que la primera fila se reserva para la referencia de tiles
|
||||
|
||||
// Calcula el nº de tile
|
||||
u32 address = (((tile_y * columns) + tile_x) << 1);
|
||||
|
||||
// Obten los bytes
|
||||
u8 lobyte = *(NF_CMAP[slot].map + address);
|
||||
u8 hibyte = *(NF_CMAP[slot].map + (address + 1));
|
||||
|
||||
// Devuelve el valor del tile
|
||||
return ((hibyte << 8) | lobyte);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SetTile();
|
||||
void NF_SetTile(u8 slot, s32 x, s32 y, u16 value) {
|
||||
|
||||
// Si la coordenada esta dentro del rango...
|
||||
if (
|
||||
(x >= 0)
|
||||
&&
|
||||
(y >= 0)
|
||||
&&
|
||||
(x < NF_CMAP[slot].width)
|
||||
&&
|
||||
(y < NF_CMAP[slot].height)
|
||||
) {
|
||||
|
||||
// Calcula el ancho en tiles del mapa
|
||||
u16 columns = (NF_CMAP[slot].width >> 3); // (width / 8);
|
||||
|
||||
// Calcula los tiles de posicion (x / 8); (y / 8);
|
||||
u16 tile_x = (x >> 3);
|
||||
u16 tile_y = (y >> 3) + 1; // +1, por que la primera fila se reserva para la referencia de tiles
|
||||
|
||||
// Calcula el nº de tile
|
||||
u32 address = (((tile_y * columns) + tile_x) << 1);
|
||||
// nº de tile x2, dado que el mapa es de 16 bits (2 bytes por dato) y el buffer
|
||||
// es de 8 bits, se lee el 2do byte, por eso se multiplica por 2.
|
||||
|
||||
// Calcula los valores de los bytes
|
||||
u8 hibyte = ((value >> 8) & 0xff); // HI Byte
|
||||
u8 lobyte = (value & 0xff); // LO Byte
|
||||
|
||||
// Escribe el nuevo valor en el mapa de colisiones
|
||||
*(NF_CMAP[slot].map + address) = lobyte;
|
||||
*(NF_CMAP[slot].map + (address + 1)) = hibyte;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadColisionBg();
|
||||
void NF_LoadColisionBg(const char* file, u8 id, u16 width, u16 height) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_CMAP)) {
|
||||
NF_Error(106, "Colision Map", NF_SLOTS_CMAP);
|
||||
}
|
||||
|
||||
// Verifica si la Id esta libre
|
||||
if (NF_CMAP[id].inuse) {
|
||||
NF_Error(109, "Colision Map", id);
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_CMAP[id].tiles);
|
||||
NF_CMAP[id].tiles = NULL;
|
||||
free(NF_CMAP[id].map);
|
||||
NF_CMAP[id].map = NULL;
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
|
||||
// Carga el archivo .DAT (TILES)
|
||||
sprintf(filename, "%s/%s.dat", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
NF_CMAP[id].tiles_size = ftell(file_id);
|
||||
rewind(file_id);
|
||||
// Reserva el espacio en RAM
|
||||
NF_CMAP[id].tiles = (char*) calloc (NF_CMAP[id].tiles_size, sizeof(char));
|
||||
if (NF_CMAP[id].tiles == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_CMAP[id].tiles_size);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_CMAP[id].tiles, 1, NF_CMAP[id].tiles_size, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
|
||||
// Carga el archivo .CMP
|
||||
sprintf(filename, "%s/%s.cmp", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
NF_CMAP[id].map_size = ftell(file_id);
|
||||
rewind(file_id);
|
||||
// Reserva el espacio en RAM
|
||||
NF_CMAP[id].map = (char*) calloc (NF_CMAP[id].map_size, sizeof(char));
|
||||
if (NF_CMAP[id].map == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_CMAP[id].map_size);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_CMAP[id].map, 1, NF_CMAP[id].map_size, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
|
||||
// Guarda las medidas
|
||||
NF_CMAP[id].width = width;
|
||||
NF_CMAP[id].height = height;
|
||||
|
||||
// Y marca esta ID como usada
|
||||
NF_CMAP[id].inuse = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadColisionBg();
|
||||
void NF_UnloadColisionBg(u8 id) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_CMAP)) {
|
||||
NF_Error(106, "Colision Map", NF_SLOTS_CMAP);
|
||||
}
|
||||
|
||||
// Verifica si la Id esta libre
|
||||
if (!NF_CMAP[id].inuse) {
|
||||
NF_Error(110, "Colision Map", id);
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_CMAP[id].tiles);
|
||||
NF_CMAP[id].tiles = NULL;
|
||||
free(NF_CMAP[id].map);
|
||||
NF_CMAP[id].map = NULL;
|
||||
|
||||
// Y marca esta ID como usada
|
||||
NF_CMAP[id].inuse = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_GetPoint();
|
||||
u8 NF_GetPoint(u8 slot, s32 x, s32 y) {
|
||||
|
||||
// Si la coordenada esta fuera de rango, devuelve 0
|
||||
if (
|
||||
(x < 0)
|
||||
||
|
||||
(y < 0)
|
||||
||
|
||||
(x >= NF_CMAP[slot].width)
|
||||
||
|
||||
(y >= NF_CMAP[slot].height)
|
||||
) {
|
||||
// Devuelve 0
|
||||
return 0;
|
||||
|
||||
} else { // Si la coordenada esta dentro del rango...
|
||||
|
||||
// Calcula el ancho en tiles del mapa
|
||||
u16 columns = (NF_CMAP[slot].width >> 3); // (width / 8);
|
||||
|
||||
// Calcula los tiles de posicion (x / 8); (y / 8);
|
||||
u16 tile_x = (x >> 3);
|
||||
u16 tile_y = (y >> 3) + 1; // +1, por que la primera fila se reserva para la referencia de tiles
|
||||
|
||||
// Calcula los pixeles relativos
|
||||
u16 pixel_x = x - (tile_x << 3);
|
||||
u16 pixel_y = (y + 8) - (tile_y << 3);
|
||||
|
||||
// Calcula la posicion de tile dentro del archivo de mapa
|
||||
s32 address = (((tile_y * columns) + tile_x) << 1);
|
||||
u8 lobyte = *(NF_CMAP[slot].map + address);
|
||||
u8 hibyte = *(NF_CMAP[slot].map + (address + 1));
|
||||
u16 tile = ((hibyte << 8) | lobyte);
|
||||
|
||||
// Obten el valor del pixel leyendola del archivo de tiles
|
||||
address = ((tile << 6) + (pixel_y << 3) + pixel_x); // (tile * 64) + (y * 8) + x
|
||||
lobyte = *(NF_CMAP[slot].tiles + address);
|
||||
|
||||
// Devuelve el valor del pixel
|
||||
return lobyte;
|
||||
|
||||
}
|
||||
|
||||
}
|
218
examples/templates/using_nflib/nflib/source/nf_media.c
Normal file
218
examples/templates/using_nflib/nflib/source/nf_media.c
Normal file
@ -0,0 +1,218 @@
|
||||
|
||||
// NightFox LIB - Include de funciones de carga de archivos multimedia
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
#include <filesystem.h>
|
||||
#include <fat.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_media.h"
|
||||
#include "nf_bitmapbg.h"
|
||||
#include "nf_basic.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadBMP();
|
||||
void NF_LoadBMP(const char* file, u8 slot) {
|
||||
|
||||
// Buffers locales
|
||||
char* buffer; // Buffer temporal
|
||||
buffer = NULL;
|
||||
char* palette; // Paleta (requerida por algun modo)
|
||||
palette = NULL;
|
||||
|
||||
// Magic ID
|
||||
char magic_id[4];
|
||||
memset(magic_id, 0, 4);
|
||||
|
||||
// Define la estructura para almacenar la cabecera del BMP
|
||||
typedef struct {
|
||||
u32 bmp_size; // Tamaño en bytes del BMP
|
||||
u16 res_a; // Reservado
|
||||
u16 res_b; // Reservado
|
||||
u32 offset; // Offset donde empiezan los datos
|
||||
u32 header_size; // Tamaño de la cabecera (40 bytes)
|
||||
u32 bmp_width; // Ancho de la imagen en pixeles
|
||||
u32 bmp_height; // Altura de la imagen en pixeles
|
||||
u16 color_planes; // Numero de planos de color
|
||||
u16 bpp; // Numero de bits por pixel
|
||||
u32 compression; // Compresion usada
|
||||
u32 raw_size; // Tamaño de los datos en RAW despues de la cabecera
|
||||
u32 dpi_hor; // Puntos por pulgada (horizontal)
|
||||
u32 dpi_ver; // Puntos por pulgada (vertical)
|
||||
u32 pal_colors; // Numero de colores en la paleta
|
||||
u32 imp_colors; // Colores importantes
|
||||
} bmp_header_info;
|
||||
bmp_header_info bmp_header;
|
||||
|
||||
// Pon todos los bytes de la estructura a 0
|
||||
memset(&bmp_header, 0, sizeof(bmp_header));
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
|
||||
// Carga el archivo .BMP
|
||||
sprintf(filename, "%s/%s.bmp", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Posicionate en el byte 0
|
||||
fseek(file_id, 0, SEEK_SET);
|
||||
// Lee el Magic String del archivo BMP (2 primeros Bytes, "BM") / (0x00 - 0x01)
|
||||
fread(magic_id, 1, 2, file_id);
|
||||
// Si es un archivo BMP... (Magic string == "BM")
|
||||
if (strcmp(magic_id, "BM") == 0) {
|
||||
// Posicionate en el byte 2
|
||||
fseek(file_id, 2, SEEK_SET);
|
||||
// Lee la cabecera del archivo BMP (0x02 - 0x36)
|
||||
fread((void*)&bmp_header, 1, sizeof(bmp_header), file_id);
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Es un archivo BMP valido, cargalo en un buffer temporal //
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Crea un buffer temporal
|
||||
buffer = (char*) calloc (bmp_header.raw_size, sizeof(char));
|
||||
if (buffer == NULL) NF_Error(102, NULL, bmp_header.raw_size);
|
||||
// Si se ha creado con exito, carga el archivo al buffer
|
||||
fseek(file_id, bmp_header.offset, SEEK_SET);
|
||||
fread(buffer, 1, bmp_header.raw_size, file_id);
|
||||
} else {
|
||||
// No es un archivo BMP valido
|
||||
NF_Error(101, "BMP", 0);
|
||||
}
|
||||
} else {
|
||||
// El archivo no existe
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
// Cierra el archivo
|
||||
fclose(file_id);
|
||||
|
||||
// Variables que se usaran a partir de aqui
|
||||
u16 pixel = 0; // Color del pixel
|
||||
u16 x = 0; // Coordemada X
|
||||
u16 y = 0; // Coordenada Y
|
||||
u32 idx = 0; // Indice en el buffer temporal
|
||||
u32 offset = 0; // Indice en el buffer de destino
|
||||
u8 r = 0; // Valores RGB
|
||||
u8 g = 0;
|
||||
u8 b = 0;
|
||||
u16 colors = 0; // En 8 bits, numero de colores
|
||||
u32 size = 0; // Tamaño del buffer de 16 bits (en bytes)
|
||||
|
||||
// Habilita el buffer de destino (u16 de alto x ancho del tamaño de imagen)
|
||||
size = ((bmp_header.bmp_width * bmp_header.bmp_height) << 1);
|
||||
free(NF_BG16B[slot].buffer);
|
||||
NF_BG16B[slot].buffer = NULL;
|
||||
NF_BG16B[slot].buffer = (u16*) calloc ((size >> 1), sizeof(u16));
|
||||
if (NF_BG16B[slot].buffer == NULL) NF_Error(102, NULL, size);
|
||||
|
||||
// Segun los BITS por Pixel (8, 16, 24)
|
||||
switch (bmp_header.bpp) {
|
||||
|
||||
case 8: // 8 bits por pixel
|
||||
// Calcula el tamaño de la paleta
|
||||
colors = ((bmp_header.offset - 0x36) >> 2);
|
||||
palette = (char*) calloc ((colors << 2), sizeof(char));
|
||||
if (palette == NULL) NF_Error(102, NULL, (colors << 2));
|
||||
// Abre de nuevo el archivo y carga la paleta
|
||||
file_id = fopen(filename, "rb");
|
||||
if (!file_id) NF_Error(101, filename, 0);
|
||||
fseek(file_id, 0x36, SEEK_SET);
|
||||
fread(palette, 1, (colors << 2), file_id);
|
||||
fclose(file_id);
|
||||
// Convierte el archivo a 16 bits
|
||||
for (y = 0; y < bmp_header.bmp_height; y ++) {
|
||||
for (x = 0; x < bmp_header.bmp_width; x ++) {
|
||||
// Calcula los offsets
|
||||
offset = ((((bmp_header.bmp_height - 1) - y) * bmp_header.bmp_width) + x);
|
||||
// Obten el pixel
|
||||
pixel = (buffer[idx] << 2);
|
||||
// Desglosa el RGB para rotar los colores BGR -> RGB
|
||||
b = (palette[pixel] >> 3);
|
||||
g = (palette[(pixel + 1)] >> 3);
|
||||
r = (palette[(pixel + 2)] >> 3);
|
||||
// Recombina el RGB a 16 bits
|
||||
pixel = ((r)|((g) << 5)|((b) << 10)|(BIT(15)));
|
||||
NF_BG16B[slot].buffer[offset] = pixel;
|
||||
// Siguiente pixel
|
||||
idx ++;
|
||||
}
|
||||
// Ajusta la alineacion a 4 bytes al final de linea
|
||||
while ((idx % 4) != 0) idx ++;
|
||||
}
|
||||
// Elimina la paleta de la RAM
|
||||
free(palette);
|
||||
palette = NULL;
|
||||
break;
|
||||
|
||||
case 16: // 16 bits por pixel
|
||||
for (y = 0; y < bmp_header.bmp_height; y ++) {
|
||||
for (x = 0; x < bmp_header.bmp_width; x ++) {
|
||||
// Calcula los offsets
|
||||
offset = ((((bmp_header.bmp_height - 1) - y) * bmp_header.bmp_width) + x);
|
||||
// Obten el pixel
|
||||
pixel = buffer[idx] + (buffer[(idx + 1)] << 8);
|
||||
// Desglosa el RGB para rotar los colores BGR -> RGB
|
||||
b = (pixel & 0x1F);
|
||||
g = ((pixel >> 5) & 0x1F);
|
||||
r = ((pixel >> 10) & 0x1F);
|
||||
// Recombina el RGB a 16 bits
|
||||
pixel = ((r)|((g) << 5)|((b) << 10)|(BIT(15)));
|
||||
NF_BG16B[slot].buffer[offset] = pixel;
|
||||
// Siguiente pixel
|
||||
idx += 2;
|
||||
}
|
||||
// Ajusta la alineacion a 4 bytes al final de linea
|
||||
while ((idx % 4) != 0) idx ++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24: // 24 bits por pixel
|
||||
for (y = 0; y < bmp_header.bmp_height; y ++) {
|
||||
for (x = 0; x < bmp_header.bmp_width; x ++) {
|
||||
// Calcula los offsets
|
||||
offset = ((((bmp_header.bmp_height - 1) - y) * bmp_header.bmp_width) + x);
|
||||
// Obten el pixel
|
||||
b = ((buffer[idx]) >> 3);
|
||||
g = ((buffer[idx + 1]) >> 3);
|
||||
r = ((buffer[idx + 2]) >> 3);
|
||||
// Recombina el RGB a 16 bits
|
||||
pixel = ((r)|((g) << 5)|((b) << 10)|(BIT(15)));
|
||||
NF_BG16B[slot].buffer[offset] = pixel;
|
||||
// Siguiente pixel
|
||||
idx += 3;
|
||||
}
|
||||
// Ajusta la alineacion a 4 bytes al final de linea
|
||||
while ((idx % 4) != 0) idx ++;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Guarda los parametros del fondo
|
||||
NF_BG16B[slot].size = size; // Guarda el tamaño
|
||||
NF_BG16B[slot].width = bmp_header.bmp_width; // Ancho del fondo
|
||||
NF_BG16B[slot].height = bmp_header.bmp_height; // Altura del fondo
|
||||
NF_BG16B[slot].inuse = true; // Marca que esta en uso
|
||||
|
||||
// Libera el buffer temporal
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
|
||||
}
|
126
examples/templates/using_nflib/nflib/source/nf_mixedbg.c
Normal file
126
examples/templates/using_nflib/nflib/source/nf_mixedbg.c
Normal file
@ -0,0 +1,126 @@
|
||||
|
||||
// NightFox LIB - Include de Fondos mixtos (Tiled / Bitmap 8 bits)
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
#include <filesystem.h>
|
||||
#include <fat.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_basic.h"
|
||||
#include "nf_2d.h"
|
||||
#include "nf_tiledbg.h"
|
||||
#include "nf_bitmapbg.h"
|
||||
#include "nf_mixedbg.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitMixedBgSys();
|
||||
void NF_InitMixedBgSys(u8 screen) {
|
||||
|
||||
// Variables
|
||||
u8 n = 0;
|
||||
|
||||
// Define el numero de bancos de Mapas y Tiles
|
||||
NF_BANKS_TILES[screen] = 4; // (1 banks = 16kb) Cada banco de tiles puede alvergar 8 bancos de Mapas
|
||||
NF_BANKS_MAPS[screen] = 8; // (1 bank = 2kb) Usar multiplos de 8. Cada set de 8 bancos consume 1 banco de tiles
|
||||
// Por defecto Tiles = 4, Mapas = 8
|
||||
// Esto nos deja 3 bancos de 16kb para tiles
|
||||
// y 8 bancos de 2kb para mapas
|
||||
|
||||
// Inicializa el array de bloques libres de Tiles
|
||||
for (n = 0; n < NF_BANKS_TILES[screen]; n ++) {
|
||||
NF_TILEBLOCKS[screen][n] = 0;
|
||||
}
|
||||
|
||||
// Inicializa el array de bloques libres de Mapas
|
||||
for (n = 0; n < NF_BANKS_MAPS[screen]; n ++) {
|
||||
NF_MAPBLOCKS[screen][n] = 0;
|
||||
}
|
||||
|
||||
// Inicializa el array de informacion de fondos en pantalla
|
||||
for (n = 0; n < 4; n ++) {
|
||||
NF_TILEDBG_LAYERS[screen][n].tilebase = 0; // Base del Tileset
|
||||
NF_TILEDBG_LAYERS[screen][n].tileblocks = 0; // Bloques usados por el Tileset
|
||||
NF_TILEDBG_LAYERS[screen][n].mapbase = 0; // Base del Map
|
||||
NF_TILEDBG_LAYERS[screen][n].mapblocks = 0; // Bloques usados por el Map
|
||||
NF_TILEDBG_LAYERS[screen][n].bgwidth = 0; // Ancho del fondo
|
||||
NF_TILEDBG_LAYERS[screen][n].bgheight = 0; // Altura del fondo
|
||||
NF_TILEDBG_LAYERS[screen][n].mapwidth = 0; // Ancho del mapa
|
||||
NF_TILEDBG_LAYERS[screen][n].mapheight = 0; // Altura del mapa
|
||||
NF_TILEDBG_LAYERS[screen][n].bgtype = 0; // Tipo de mapa
|
||||
NF_TILEDBG_LAYERS[screen][n].bgslot = 0; // Buffer de graficos usado
|
||||
NF_TILEDBG_LAYERS[screen][n].blockx = 0; // Bloque de mapa actual (horizontal)
|
||||
NF_TILEDBG_LAYERS[screen][n].blocky = 0; // Bloque de mapa actual (vertical)
|
||||
NF_TILEDBG_LAYERS[screen][n].created = false; // Esta creado ?
|
||||
}
|
||||
|
||||
// Ahora reserva los bancos necesarios de VRAM para mapas
|
||||
// Cada bloque de 16kb (1 banco de tiles) permite 8 bancos de mapas (de 2kb cada uno)
|
||||
u8 r_banks;
|
||||
r_banks = ((NF_BANKS_MAPS[screen] - 1) >> 3) + 1; // Calcula los bancos de Tiles a reservar para Maps
|
||||
for (n = 0; n < r_banks; n ++) {
|
||||
NF_TILEBLOCKS[screen][n] = 128; // Marca que bancos de VRAM son para MAPS
|
||||
}
|
||||
|
||||
if (screen == 0) {
|
||||
// Si es la pantalla 0 (Superior, Main engine)
|
||||
REG_DISPCNT |= (DISPLAY_BG_EXT_PALETTE); // Activa las paletas extendidas
|
||||
vramSetBankA(VRAM_A_MAIN_BG); // Banco A de la VRAM para fondos (128kb)
|
||||
memset((void*)0x06000000, 0, 131072); // Borra el contenido del banco A
|
||||
vramSetBankE(VRAM_E_LCD); // Reserva el banco E de la VRAM para Paletas Extendidas (0-3) (32kb de 64kb)
|
||||
memset((void*)0x06880000, 0, 32768); // Borra el contenido del banco E
|
||||
for (n = 0; n < 4; n ++) { // Oculta todas las 4 capas
|
||||
NF_HideBg(0, n);
|
||||
}
|
||||
} else {
|
||||
// Si es la pantalla 1 (Inferior, Sub engine)
|
||||
REG_DISPCNT_SUB |= (DISPLAY_BG_EXT_PALETTE); // Activa las paletas extendidas
|
||||
vramSetBankC(VRAM_C_SUB_BG); // Banco C de la VRAM para fondos (128kb)
|
||||
memset((void*)0x06200000, 0, 131072); // Borra el contenido del banco C
|
||||
vramSetBankH(VRAM_H_LCD); // Reserva el banco H de la VRAM para Paletas Extendidas (0-3) (32kb)
|
||||
memset((void*)0x06898000, 0, 32768); // Borra el contenido del banco H
|
||||
for (n = 0; n < 4; n ++) { // Oculta todas las 4 capas
|
||||
NF_HideBg(1, n);
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializa la capa de dibujado para bitmaps (capa 3 unicamente)
|
||||
if (screen == 0) {
|
||||
// Modo 8 bits (Capas 3)
|
||||
REG_BG3CNT = BG_PRIORITY_3 | BG_BMP_BASE(4) | BG_BMP8_256x256;
|
||||
// Resetea los registros de RotScale (Capa 3)
|
||||
REG_BG3PA = (1 << 8);
|
||||
REG_BG3PB = 0;
|
||||
REG_BG3PC = 0;
|
||||
REG_BG3PD = (1 << 8);
|
||||
NF_ScrollBg(0, 3, 0, 0); // Posicionala en 0, 0
|
||||
NF_ShowBg(0, 3); // Muestra la capa 3
|
||||
} else {
|
||||
// Modo 8 bits (Capas 2 y 3)
|
||||
REG_BG3CNT_SUB = BG_PRIORITY_3 | BG_BMP_BASE(4) | BG_BMP8_256x256;
|
||||
// Resetea los registros de RotScale (Capa 3)
|
||||
REG_BG3PA_SUB = (1 << 8);
|
||||
REG_BG3PB_SUB = 0;
|
||||
REG_BG3PC_SUB = 0;
|
||||
REG_BG3PD_SUB = (1 << 8);
|
||||
NF_ScrollBg(1, 3, 0, 0); // Posicionala en 0, 0
|
||||
NF_ShowBg(1, 3); // Muestra la capa 3
|
||||
}
|
||||
|
||||
}
|
175
examples/templates/using_nflib/nflib/source/nf_sound.c
Normal file
175
examples/templates/using_nflib/nflib/source/nf_sound.c
Normal file
@ -0,0 +1,175 @@
|
||||
|
||||
// NightFox LIB - Funciones de de funciones de sonido
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
#include <filesystem.h>
|
||||
#include <fat.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_basic.h"
|
||||
#include "nf_sound.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Define los Buffers para almacenar los archivos de audio
|
||||
char* NF_BUFFER_RAWSOUND[NF_SLOTS_RAWSOUND];
|
||||
|
||||
// Datos de los sonidos cargado
|
||||
NF_TYPE_RAWSOUND_INFO NF_RAWSOUND[NF_SLOTS_RAWSOUND];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitRawSoundBuffers();
|
||||
void NF_InitRawSoundBuffers(void) {
|
||||
|
||||
u8 n = 0; // Variable comun
|
||||
|
||||
// Inicializa Buffers de sonido en RAW
|
||||
for (n = 0; n < NF_SLOTS_RAWSOUND; n ++) {
|
||||
NF_BUFFER_RAWSOUND[n] = NULL; // Inicializa puntero
|
||||
NF_RAWSOUND[n].available = true; // Disponibilidad del slot
|
||||
NF_RAWSOUND[n].size = 0; // Tamaño del archivo
|
||||
NF_RAWSOUND[n].freq = 0; // Frecuencia del sample
|
||||
NF_RAWSOUND[n].format = 0; // Formato del sample
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ResetRawSoundBuffers();
|
||||
void NF_ResetRawSoundBuffers(void) {
|
||||
|
||||
u8 n = 0; // Variable comun
|
||||
|
||||
// Borra los datos de los buffers de sonido en RAW
|
||||
for (n = 0; n < NF_SLOTS_RAWSOUND; n ++) {
|
||||
free(NF_BUFFER_RAWSOUND[n]); // Borra el contenido puntero
|
||||
}
|
||||
|
||||
// Reinicia las estructuras de datos
|
||||
NF_InitRawSoundBuffers();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadRawSound();
|
||||
void NF_LoadRawSound(const char* file, u16 id, u16 freq, u8 format) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_RAWSOUND)) {
|
||||
NF_Error(106, "Raw Sound", NF_SLOTS_RAWSOUND);
|
||||
}
|
||||
|
||||
// Verifica si la Id esta libre
|
||||
if (!NF_RAWSOUND[id].available) {
|
||||
NF_Error(109, "Raw Sound", id);
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_BUFFER_RAWSOUND[id]);
|
||||
NF_BUFFER_RAWSOUND[id] = NULL;
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
|
||||
// Carga el archivo .RAW
|
||||
sprintf(filename, "%s/%s.raw", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
NF_RAWSOUND[id].size = ftell(file_id);
|
||||
rewind(file_id);
|
||||
// Si excede del tamaño maximo, error
|
||||
if (NF_RAWSOUND[id].size > (1 << 18)) NF_Error(116, filename, (1 << 18));
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_RAWSOUND[id] = (char*) calloc (NF_RAWSOUND[id].size, sizeof(char));
|
||||
if (NF_BUFFER_RAWSOUND[id] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_RAWSOUND[id].size);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BUFFER_RAWSOUND[id], 1, NF_RAWSOUND[id].size, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
// swiWaitForVBlank(); // Espera al cierre del archivo (Usar en caso de corrupcion de datos)
|
||||
|
||||
// Guarda los parametros del archivo de sonido
|
||||
NF_RAWSOUND[id].freq = freq; // Frequencia del sample (en Hz)
|
||||
NF_RAWSOUND[id].format = format; // Formato del sample (0 - > 8 bits, 1 - > 16 bits, 2 -> ADPCM)
|
||||
|
||||
// Y marca esta ID como usada
|
||||
NF_RAWSOUND[id].available = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion UnloadRawSound();
|
||||
void NF_UnloadRawSound(u8 id) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_RAWSOUND)) NF_Error(106, "RAW Sound", NF_SLOTS_RAWSOUND);
|
||||
|
||||
// Verifica si el sonido existe
|
||||
if (NF_RAWSOUND[id].available) NF_Error(110, "RAW Sound", id);
|
||||
|
||||
// Vacia los buffers de la Id. seleccionada
|
||||
free(NF_BUFFER_RAWSOUND[id]);
|
||||
NF_BUFFER_RAWSOUND[id] = NULL;
|
||||
|
||||
// Resetea las variables
|
||||
NF_RAWSOUND[id].freq = 0; // Frequencia del sample (en Hz)
|
||||
NF_RAWSOUND[id].format = 0; // Formato del sample (0 - > 8 bits, 1 - > 16 bits, 2 -> ADPCM)
|
||||
|
||||
// Y marca esta ID como libre
|
||||
NF_RAWSOUND[id].available = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_PlayRawSound();
|
||||
u8 NF_PlayRawSound(u8 id, u8 volume, u8 pan, bool loop, u16 loopfrom) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_RAWSOUND)) NF_Error(106, "RAW Sound", NF_SLOTS_RAWSOUND);
|
||||
|
||||
// Verifica si el sonido existe
|
||||
if (NF_RAWSOUND[id].available) NF_Error(110, "RAW Sound", id);
|
||||
|
||||
return soundPlaySample(NF_BUFFER_RAWSOUND[id], NF_RAWSOUND[id].format, NF_RAWSOUND[id].size, NF_RAWSOUND[id].freq, volume, pan, loop, loopfrom);
|
||||
|
||||
}
|
989
examples/templates/using_nflib/nflib/source/nf_sprite256.c
Normal file
989
examples/templates/using_nflib/nflib/source/nf_sprite256.c
Normal file
@ -0,0 +1,989 @@
|
||||
|
||||
// NightFox LIB - Funciones de Sprites a 256 colores
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
#include <filesystem.h>
|
||||
#include <fat.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_basic.h"
|
||||
#include "nf_2d.h"
|
||||
#include "nf_sprite256.h"
|
||||
|
||||
|
||||
|
||||
// Define los Buffers para almacenar los Sprites
|
||||
char* NF_BUFFER_SPR256GFX[NF_SLOTS_SPR256GFX];
|
||||
char* NF_BUFFER_SPR256PAL[NF_SLOTS_SPR256PAL];
|
||||
|
||||
// Define la estructura de datos de los Graficos de los Sprites
|
||||
NF_TYPE_SPR256GFX_INFO NF_SPR256GFX[NF_SLOTS_SPR256GFX];
|
||||
// Define la estructura de datos de las Paletas de los Sprites
|
||||
NF_TYPE_SPR256PAL_INFO NF_SPR256PAL[NF_SLOTS_SPR256PAL];
|
||||
|
||||
// Define la estructura de Gfx en VRAM
|
||||
NF_TYPE_SPR256VRAM_INFO NF_SPR256VRAM[2][128];
|
||||
// Datos de paletas de Sprites en VRAM (en uso, slot en ram, etc)
|
||||
NF_TYPE_SPRPALSLOT_INFO NF_SPRPALSLOT[2][16];
|
||||
|
||||
// Define la estructura de datos del OAM (Sprites)
|
||||
NF_TYPE_SPRITEOAM_INFO NF_SPRITEOAM[2][128]; // 2 pantallas, 128 sprites
|
||||
|
||||
// Define la esturctura de control de la VRAM para Sprites
|
||||
NF_TYPE_SPRVRAM_INFO NF_SPRVRAM[2]; // Informacion VRAM de Sprites en ambas pantallas
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitSpriteBuffers()
|
||||
void NF_InitSpriteBuffers(void) {
|
||||
|
||||
u16 n = 0; // Variable comun
|
||||
|
||||
// Inicializa Buffers de GFX
|
||||
for (n = 0; n < NF_SLOTS_SPR256GFX; n ++) {
|
||||
NF_BUFFER_SPR256GFX[n] = NULL; // Inicializa puntero
|
||||
NF_SPR256GFX[n].size = 0; // Tamaño (en bytes) del grafico (GFX)
|
||||
NF_SPR256GFX[n].width = 0; // Ancho del Gfx
|
||||
NF_SPR256GFX[n].height = 0; // Altura del Gfx
|
||||
NF_SPR256GFX[n].available = true; // Disponibilidat del Slot
|
||||
}
|
||||
|
||||
// Inicializa Buffers de PAL
|
||||
for (n = 0; n < NF_SLOTS_SPR256PAL; n ++) {
|
||||
NF_BUFFER_SPR256PAL[n] = NULL; // Inicializa puntero
|
||||
NF_SPR256PAL[n].size = 0; // Tamaño (en bytes) de la paleta (PAL)
|
||||
NF_SPR256PAL[n].available = true; // Disponibilidat del Slot
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ResetSpriteBuffers()
|
||||
void NF_ResetSpriteBuffers(void) {
|
||||
|
||||
u16 n = 0; // Variable comun
|
||||
|
||||
// Borra los Buffers de GFX
|
||||
for (n = 0; n < NF_SLOTS_SPR256GFX; n ++) {
|
||||
free(NF_BUFFER_SPR256GFX[n]);
|
||||
}
|
||||
|
||||
// Borra los Buffers de PAL
|
||||
for (n = 0; n < NF_SLOTS_SPR256PAL; n ++) {
|
||||
free(NF_BUFFER_SPR256PAL[n]);
|
||||
}
|
||||
|
||||
// Reinicia el sistema de Sprites
|
||||
NF_InitSpriteBuffers();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitSpriteSys();
|
||||
void NF_InitSpriteSys(int screen, ...) {
|
||||
|
||||
// Analiza los parametros variables de la funcion
|
||||
va_list options;
|
||||
va_start(options, screen);
|
||||
u8 mode = va_arg(options, int);
|
||||
va_end(options);
|
||||
|
||||
|
||||
// Variables
|
||||
u8 n = 0; // Uso comun
|
||||
|
||||
// Inicializa la estructura de Gfx en VRAM
|
||||
// y la estructura de datos del OAM (Sprites)
|
||||
for (n = 0; n < 128; n ++) { // 128 sprites
|
||||
// Gfx en la VRAM (128 Gfx x pantalla)
|
||||
NF_SPR256VRAM[screen][n].size = 0; // Tamaño (en bytes) del Gfx
|
||||
NF_SPR256VRAM[screen][n].width = 0; // Ancho del Gfx
|
||||
NF_SPR256VRAM[screen][n].height = 0; // Altura del Gfx
|
||||
NF_SPR256VRAM[screen][n].address = 0; // Posicion en la VRAM
|
||||
NF_SPR256VRAM[screen][n].ramid = 0; // Numero de Slot en RAM del que provienes
|
||||
NF_SPR256VRAM[screen][n].framesize = 0; // Tamaño del frame (en bytes)
|
||||
NF_SPR256VRAM[screen][n].lastframe = 0; // Ultimo frame
|
||||
NF_SPR256VRAM[screen][n].keepframes = false; // Si es un Sprite animado, debes de mantener los frames en RAM ?
|
||||
NF_SPR256VRAM[screen][n].inuse = false; // Esta en uso ?
|
||||
// OAM (128 Sprites x pantalla)
|
||||
NF_SPRITEOAM[screen][n].index = n; // Numero de Sprite (Index = N)
|
||||
NF_SPRITEOAM[screen][n].x = 0; // Coordenada X del Sprite (0 por defecto)
|
||||
NF_SPRITEOAM[screen][n].y = 0; // Coordenada Y del Sprite (0 por defecto)
|
||||
NF_SPRITEOAM[screen][n].layer = 0; // Prioridad en las capas (0 por defecto)
|
||||
NF_SPRITEOAM[screen][n].pal = 0; // Paleta que usaras (0 por defecto)
|
||||
NF_SPRITEOAM[screen][n].size = SpriteSize_8x8; // Tamaño del Sprite (macro) (8x8 por defecto)
|
||||
NF_SPRITEOAM[screen][n].color = SpriteColorFormat_256Color; // Modo de color (macro) (256 colores)
|
||||
NF_SPRITEOAM[screen][n].gfx = NULL; // Puntero al grafico usado
|
||||
NF_SPRITEOAM[screen][n].rot = -1; // Id de rotacion (-1 por defecto) (0 - 31 Id de rotacion)
|
||||
NF_SPRITEOAM[screen][n].doublesize = false; // Usar el "double size" al rotar ? ("NO" por defecto)
|
||||
NF_SPRITEOAM[screen][n].hide = true; // Ocultar el Sprite ("SI" por defecto)
|
||||
NF_SPRITEOAM[screen][n].hflip = false; // Volteado Horizontal ("NO" por defecto)
|
||||
NF_SPRITEOAM[screen][n].vflip = false; // Volteado Vertical ("NO" por defecto)
|
||||
NF_SPRITEOAM[screen][n].mosaic = false; // Mosaico ("NO" por defecto)
|
||||
NF_SPRITEOAM[screen][n].gfxid = 0; // Numero de Gfx usado
|
||||
NF_SPRITEOAM[screen][n].frame = 0; // Frame actual
|
||||
NF_SPRITEOAM[screen][n].framesize = 0; // Tamaño del frame (en bytes)
|
||||
NF_SPRITEOAM[screen][n].lastframe = 0; // Ultimo frame
|
||||
NF_SPRITEOAM[screen][n].created = false; // Esta creado este sprite ?
|
||||
}
|
||||
|
||||
// Inicializa la estructura de datos de la VRAM de Sprites
|
||||
if (mode == 128) {
|
||||
NF_SPRVRAM[screen].max = 131072;
|
||||
} else {
|
||||
NF_SPRVRAM[screen].max = 65536;
|
||||
}
|
||||
NF_SPRVRAM[screen].free = NF_SPRVRAM[screen].max; // Memoria VRAM libre (64kb/128kb)
|
||||
NF_SPRVRAM[screen].last = 0; // Ultima posicion usada
|
||||
NF_SPRVRAM[screen].deleted = 0; // Ningun Gfx borrado
|
||||
NF_SPRVRAM[screen].fragmented = 0; // Memoria VRAM fragmentada
|
||||
NF_SPRVRAM[screen].inarow = NF_SPRVRAM[screen].max; // Memoria VRAM contigua
|
||||
for (n = 0; n < 128; n ++) {
|
||||
NF_SPRVRAM[screen].pos[n] = 0; // Posicion en VRAM para reusar despues de un borrado
|
||||
NF_SPRVRAM[screen].size[n] = 0; // Tamaño del bloque libre para reusar
|
||||
}
|
||||
|
||||
// Inicializa los datos de las paletas
|
||||
for (n = 0; n < 16; n ++) {
|
||||
NF_SPRPALSLOT[screen][n].inuse = false;
|
||||
NF_SPRPALSLOT[screen][n].ramslot = 0;
|
||||
}
|
||||
|
||||
// Configura el Motor 2D y VRAM segun la pantalla de destino
|
||||
if (screen == 0) {
|
||||
|
||||
// Configura la pantalla 0
|
||||
REG_DISPCNT |= (DISPLAY_SPR_ACTIVE); // Activa los Sprites en la pantalla superior
|
||||
vramSetBankB(VRAM_B_MAIN_SPRITE_0x06400000); // Banco B de la VRAM para Sprites (128kb)
|
||||
memset((void*)0x06400000, 0, 131072); // Borra el contenido del banco B
|
||||
NF_SPRVRAM[screen].next = (0x06400000); // Guarda la primera posicion de VRAM para Gfx
|
||||
vramSetBankF(VRAM_F_LCD); // Banco F de la VRAM para paletas extendidas (Sprites) (8kb de 16kb)
|
||||
memset((void*)0x06890000, 0, 8192); // Borra el contenido del banco F
|
||||
if (mode == 128) {
|
||||
oamInit(&oamMain, SpriteMapping_1D_128, true); // Inicializa el OAM (Mapeado de 128 bytes, Paletas extendidas)
|
||||
} else {
|
||||
oamInit(&oamMain, SpriteMapping_1D_64, true); // Inicializa el OAM (Mapeado de 64 bytes, Paletas extendidas)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Configura la pantalla 1
|
||||
REG_DISPCNT_SUB |= (DISPLAY_SPR_ACTIVE); // Activa los Sprites en la pantalla inferior
|
||||
vramSetBankD(VRAM_D_SUB_SPRITE); // Banco D de la VRAM para Sprites (128kb)
|
||||
memset((void*)0x06600000, 0, 131072); // Borra el contenido del banco D
|
||||
NF_SPRVRAM[screen].next = (0x06600000); // Guarda la primera posicion de VRAM para Gfx
|
||||
vramSetBankI(VRAM_I_LCD); // Banco I de la VRAM para paletas extendidas (Sprites) (8kb de 16kb)
|
||||
memset((void*)0x068A0000, 0, 8192); // Borra el contenido del banco I
|
||||
if (mode == 128) {
|
||||
oamInit(&oamSub, SpriteMapping_1D_128, true); // Inicializa el OAM (Mapeado de 128 bytes, Paletas extendidas)
|
||||
} else {
|
||||
oamInit(&oamSub, SpriteMapping_1D_64, true); // Inicializa el OAM (Mapeado de 64 bytes, Paletas extendidas)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadSpriteGfx();
|
||||
void NF_LoadSpriteGfx(const char* file, u16 id, u16 width, u16 height) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_SPR256GFX)) {
|
||||
NF_Error(106, "Sprite GFX", NF_SLOTS_SPR256GFX);
|
||||
}
|
||||
|
||||
// Verifica si la Id esta libre
|
||||
if (!NF_SPR256GFX[id].available) {
|
||||
NF_Error(109, "Sprite GFX", id);
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_BUFFER_SPR256GFX[id]);
|
||||
NF_BUFFER_SPR256GFX[id] = NULL;
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
|
||||
// Carga el archivo .IMG
|
||||
sprintf(filename, "%s/%s.img", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
NF_SPR256GFX[id].size = ftell(file_id);
|
||||
rewind(file_id);
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_SPR256GFX[id] = (char*) calloc (NF_SPR256GFX[id].size, sizeof(char));
|
||||
if (NF_BUFFER_SPR256GFX[id] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_SPR256GFX[id].size);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BUFFER_SPR256GFX[id], 1, NF_SPR256GFX[id].size, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
|
||||
// Guarda las medidas del grafico
|
||||
NF_SPR256GFX[id].width = width; // Ancho del Gfx
|
||||
NF_SPR256GFX[id].height = height; // Altura del Gfx
|
||||
|
||||
// Y marca esta ID como usada
|
||||
NF_SPR256GFX[id].available = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadSpriteGfx();
|
||||
void NF_UnloadSpriteGfx(u16 id) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_SPR256GFX)) {
|
||||
NF_Error(106, "Sprite GFX", NF_SLOTS_SPR256GFX);
|
||||
}
|
||||
|
||||
// Verifica si la Id esta libre
|
||||
if (NF_SPR256GFX[id].available) {
|
||||
NF_Error(110, "Sprite GFX", id);
|
||||
}
|
||||
|
||||
// Vacia el buffer
|
||||
free(NF_BUFFER_SPR256GFX[id]);
|
||||
|
||||
// Y reinicia las variables
|
||||
NF_BUFFER_SPR256GFX[id] = NULL; // Inicializa puntero
|
||||
NF_SPR256GFX[id].size = 0; // Tamaño (en bytes) del grafico (GFX)
|
||||
NF_SPR256GFX[id].width = 0; // Ancho del Gfx
|
||||
NF_SPR256GFX[id].height = 0; // Altura del Gfx
|
||||
NF_SPR256GFX[id].available = true; // Disponibilidat del Slot
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadSpritePal();
|
||||
void NF_LoadSpritePal(const char* file, u8 id) {
|
||||
|
||||
// Variable temporal del tamaño de la paleta
|
||||
u32 pal_size = 0;
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_SPR256PAL)) {
|
||||
NF_Error(106, "Sprite PAL", NF_SLOTS_SPR256PAL);
|
||||
}
|
||||
|
||||
// Verifica si la Id esta libre
|
||||
if (!NF_SPR256PAL[id].available) {
|
||||
NF_Error(109, "Sprite PAL", id);
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_BUFFER_SPR256PAL[id]);
|
||||
NF_BUFFER_SPR256PAL[id] = NULL;
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
|
||||
// Carga el archivo .PAL
|
||||
sprintf(filename, "%s/%s.pal", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
pal_size = ftell(file_id);
|
||||
NF_SPR256PAL[id].size = pal_size;
|
||||
rewind(file_id);
|
||||
// Si el tamaño es inferior a 512 bytes, ajustalo
|
||||
if (NF_SPR256PAL[id].size < 512) NF_SPR256PAL[id].size = 512;
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_SPR256PAL[id] = (char*) calloc (NF_SPR256PAL[id].size, sizeof(char));
|
||||
if (NF_BUFFER_SPR256PAL[id] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_SPR256PAL[id].size);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BUFFER_SPR256PAL[id], 1, pal_size, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
|
||||
// Y marca esta ID como usada
|
||||
NF_SPR256PAL[id].available = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadSpritePal();
|
||||
void NF_UnloadSpritePal(u8 id) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_SPR256PAL)) {
|
||||
NF_Error(106, "Sprite PAL", NF_SLOTS_SPR256PAL);
|
||||
}
|
||||
|
||||
// Verifica si la Id esta libre
|
||||
if (NF_SPR256PAL[id].available) {
|
||||
NF_Error(110, "Sprite PAL", id);
|
||||
}
|
||||
|
||||
// Vacia el buffer
|
||||
free(NF_BUFFER_SPR256PAL[id]);
|
||||
|
||||
// Y reinicia las variables
|
||||
NF_BUFFER_SPR256PAL[id] = NULL; // Inicializa puntero
|
||||
NF_SPR256PAL[id].size = 0; // Tamaño (en bytes) de la paleta (PAL)
|
||||
NF_SPR256PAL[id].available = true; // Disponibilidat del Slot
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_VramSpriteGfx();
|
||||
void NF_VramSpriteGfx(u8 screen, u16 ram, u16 vram, bool keepframes) {
|
||||
|
||||
// Verifica el rango de Id's de RAM
|
||||
if ((ram < 0) || (ram >= NF_SLOTS_SPR256GFX)) {
|
||||
NF_Error(106, "Sprite GFX", (NF_SLOTS_SPR256GFX - 1));
|
||||
}
|
||||
|
||||
// Verifica si slot de RAM esta vacio
|
||||
if (NF_SPR256GFX[ram].available) {
|
||||
NF_Error(110, "Sprite GFX", ram);
|
||||
}
|
||||
|
||||
// Verifica el rango de Id's de VRAM
|
||||
if ((vram < 0) || (vram > 127)) {
|
||||
NF_Error(106, "VRAM GFX", 127);
|
||||
}
|
||||
|
||||
// Verifica si el slot de VRAM esta libre
|
||||
if (NF_SPR256VRAM[screen][vram].inuse) {
|
||||
NF_Error(109, "VRAM", vram);
|
||||
}
|
||||
|
||||
// Variables de uso general
|
||||
s16 n = 0; // General
|
||||
s16 id = 255; // Id del posible bloque libre
|
||||
s16 last_reuse = 0; // Nº del ultimo bloque reusable
|
||||
u32 gfxsize = 0; // Tamaño de los datos que se copiaran
|
||||
u32 size = 0; // Diferencia de tamaños entre bloque libre y datos
|
||||
u8 width = 0; // Calculo de las medidas
|
||||
u8 height = 0;
|
||||
bool organize = true; // Se debe de reorganizar el array de bloques libres ?
|
||||
|
||||
// Auto calcula el tamaño de 1 frame
|
||||
width = (NF_SPR256GFX[ram].width >> 3); // (width / 8)
|
||||
height = (NF_SPR256GFX[ram].height >> 3); // (height / 8)
|
||||
NF_SPR256VRAM[screen][vram].framesize = ((width * height) << 6); // ((width * height) * 64)
|
||||
// Auto calcula el ultimo frame de la animacion
|
||||
NF_SPR256VRAM[screen][vram].lastframe = ((int)(NF_SPR256GFX[ram].size / NF_SPR256VRAM[screen][vram].framesize)) - 1;
|
||||
NF_SPR256VRAM[screen][vram].inuse = true; // Slot ocupado
|
||||
|
||||
// Calcula el tamaño del grafico a copiar segun si debes o no copiar todos los frames
|
||||
if (keepframes) { // Si debes de mantener los frames en RAM, solo copia el primero
|
||||
gfxsize = NF_SPR256VRAM[screen][vram].framesize;
|
||||
} else { // Si no, copialos todos
|
||||
gfxsize = NF_SPR256GFX[ram].size;
|
||||
}
|
||||
|
||||
// Actualiza la VRAM disponible
|
||||
NF_SPRVRAM[screen].free -= gfxsize;
|
||||
|
||||
// Si no hay suficiente VRAM, error
|
||||
if (NF_SPRVRAM[screen].free < 0) {
|
||||
NF_Error(113, "Sprites", gfxsize);
|
||||
}
|
||||
|
||||
// Si hay que aprovechar algun bloque borrado... (tamaño identico, preferente)
|
||||
if (NF_SPRVRAM[screen].deleted > 0) {
|
||||
// Busca un bloque vacio del tamaño identico
|
||||
for (n = 0; n < NF_SPRVRAM[screen].deleted; n ++) {
|
||||
if (NF_SPRVRAM[screen].size[n] == gfxsize) { // Si el bloque tiene el tamaño suficiente
|
||||
id = n; // Guarda la Id
|
||||
n = NF_SPRVRAM[screen].deleted; // y sal
|
||||
}
|
||||
}
|
||||
// Si no habia ningun bloque de tamaño identico, busca el mas parecido (produce fragmentacion)
|
||||
if (id == 255) {
|
||||
// Busca un bloque vacio del tamaño suficiente
|
||||
for (n = 0; n < NF_SPRVRAM[screen].deleted; n ++) {
|
||||
if (NF_SPRVRAM[screen].size[n] > gfxsize) { // Si el bloque tiene el tamaño suficiente
|
||||
id = n; // Guarda la Id
|
||||
n = NF_SPRVRAM[screen].deleted; // y sal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Si hay algun bloque borrado libre del tamaño suficiente...
|
||||
if (id != 255) {
|
||||
|
||||
// Transfiere el grafico a la VRAM
|
||||
NF_DmaMemCopy((void*)NF_SPRVRAM[screen].pos[id], NF_BUFFER_SPR256GFX[ram], gfxsize);
|
||||
// Guarda el puntero donde lo has almacenado
|
||||
NF_SPR256VRAM[screen][vram].address = NF_SPRVRAM[screen].pos[id];
|
||||
|
||||
// Si no has usado todo el tamaño, deja constancia
|
||||
if (gfxsize < NF_SPRVRAM[screen].size[id]) {
|
||||
|
||||
// Calcula el tamaño del nuevo bloque libre
|
||||
size = (NF_SPRVRAM[screen].size[id] - gfxsize);
|
||||
// Actualiza los datos
|
||||
NF_SPRVRAM[screen].pos[id] += gfxsize; // Nueva direccion
|
||||
NF_SPRVRAM[screen].size[id] = size; // Nuevo tamaño
|
||||
NF_SPRVRAM[screen].fragmented -= gfxsize; // Actualiza el contador de VRAM fragmentada
|
||||
organize = false; // No se debe de reorganizar el array de bloques
|
||||
|
||||
} else { // Si has usado todo el tamaño, deja constancia
|
||||
|
||||
NF_SPRVRAM[screen].fragmented -= NF_SPRVRAM[screen].size[id]; // Actualiza el contador de VRAM fragmentada
|
||||
|
||||
}
|
||||
|
||||
// Se tiene que reorganizar el array de bloques libres ?
|
||||
if (organize) {
|
||||
last_reuse = (NF_SPRVRAM[screen].deleted - 1);
|
||||
if (
|
||||
(last_reuse > 0) // Si hay mas de un bloque borrado
|
||||
&&
|
||||
(id != last_reuse) // Y no es la ultima posicion
|
||||
) {
|
||||
// Coloca los valores de la ultima posicion en esta
|
||||
NF_SPRVRAM[screen].pos[id] = NF_SPRVRAM[screen].pos[last_reuse]; // Nueva direccion
|
||||
NF_SPRVRAM[screen].size[id] = NF_SPRVRAM[screen].size[last_reuse]; // Nuevo tamaño
|
||||
}
|
||||
NF_SPRVRAM[screen].deleted --; // Actualiza el contador de bloques libres, borrando el ultimo registro
|
||||
}
|
||||
|
||||
} else { // Si no habia ningun bloque borrado o con el tamaño suficiente, colacalo al final de la VRAM ocupada
|
||||
|
||||
// Actualiza la VRAM contigua disponible (mayor bloque libre al final)
|
||||
NF_SPRVRAM[screen].inarow -= gfxsize;
|
||||
|
||||
// Si no hay suficiente VRAM (contigua), error
|
||||
if (NF_SPRVRAM[screen].inarow < 0) {
|
||||
NF_Error(113, "Sprites", gfxsize);
|
||||
}
|
||||
|
||||
// Transfiere el grafico a la VRAM
|
||||
NF_DmaMemCopy((void*)NF_SPRVRAM[screen].next, NF_BUFFER_SPR256GFX[ram], gfxsize);
|
||||
// Guarda el puntero donde lo has almacenado
|
||||
NF_SPR256VRAM[screen][vram].address = NF_SPRVRAM[screen].next;
|
||||
// Guarda la direccion actual como la ultima usada
|
||||
NF_SPRVRAM[screen].last = NF_SPRVRAM[screen].next;
|
||||
// Calcula la siguiente posicion libre
|
||||
NF_SPRVRAM[screen].next += gfxsize;
|
||||
|
||||
}
|
||||
|
||||
// Guarda los datos del Gfx que se copiara a la VRAM.
|
||||
NF_SPR256VRAM[screen][vram].size = gfxsize; // Tamaño en bytes de los datos copiados
|
||||
NF_SPR256VRAM[screen][vram].width = NF_SPR256GFX[ram].width; // Alto (px)
|
||||
NF_SPR256VRAM[screen][vram].height = NF_SPR256GFX[ram].height; // Ancho (px)
|
||||
NF_SPR256VRAM[screen][vram].ramid = ram; // Slot RAM de origen
|
||||
NF_SPR256VRAM[screen][vram].keepframes = keepframes; // Debes guardar los frames en RAM o copiarlos a la VRAM?
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_FreeSpriteGfx();
|
||||
void NF_FreeSpriteGfx(u8 screen, u16 id) {
|
||||
|
||||
// Verifica si hay un grafico cargado en esa Id.
|
||||
if (!NF_SPR256VRAM[screen][id].inuse) {
|
||||
NF_Error(110, "Sprite Gfx", id);
|
||||
}
|
||||
|
||||
// Borra el Gfx de la VRAM (pon a 0 todos los Bytes)
|
||||
memset((void*)NF_SPR256VRAM[screen][id].address, 0, NF_SPR256VRAM[screen][id].size);
|
||||
|
||||
// Actualiza la cantidad de VRAM disponible
|
||||
NF_SPRVRAM[screen].free += NF_SPR256VRAM[screen][id].size;
|
||||
|
||||
// Guarda la posicion y tamaño del bloque borrado para su reutilizacion
|
||||
NF_SPRVRAM[screen].pos[NF_SPRVRAM[screen].deleted] = NF_SPR256VRAM[screen][id].address;
|
||||
NF_SPRVRAM[screen].size[NF_SPRVRAM[screen].deleted] = NF_SPR256VRAM[screen][id].size;
|
||||
|
||||
// Incrementa en contador de bloques borrados
|
||||
NF_SPRVRAM[screen].deleted ++;
|
||||
|
||||
// Incrementa el contador de memoria fragmentada
|
||||
NF_SPRVRAM[screen].fragmented += NF_SPR256VRAM[screen][id].size;
|
||||
|
||||
// Reinicia los datos de esta Id. de gfx
|
||||
NF_SPR256VRAM[screen][id].size = 0; // Tamaño en bytes
|
||||
NF_SPR256VRAM[screen][id].width = 0; // Alto (px)
|
||||
NF_SPR256VRAM[screen][id].height = 0; // Ancho (px)
|
||||
NF_SPR256VRAM[screen][id].address = 0; // Puntero en VRAM
|
||||
NF_SPR256VRAM[screen][id].framesize = 0; // Tamaño del frame (en bytes)
|
||||
NF_SPR256VRAM[screen][id].lastframe = 0; // Ultimo frame
|
||||
NF_SPR256VRAM[screen][id].inuse = false;
|
||||
|
||||
// Debes desfragmentar la VRAM
|
||||
if (NF_SPRVRAM[screen].fragmented >= (NF_SPRVRAM[screen].inarow >> 1)) {
|
||||
NF_VramSpriteGfxDefrag(screen);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_VramSpriteGfxDefrag();
|
||||
void NF_VramSpriteGfxDefrag(u8 screen) {
|
||||
|
||||
// Calcula la VRAM en uso y crea un buffer para guardarla
|
||||
u32 used_vram = ((NF_SPRVRAM[screen].max - NF_SPRVRAM[screen].free) + 1);
|
||||
char* buffer;
|
||||
buffer = (char*) calloc (used_vram, sizeof(char));
|
||||
if (buffer == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, used_vram);
|
||||
}
|
||||
|
||||
char* address[128]; // Guarda la direccion en RAM
|
||||
u32 size[128]; // Guarda el tamaño
|
||||
u32 ram = 0; // Puntero inicial de RAM
|
||||
u8 n = 0; // Variable General
|
||||
u32 frame_address = 0; // Guarda la direccion de VRAM del frame
|
||||
|
||||
|
||||
// Copia los datos de la VRAM a la RAM
|
||||
for (n = 0; n < 128; n ++) {
|
||||
// Si esta en uso
|
||||
if (NF_SPR256VRAM[screen][n].inuse) {
|
||||
// Copia el Gfx a la RAM
|
||||
address[n] = (buffer + ram); // Calcula el puntero
|
||||
size[n] = NF_SPR256VRAM[screen][n].size; // Almacena el tamaño
|
||||
NF_DmaMemCopy(address[n], (void*)NF_SPR256VRAM[screen][n].address, size[n]); // Copialo a la VRAM
|
||||
ram += size[n]; // Siguiente posicion en RAM (relativa)
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializa la estructura de datos de la VRAM de Sprites
|
||||
NF_SPRVRAM[screen].free = NF_SPRVRAM[screen].max; // Memoria VRAM libre (128kb)
|
||||
NF_SPRVRAM[screen].last = 0; // Ultima posicion usada
|
||||
NF_SPRVRAM[screen].deleted = 0; // Ningun Gfx borrado
|
||||
NF_SPRVRAM[screen].fragmented = 0; // Memoria VRAM fragmentada
|
||||
NF_SPRVRAM[screen].inarow = NF_SPRVRAM[screen].max; // Memoria VRAM contigua
|
||||
for (n = 0; n < 128; n ++) {
|
||||
NF_SPRVRAM[screen].pos[n] = 0; // Posicion en VRAM para reusar despues de un borrado
|
||||
NF_SPRVRAM[screen].size[n] = 0; // Tamaño del bloque libre para reusar
|
||||
}
|
||||
// Aplica la direccion de inicio de la VRAM
|
||||
if (screen == 0) {
|
||||
NF_SPRVRAM[screen].next = (0x06400000);
|
||||
} else {
|
||||
NF_SPRVRAM[screen].next = (0x06600000);
|
||||
}
|
||||
|
||||
// Ahora, copia de nuevo los datos a la VRAM, pero alineados
|
||||
for (n = 0; n < 128; n ++) {
|
||||
// Si esta en uso
|
||||
if (NF_SPR256VRAM[screen][n].inuse) {
|
||||
NF_DmaMemCopy((void*)NF_SPRVRAM[screen].next, address[n], size[n]); // Vuelve a colocar la el Gfx en VRAM
|
||||
NF_SPR256VRAM[screen][n].address = NF_SPRVRAM[screen].next; // Guarda la nueva posicion en VRAM
|
||||
NF_SPRVRAM[screen].free -= size[n]; // Ram libre
|
||||
NF_SPRVRAM[screen].inarow -= size[n]; // Ram libre en bloque
|
||||
NF_SPRVRAM[screen].last = NF_SPRVRAM[screen].next; // Guarda la posicion como ultima usada
|
||||
NF_SPRVRAM[screen].next += size[n]; // Y calcula la siguiente posicion a escribir
|
||||
}
|
||||
}
|
||||
|
||||
// Reasigna a los sprites las nuevas posiciones de los graficos que usan
|
||||
for (n = 0; n < 128; n ++) {
|
||||
if (NF_SPRITEOAM[screen][n].created) {
|
||||
if (NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][n].gfxid].keepframes) {
|
||||
// Si la opcion de animacion KEEP FRAMES esta activada,
|
||||
// simplemente asigna la nueva direccion en VRAM del grafico.
|
||||
NF_SPRITEOAM[screen][n].gfx = (u32*)NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][n].gfxid].address;
|
||||
} else {
|
||||
// Si la opcion KEEP FRAMES esta desactivada,
|
||||
// calcula el desplazamiento dentro de la nueva direccion asignada.
|
||||
frame_address = (NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][n].gfxid].address + (NF_SPRITEOAM[screen][n].framesize * NF_SPRITEOAM[screen][n].frame));
|
||||
NF_SPRITEOAM[screen][n].gfx = (u32*)frame_address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Vacia el buffer
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_VramSpritePal();
|
||||
void NF_VramSpritePal(u8 screen, u8 id, u8 slot) {
|
||||
|
||||
// Verifica el rango de Id's
|
||||
if ((id < 0) || (id >= NF_SLOTS_SPR256PAL)) {
|
||||
NF_Error(106, "Sprite PAL", NF_SLOTS_SPR256PAL);
|
||||
}
|
||||
|
||||
// Verifica si la Id esta libre
|
||||
if (NF_SPR256PAL[id].available) {
|
||||
NF_Error(110, "Sprite PAL", id);
|
||||
}
|
||||
|
||||
// Verifica si te has salido de rango (Paleta)
|
||||
if ((slot < 0) || (slot > 15)) {
|
||||
NF_Error(106, "Sprite Palette Slot", 15);
|
||||
}
|
||||
|
||||
// Copia la paleta a la VRAM, segun la pantalla y el Slot
|
||||
u32 address = 0;
|
||||
if (screen == 0) {
|
||||
address = (0x06890000) + (slot << 9); // Calcula donde guardaras la paleta
|
||||
vramSetBankF(VRAM_F_LCD); // Bloquea el banco F para escribir las paletas
|
||||
NF_DmaMemCopy((void*)address, NF_BUFFER_SPR256PAL[id], NF_SPR256PAL[id].size); // Copia la paleta al banco F
|
||||
vramSetBankF(VRAM_F_SPRITE_EXT_PALETTE); // Pon el banco F en modo paleta extendida
|
||||
} else {
|
||||
address = (0x068A0000) + (slot << 9); // Calcula donde guardaras la paleta
|
||||
vramSetBankI(VRAM_I_LCD); // Bloquea el banco I para escribir las paletas
|
||||
NF_DmaMemCopy((void*)address, NF_BUFFER_SPR256PAL[id], NF_SPR256PAL[id].size); // Copia la paleta al banco I
|
||||
vramSetBankI(VRAM_I_SUB_SPRITE_EXT_PALETTE); // Pon el banco I en modo paleta extendida
|
||||
}
|
||||
|
||||
NF_SPRPALSLOT[screen][slot].inuse = true; // Marca el SLOT de paleta como en uso
|
||||
NF_SPRPALSLOT[screen][slot].ramslot = id; // Guarda el slot de RAM donde esta la paleta original
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_CreateSprite();
|
||||
void NF_CreateSprite(u8 screen, u8 id, u16 gfx, u8 pal, s16 x, s16 y) {
|
||||
|
||||
// Verifica el rango de Id's de Sprites
|
||||
if ((id < 0) || (id > 127)) {
|
||||
NF_Error(106, "Sprite", 127);
|
||||
}
|
||||
|
||||
// Verifica el rango de Id's de Gfx
|
||||
if ((gfx < 0) || (gfx > 127)) {
|
||||
NF_Error(106, "Sprite GFX", 127);
|
||||
}
|
||||
|
||||
// Verifica si esta el Gfx en VRAM
|
||||
if (!NF_SPR256VRAM[screen][gfx].inuse) {
|
||||
NF_Error(111, "Sprite GFX", gfx);
|
||||
}
|
||||
|
||||
// Verifica el rango de slots de paletas
|
||||
if ((pal < 0) || (pal > 15)) {
|
||||
NF_Error(106, "Sprite Palette Slot", 15);
|
||||
}
|
||||
|
||||
// Verifica si esta la paleta en VRAM
|
||||
if (!NF_SPRPALSLOT[screen][pal].inuse) {
|
||||
NF_Error(111, "Sprite PAL", pal);
|
||||
}
|
||||
|
||||
// // Informa al array de OAM del Id
|
||||
NF_SPRITEOAM[screen][id].index = id;
|
||||
|
||||
// Informa al array de OAM del Gfx a usar
|
||||
NF_SPRITEOAM[screen][id].gfx = (u32*)NF_SPR256VRAM[screen][gfx].address;
|
||||
|
||||
// Informa al array de OAM de la Paleta a usar
|
||||
NF_SPRITEOAM[screen][id].pal = pal;
|
||||
|
||||
// Informa al array de OAM de la coordenada X
|
||||
NF_SPRITEOAM[screen][id].x = x;
|
||||
|
||||
// Informa al array de OAM de la coordenada X
|
||||
NF_SPRITEOAM[screen][id].y = y;
|
||||
|
||||
// Informa al array de OAM del numero de colores
|
||||
NF_SPRITEOAM[screen][id].color = SpriteColorFormat_256Color;
|
||||
|
||||
// Informa al array de OAM de que debe mostrar el sprite
|
||||
NF_SPRITEOAM[screen][id].hide = false;
|
||||
|
||||
// Informa al array de OAM del Id de Gfx usado
|
||||
NF_SPRITEOAM[screen][id].gfxid = gfx;
|
||||
|
||||
// Informa al array de OAM de que el sprite se ha creado
|
||||
NF_SPRITEOAM[screen][id].created = true;
|
||||
|
||||
// Informa al array de OAM del tamaño
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 8) && (NF_SPR256VRAM[screen][gfx].height == 8)) { // 8x8
|
||||
if (NF_SPRVRAM[screen].max != 131072) { // En modo 1D_128, este tamaño es ilegal
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_8x8;
|
||||
} else {
|
||||
NF_Error(120, NULL, id);
|
||||
}
|
||||
}
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 16) && (NF_SPR256VRAM[screen][gfx].height == 16)) { // 16x16
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_16x16;
|
||||
}
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 32) && (NF_SPR256VRAM[screen][gfx].height == 32)) { // 32x32
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_32x32;
|
||||
}
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 64) && (NF_SPR256VRAM[screen][gfx].height == 64)) { // 64x64
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_64x64;
|
||||
}
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 16) && (NF_SPR256VRAM[screen][gfx].height == 8)) { // 16x8
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_16x8;
|
||||
}
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 32) && (NF_SPR256VRAM[screen][gfx].height == 8)) { // 32x8
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_32x8;
|
||||
}
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 32) && (NF_SPR256VRAM[screen][gfx].height == 16)) { // 32x16
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_32x16;
|
||||
}
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 64) && (NF_SPR256VRAM[screen][gfx].height == 32)) { // 64x32
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_64x32;
|
||||
}
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 8) && (NF_SPR256VRAM[screen][gfx].height == 16)) { // 8x16
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_8x16;
|
||||
}
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 8) && (NF_SPR256VRAM[screen][gfx].height == 32)) { // 8x32
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_8x32;
|
||||
}
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 16) && (NF_SPR256VRAM[screen][gfx].height == 32)) { // 16x32
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_16x32;
|
||||
}
|
||||
if ((NF_SPR256VRAM[screen][gfx].width == 32) && (NF_SPR256VRAM[screen][gfx].height == 64)) { // 32x64
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_32x64;
|
||||
}
|
||||
|
||||
// Informa al array de OAM del ultimo frame del Sprite
|
||||
NF_SPRITEOAM[screen][id].lastframe = NF_SPR256VRAM[screen][gfx].lastframe;
|
||||
|
||||
// Informa al array de OAM del tamaño del frame del Sprite (en bytes)
|
||||
NF_SPRITEOAM[screen][id].framesize = NF_SPR256VRAM[screen][gfx].framesize;
|
||||
|
||||
// Por defecto, el primer frame (0)
|
||||
NF_SPRITEOAM[screen][id].frame = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DeleteSprite();
|
||||
void NF_DeleteSprite(u8 screen, u8 id) {
|
||||
|
||||
// Verifica el rango de Id's de Sprites
|
||||
if ((id < 0) || (id > 127)) {
|
||||
NF_Error(106, "Sprite", 127);
|
||||
}
|
||||
|
||||
// Verifica si el Sprite esta creado
|
||||
if (!NF_SPRITEOAM[screen][id].created) {
|
||||
char text[4];
|
||||
sprintf(text, "%d", screen);
|
||||
NF_Error(112, text, id);
|
||||
}
|
||||
|
||||
// Reinicia todas las variables de ese Sprite
|
||||
NF_SPRITEOAM[screen][id].index = id; // Numero de Sprite
|
||||
NF_SPRITEOAM[screen][id].x = 0; // Coordenada X del Sprite (0 por defecto)
|
||||
NF_SPRITEOAM[screen][id].y = 0; // Coordenada Y del Sprite (0 por defecto)
|
||||
NF_SPRITEOAM[screen][id].layer = 0; // Prioridad en las capas (0 por defecto)
|
||||
NF_SPRITEOAM[screen][id].pal = 0; // Paleta que usaras (0 por defecto)
|
||||
NF_SPRITEOAM[screen][id].size = SpriteSize_8x8; // Tamaño del Sprite (macro) (8x8 por defecto)
|
||||
NF_SPRITEOAM[screen][id].color = SpriteColorFormat_256Color; // Modo de color (macro) (256 colores)
|
||||
NF_SPRITEOAM[screen][id].gfx = NULL; // Puntero al grafico usado
|
||||
NF_SPRITEOAM[screen][id].rot = -1; // Id de rotacion (-1 ninguno) (0 - 31 Id de rotacion)
|
||||
NF_SPRITEOAM[screen][id].doublesize = false; // Usar el "double size" al rotar ? ("NO" por defecto)
|
||||
NF_SPRITEOAM[screen][id].hide = true; // Ocultar el Sprite ("SI" por defecto)
|
||||
NF_SPRITEOAM[screen][id].hflip = false; // Volteado Horizontal ("NO" por defecto)
|
||||
NF_SPRITEOAM[screen][id].vflip = false; // Volteado Vertical ("NO" por defecto)
|
||||
NF_SPRITEOAM[screen][id].mosaic = false; // Mosaico ("NO" por defecto)
|
||||
NF_SPRITEOAM[screen][id].gfxid = 0; // Numero de Gfx usado
|
||||
NF_SPRITEOAM[screen][id].frame = 0; // Frame actual
|
||||
NF_SPRITEOAM[screen][id].framesize = 0; // Tamaño del frame (en bytes)
|
||||
NF_SPRITEOAM[screen][id].lastframe = 0; // Ultimo frame
|
||||
NF_SPRITEOAM[screen][id].created = false; // Esta creado este sprite ?
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteOamSet();
|
||||
void NF_SpriteOamSet(u8 screen) {
|
||||
|
||||
u8 n = 0; // Variable de uso general
|
||||
|
||||
if (screen == 0) {
|
||||
|
||||
for (n = 0; n < 128; n ++) {
|
||||
oamSet(&oamMain, // OAM pantalla superior (Main, 0)
|
||||
NF_SPRITEOAM[screen][n].index, // Numero de Sprite
|
||||
NF_SPRITEOAM[screen][n].x, // Coordenada X del Sprite
|
||||
NF_SPRITEOAM[screen][n].y, // Coordenada Y del Sprite
|
||||
NF_SPRITEOAM[screen][n].layer, // Prioridad en las capas
|
||||
NF_SPRITEOAM[screen][n].pal, // Paleta que usaras
|
||||
NF_SPRITEOAM[screen][n].size, // Tamaño del Sprite (macro)
|
||||
NF_SPRITEOAM[screen][n].color, // Modo de color (macro)
|
||||
NF_SPRITEOAM[screen][n].gfx, // Puntero al grafico usado
|
||||
NF_SPRITEOAM[screen][n].rot, // Valor de la rotacion
|
||||
NF_SPRITEOAM[screen][n].doublesize, // Usar el "double size" al rotar ?
|
||||
NF_SPRITEOAM[screen][n].hide, // Ocultar el Sprite
|
||||
NF_SPRITEOAM[screen][n].hflip, // Volteado Horizontal
|
||||
NF_SPRITEOAM[screen][n].vflip, // Volteado Vertical
|
||||
NF_SPRITEOAM[screen][n].mosaic); // Mosaico
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for (n = 0; n < 128; n ++) {
|
||||
oamSet(&oamSub, // OAM pantalla superior (Main, 0)
|
||||
NF_SPRITEOAM[screen][n].index, // Numero de Sprite
|
||||
NF_SPRITEOAM[screen][n].x, // Coordenada X del Sprite
|
||||
NF_SPRITEOAM[screen][n].y, // Coordenada Y del Sprite
|
||||
NF_SPRITEOAM[screen][n].layer, // Prioridad en las capas
|
||||
NF_SPRITEOAM[screen][n].pal, // Paleta que usaras
|
||||
NF_SPRITEOAM[screen][n].size, // Tamaño del Sprite (macro)
|
||||
NF_SPRITEOAM[screen][n].color, // Modo de color (macro)
|
||||
NF_SPRITEOAM[screen][n].gfx, // Puntero al grafico usado
|
||||
NF_SPRITEOAM[screen][n].rot, // Valor de la rotacion
|
||||
NF_SPRITEOAM[screen][n].doublesize, // Usar el "double size" al rotar ?
|
||||
NF_SPRITEOAM[screen][n].hide, // Ocultar el Sprite
|
||||
NF_SPRITEOAM[screen][n].hflip, // Volteado Horizontal
|
||||
NF_SPRITEOAM[screen][n].vflip, // Volteado Vertical
|
||||
NF_SPRITEOAM[screen][n].mosaic); // Mosaico
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteSetPalColor();
|
||||
void NF_SpriteSetPalColor(u8 screen, u8 pal, u8 number, u8 r, u8 g, u8 b) {
|
||||
|
||||
// Verifica si esta la paleta en VRAM
|
||||
if (!NF_SPRPALSLOT[screen][pal].inuse) {
|
||||
NF_Error(111, "Sprite PAL", pal);
|
||||
}
|
||||
|
||||
// Calcula el valor RGB
|
||||
u16 rgb = ((r)|((g) << 5)|((b) << 10));
|
||||
// Direccion en VRAM
|
||||
u32 address = 0;
|
||||
|
||||
// Modifica la paleta
|
||||
if (screen == 0) {
|
||||
address = (0x06890000) + (pal << 9) + (number << 1); // Calcula donde guardaras el color de la paleta
|
||||
vramSetBankF(VRAM_F_LCD); // Bloquea el banco F para escribir las paletas
|
||||
*((u16*)address) = rgb; // Cambia el color
|
||||
vramSetBankF(VRAM_F_SPRITE_EXT_PALETTE); // Pon el banco F en modo paleta extendida
|
||||
} else {
|
||||
address = (0x068A0000) + (pal << 9) + (number << 1); // Calcula donde guardaras el color de la paleta
|
||||
vramSetBankI(VRAM_I_LCD); // Bloquea el banco I para escribir las paletas
|
||||
*((u16*)address) = rgb; // Cambia el color
|
||||
vramSetBankI(VRAM_I_SUB_SPRITE_EXT_PALETTE); // Pon el banco I en modo paleta extendida
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteEditPalColor();
|
||||
void NF_SpriteEditPalColor(u8 screen, u8 pal, u8 number, u8 r, u8 g, u8 b) {
|
||||
|
||||
// Verifica si esta la paleta en VRAM
|
||||
if (!NF_SPRPALSLOT[screen][pal].inuse) {
|
||||
NF_Error(111, "Sprite PAL", pal);
|
||||
}
|
||||
|
||||
// Calcula el valor RGB
|
||||
u16 rgb = ((r)|((g) << 5)|((b) << 10));
|
||||
|
||||
// Calcula los valores para el HI-Byte y el LO-Byte
|
||||
u8 hibyte = ((rgb >> 8) & 0xff);
|
||||
u8 lobyte = (rgb & 0xff);
|
||||
|
||||
// Graba los bytes
|
||||
*(NF_BUFFER_SPR256PAL[NF_SPRPALSLOT[screen][pal].ramslot] + (number << 1)) = lobyte;
|
||||
*(NF_BUFFER_SPR256PAL[NF_SPRPALSLOT[screen][pal].ramslot] + ((number << 1) + 1)) = hibyte;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteUpdatePalette();
|
||||
void NF_SpriteUpdatePalette(u8 screen, u8 pal) {
|
||||
|
||||
// Verifica si esta la paleta en VRAM
|
||||
if (!NF_SPRPALSLOT[screen][pal].inuse) {
|
||||
NF_Error(111, "Sprite PAL", pal);
|
||||
}
|
||||
|
||||
// Direccion en VRAM
|
||||
u32 address = 0;
|
||||
|
||||
// Obten el slot donde esta la paleta en RAM
|
||||
u8 slot = NF_SPRPALSLOT[screen][pal].ramslot;
|
||||
|
||||
// Actualiza la paleta en VRAM
|
||||
if (screen == 0) {
|
||||
address = (0x06890000) + (pal << 9); // Calcula donde guardaras la paleta
|
||||
vramSetBankF(VRAM_F_LCD); // Bloquea el banco F para escribir las paletas
|
||||
NF_DmaMemCopy((void*)address, NF_BUFFER_SPR256PAL[slot], NF_SPR256PAL[slot].size); // Copia la paleta al banco F
|
||||
vramSetBankF(VRAM_F_SPRITE_EXT_PALETTE); // Pon el banco F en modo paleta extendida
|
||||
} else {
|
||||
address = (0x068A0000) + (pal << 9); // Calcula donde guardaras la paleta
|
||||
vramSetBankI(VRAM_I_LCD); // Bloquea el banco I para escribir las paletas
|
||||
NF_DmaMemCopy((void*)address, NF_BUFFER_SPR256PAL[slot], NF_SPR256PAL[slot].size); // Copia la paleta al banco I
|
||||
vramSetBankI(VRAM_I_SUB_SPRITE_EXT_PALETTE); // Pon el banco I en modo paleta extendida
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_SpriteGetPalColor();
|
||||
void NF_SpriteGetPalColor(u8 screen, u8 pal, u8 number, u8* r, u8* g, u8* b) {
|
||||
|
||||
// Verifica si esta la paleta en VRAM
|
||||
if (!NF_SPRPALSLOT[screen][pal].inuse) {
|
||||
NF_Error(111, "Sprite PAL", pal);
|
||||
}
|
||||
|
||||
// Obten los bytes
|
||||
u8 lobyte = *(NF_BUFFER_SPR256PAL[NF_SPRPALSLOT[screen][pal].ramslot] + (number << 1));
|
||||
u8 hibyte = *(NF_BUFFER_SPR256PAL[NF_SPRPALSLOT[screen][pal].ramslot] + ((number << 1) + 1));
|
||||
|
||||
// Calcula el RGB (compuesto)
|
||||
u16 rgb = ((hibyte << 8) | lobyte);
|
||||
|
||||
// Calcula los RGB
|
||||
*r = (rgb & 0x1F);
|
||||
*g = ((rgb >> 5) & 0x1F);
|
||||
*b = ((rgb >> 10) & 0x1F);
|
||||
|
||||
}
|
1101
examples/templates/using_nflib/nflib/source/nf_sprite3d.c
Normal file
1101
examples/templates/using_nflib/nflib/source/nf_sprite3d.c
Normal file
File diff suppressed because it is too large
Load Diff
502
examples/templates/using_nflib/nflib/source/nf_text.c
Normal file
502
examples/templates/using_nflib/nflib/source/nf_text.c
Normal file
@ -0,0 +1,502 @@
|
||||
|
||||
// NightFox LIB - Funciones de Textos
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
#include <filesystem.h>
|
||||
#include <fat.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_basic.h"
|
||||
#include "nf_2d.h"
|
||||
#include "nf_tiledbg.h"
|
||||
#include "nf_text.h"
|
||||
|
||||
|
||||
|
||||
|
||||
// Define los buffers para almacenar las capas de texto
|
||||
NF_TYPE_TEXT_INFO NF_TEXT[2][4];
|
||||
|
||||
|
||||
|
||||
// Funcion NF_InitTextSys();
|
||||
void NF_InitTextSys(u8 screen) {
|
||||
|
||||
u8 n = 0;
|
||||
|
||||
// Reinicia las variables
|
||||
for (n = 0; n < 4; n ++) {
|
||||
NF_TEXT[screen][n].width = 0; // Ancho del mapa de texto
|
||||
NF_TEXT[screen][n].height = 0; // Alto del mapa de texto
|
||||
NF_TEXT[screen][n].rotation = 0; // Rotacion a 0 (ninguna)
|
||||
NF_TEXT[screen][n].slot = 255; // Slot donde esta el tileset
|
||||
NF_TEXT[screen][n].pal = 0; // nº de paleta extendida (0 por defecto)
|
||||
NF_TEXT[screen][n].exist = false; // Marcalo como no existente
|
||||
NF_TEXT[screen][n].update = false; // No es necesario actualizarlo
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadTextFont();
|
||||
void NF_LoadTextFont(const char* file, const char* name, u16 width, u16 height, u8 rotation) {
|
||||
|
||||
// Busca un slot libre
|
||||
u16 n = 0;
|
||||
u8 slot = 255;
|
||||
for (n = 0; n < NF_SLOTS_TBG; n ++) { // Busca en todos los slots
|
||||
if (NF_TILEDBG[n].available) { // Si esta libre
|
||||
NF_TILEDBG[n].available = false; // Marcalo como en uso
|
||||
slot = n; // Guarda el slot a usar
|
||||
n = NF_SLOTS_TBG; // Deja de buscar
|
||||
}
|
||||
}
|
||||
// Si no hay ningun slot libre, error
|
||||
if (slot == 255) {
|
||||
NF_Error(103, "Tiled Bg", NF_SLOTS_TBG);
|
||||
}
|
||||
|
||||
// Verifica que el fondo sea multiplo de 256px (32 tiles)
|
||||
if (((width % 256) != 0) || ((height % 256) != 0)) {
|
||||
NF_Error(115, file, 0);
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_BUFFER_BGMAP[slot]); // Buffer para los mapas
|
||||
NF_BUFFER_BGMAP[slot] = NULL;
|
||||
free(NF_BUFFER_BGTILES[slot]); // Buffer para los tiles
|
||||
NF_BUFFER_BGTILES[slot] = NULL;
|
||||
free(NF_BUFFER_BGPAL[slot]); // Buffer para los paletas
|
||||
NF_BUFFER_BGPAL[slot] = NULL;
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
|
||||
// Carga el archivo .FNT
|
||||
sprintf(filename, "%s/%s.fnt", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
NF_TILEDBG[slot].tilesize = (NF_TEXT_FONT_CHARS << 6); // 100 caracteres x 64 bytes
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGTILES[slot] = (char*) calloc (NF_TILEDBG[slot].tilesize, sizeof(char));
|
||||
if (NF_BUFFER_BGTILES[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].tilesize);
|
||||
}
|
||||
fread(NF_BUFFER_BGTILES[slot], 1, NF_TILEDBG[slot].tilesize, file_id); // Lee el resto de caracteres de la fuente
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
|
||||
// Rota los Gfx de los tiles si es necesario
|
||||
if (rotation > 0) {
|
||||
for (n = 0; n < NF_TEXT_FONT_CHARS; n ++) {
|
||||
NF_RotateTileGfx(slot, n, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
// Crea un archivo .MAP vacio en RAM
|
||||
// ((ancho / 8) * (alto / 8)) * 2
|
||||
NF_TILEDBG[slot].mapsize = (((width >> 3) * (height >> 3)) << 1);
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGMAP[slot] = (char*) calloc (NF_TILEDBG[slot].mapsize, sizeof(char));
|
||||
if (NF_BUFFER_BGMAP[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].mapsize);
|
||||
}
|
||||
// Y ponlo a 0
|
||||
memset(NF_BUFFER_BGMAP[slot], 0, NF_TILEDBG[slot].mapsize);
|
||||
|
||||
// Carga el archivo .PAL
|
||||
sprintf(filename, "%s/%s.pal", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
NF_TILEDBG[slot].palsize = ftell(file_id);
|
||||
rewind(file_id);
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGPAL[slot] = (char*) calloc (NF_TILEDBG[slot].palsize, sizeof(char));
|
||||
if (NF_BUFFER_BGPAL[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].palsize);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BUFFER_BGPAL[slot], 1, NF_TILEDBG[slot].palsize, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
|
||||
// Guarda el nombre del Fondo
|
||||
sprintf(NF_TILEDBG[slot].name, "%s", name);
|
||||
|
||||
// Y las medidas
|
||||
NF_TILEDBG[slot].width = width;
|
||||
NF_TILEDBG[slot].height = height;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UnloadTestFont();
|
||||
void NF_UnloadTextFont(const char* name) {
|
||||
NF_UnloadTiledBg(name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_CreateTextLayer();
|
||||
void NF_CreateTextLayer(u8 screen, u8 layer, u8 rotation, const char* name) {
|
||||
|
||||
u8 n = 0; // Bucle
|
||||
u8 slot = 255; // Slot seleccionado
|
||||
char bg[32]; // Nombre
|
||||
|
||||
// Crea un fondo para usarlo como capa de texto
|
||||
NF_CreateTiledBg(screen, layer, name);
|
||||
|
||||
// Busca el numero de slot donde esta cargada la fuente
|
||||
sprintf(bg, "%s", name); // Obten el nombre del fondo a buscar
|
||||
for (n = 0; n < NF_SLOTS_TBG; n ++) { // Busca en todos los slots
|
||||
if (strcmp(bg, NF_TILEDBG[n].name) == 0) { // Si lo encuentras
|
||||
slot = n; // Guarda el slot a usar
|
||||
n = NF_SLOTS_TBG; // Deja de buscar
|
||||
}
|
||||
}
|
||||
|
||||
// Guarda si el texto debe ser rotado
|
||||
NF_TEXT[screen][layer].rotation = rotation;
|
||||
|
||||
// Guarda las medidas del fondo en tiles (ultimo numero de tile)
|
||||
NF_TEXT[screen][layer].width = ((NF_TILEDBG[slot].width >> 3) - 1);
|
||||
NF_TEXT[screen][layer].height = ((NF_TILEDBG[slot].height >> 3) - 1);
|
||||
|
||||
// Almacena el slot donde esta cargada la fuente
|
||||
NF_TEXT[screen][layer].slot = slot;
|
||||
|
||||
// Y marcalo como creado
|
||||
NF_TEXT[screen][layer].exist = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DeleteTextLayer();
|
||||
void NF_DeleteTextLayer(u8 screen, u8 layer) {
|
||||
|
||||
// Verifica si la capa de texto de destino existe
|
||||
if (!NF_TEXT[screen][layer].exist) {
|
||||
NF_Error(114, NULL, screen);
|
||||
}
|
||||
|
||||
// Borra el fondo usado como capa de texto
|
||||
NF_DeleteTiledBg(screen, layer);
|
||||
|
||||
// Guarda si el texto debe ser rotado
|
||||
NF_TEXT[screen][layer].rotation = 0;
|
||||
|
||||
// Guarda las medidas del fondo en tiles
|
||||
NF_TEXT[screen][layer].width = 0;
|
||||
NF_TEXT[screen][layer].height = 0;
|
||||
|
||||
// Y marcalo como creado
|
||||
NF_TEXT[screen][layer].exist = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_WriteText();
|
||||
void NF_WriteText(u8 screen, u8 layer, u16 x, u16 y, const char* text) {
|
||||
|
||||
// Verifica si la capa de texto de destino existe
|
||||
if (!NF_TEXT[screen][layer].exist) {
|
||||
NF_Error(114, NULL, screen);
|
||||
}
|
||||
|
||||
u16 n = 0; // Variable de uso general
|
||||
|
||||
s16 value = 0; // Valor
|
||||
|
||||
u16 tsize = 0; // Almacena el numero de letras
|
||||
tsize = strlen(text); // Calcula el numero de letras del texto
|
||||
|
||||
u8* string; // Buffer temporal
|
||||
string = NULL;
|
||||
string = (u8*) calloc (tsize, sizeof(u8));
|
||||
|
||||
// Almacena en el buffer temporal el valor de los caracteres
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
value = ((int)(text[n])) - 32; // Resta 32 al valor entrado
|
||||
if (value < 0) value = 0;
|
||||
string[n] = value;
|
||||
// Si es un caracter especial...
|
||||
if (string[n] > 95) {
|
||||
// Resetea el caracter...
|
||||
string[n] = 0;
|
||||
// Verifica caracteres especiales
|
||||
switch (((int)(text[n]))) {
|
||||
// Salto de linea
|
||||
case 10: // \n
|
||||
string[n] = 200;
|
||||
break;
|
||||
// Caracteres especiales
|
||||
case 199: // Ç
|
||||
string[n] = 96;
|
||||
break;
|
||||
case 231: // ç
|
||||
string[n] = 97;
|
||||
break;
|
||||
case 209: // Ñ
|
||||
string[n] = 98;
|
||||
break;
|
||||
case 241: // ñ
|
||||
string[n] = 99;
|
||||
break;
|
||||
// Acentos Mayusculas
|
||||
case 193: // Á
|
||||
string[n] = 100;
|
||||
break;
|
||||
case 201: // É
|
||||
string[n] = 101;
|
||||
break;
|
||||
case 205: // Í
|
||||
string[n] = 102;
|
||||
break;
|
||||
case 211: // Ó
|
||||
string[n] = 103;
|
||||
break;
|
||||
case 218: // Ú
|
||||
string[n] = 104;
|
||||
break;
|
||||
// Acentos Minusculas
|
||||
case 225: // á
|
||||
string[n] = 105;
|
||||
break;
|
||||
case 233: // é
|
||||
string[n] = 106;
|
||||
break;
|
||||
case 237: // í
|
||||
string[n] = 107;
|
||||
break;
|
||||
case 243: // ó
|
||||
string[n] = 108;
|
||||
break;
|
||||
case 250: // ú
|
||||
string[n] = 109;
|
||||
break;
|
||||
// Dieresis
|
||||
case 239: // ï
|
||||
string[n] = 110;
|
||||
break;
|
||||
case 252: // ü
|
||||
string[n] = 111;
|
||||
break;
|
||||
// Admiracion e interrogante (Español)
|
||||
case 161: // ¡
|
||||
string[n] = 112;
|
||||
break;
|
||||
case 191: // ¿
|
||||
string[n] = 113;
|
||||
break;
|
||||
// Caracter invalido
|
||||
default:
|
||||
string[n] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Variable para calcular la posicion del texto
|
||||
s16 tx = 0; // X
|
||||
s16 ty = 0; // Y
|
||||
|
||||
// Escribe los datos en el buffer de texto, segun la rotacion
|
||||
switch (NF_TEXT[screen][layer].rotation) {
|
||||
|
||||
case 0: // Sin rotacion
|
||||
// Traspasa las coordenadas virtuales a las reales
|
||||
tx = x;
|
||||
ty = y;
|
||||
// Copia el texto al buffer letra a letra
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
// Si es un caracter valido
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR) {
|
||||
// Escribe la letra correspondiente
|
||||
NF_SetTileOfMap(screen,layer, tx, ty, ((NF_TEXT[screen][layer].pal << 12) + string[n]));
|
||||
// Siguiente letra
|
||||
tx ++;
|
||||
}
|
||||
if ((tx > NF_TEXT[screen][layer].width) || (string[n] == 200)) { // Si llegas al final de linea,
|
||||
tx = 0; // salto de linea
|
||||
ty ++;
|
||||
if (ty > NF_TEXT[screen][layer].height) { // Si estas en la ultima linea,
|
||||
ty = 0; // vuelve a la primera
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 1: // Rotacion 90º a la derecha
|
||||
// Traspasa las coordenadas virtuales a las reales
|
||||
tx = (NF_TEXT[screen][layer].width - y);
|
||||
ty = x;
|
||||
// Copia el texto al buffer letra a letra
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
// Si es un caracter valido
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR) {
|
||||
// Escribe la letra correspondiente
|
||||
NF_SetTileOfMap(screen,layer, tx, ty, ((NF_TEXT[screen][layer].pal << 12) + string[n]));
|
||||
// Siguiente letra
|
||||
ty ++;
|
||||
}
|
||||
if ((ty > NF_TEXT[screen][layer].height) || (string[n] == 200)) { // Si llegas al final de linea,
|
||||
ty = 0; // salto de linea
|
||||
tx --;
|
||||
if (tx < 0) { // Si estas en la ultima linea,
|
||||
tx = NF_TEXT[screen][layer].width; // vuelve a la primera
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 2: // Rotacion 90º a la izquierda
|
||||
// Traspasa las coordenadas virtuales a las reales
|
||||
tx = y;
|
||||
ty = (NF_TEXT[screen][layer].height - x);
|
||||
// Copia el texto al buffer letra a letra
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
// Si es un caracter valido
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR) {
|
||||
// Escribe la letra correspondiente
|
||||
NF_SetTileOfMap(screen,layer, tx, ty, ((NF_TEXT[screen][layer].pal << 12) + string[n]));
|
||||
// Siguiente letra
|
||||
ty --;
|
||||
}
|
||||
if ((ty < 0) || (string[n] == 200)) { // Si llegas al final de linea,
|
||||
ty = NF_TEXT[screen][layer].height; // Salto de linea
|
||||
tx ++;
|
||||
if (tx > NF_TEXT[screen][layer].width) { // Si llegas a la ultima linea
|
||||
tx = 0; // vuelve a la primera
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Marca esta capa de texto para actualizar
|
||||
NF_TEXT[screen][layer].update = true;
|
||||
|
||||
// Libera el buffer
|
||||
free(string);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_UpdateTextLayers();
|
||||
void NF_UpdateTextLayers(void) {
|
||||
|
||||
// Variables
|
||||
u8 screen = 0;
|
||||
u8 layer = 0;
|
||||
|
||||
// Verifica si se tiene que actualizar la capa de texto
|
||||
for (screen = 0; screen < 2; screen ++) { // Bucle de pantalla
|
||||
for (layer = 0; layer < 4; layer ++) { // Bucle de capas
|
||||
if (NF_TEXT[screen][layer].update) { // Si estas marcado para actualizar, hazlo
|
||||
NF_UpdateVramMap(screen, layer);
|
||||
// Y marcala como actualizada
|
||||
NF_TEXT[screen][layer].update = false;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ClearTextLayer();
|
||||
void NF_ClearTextLayer(u8 screen, u8 layer) {
|
||||
|
||||
// Verifica si la capa de texto de destino existe
|
||||
if (!NF_TEXT[screen][layer].exist) {
|
||||
NF_Error(114, NULL, screen);
|
||||
}
|
||||
|
||||
// Calcula el tamaño del buffer
|
||||
u32 size = (((NF_TEXT[screen][layer].width + 1) * (NF_TEXT[screen][layer].height + 1)) << 1);
|
||||
|
||||
// Pon a 0 todos los bytes del mapa de la capa de texto
|
||||
memset(NF_BUFFER_BGMAP[NF_TEXT[screen][layer].slot], 0, size);
|
||||
|
||||
// Marca esta capa de texto para actualizar
|
||||
NF_TEXT[screen][layer].update = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Funcion NF_DefineTextColor();
|
||||
void NF_DefineTextColor(u8 screen, u8 layer, u8 color, u8 r, u8 g, u8 b) {
|
||||
|
||||
// Verifica si la capa de texto de destino existe
|
||||
if (!NF_TEXT[screen][layer].exist) {
|
||||
NF_Error(114, NULL, screen);
|
||||
}
|
||||
|
||||
// Calcula el valor RGB
|
||||
u16 rgb = ((r)|((g) << 5)|((b) << 10));
|
||||
// Direccion en VRAM
|
||||
u32 address = 0;
|
||||
|
||||
// Modifica la paleta
|
||||
if (screen == 0) {
|
||||
|
||||
vramSetBankE(VRAM_E_LCD);
|
||||
address = (0x06880000) + (layer << 13) + (color << 9); // Primer color de la paleta
|
||||
*((u16*)address) = (u16)0xFF00FF;
|
||||
address = (0x06880000) + (layer << 13) + (color << 9) + 2; // Segundo color de la paleta
|
||||
*((u16*)address) = rgb;
|
||||
vramSetBankE(VRAM_E_BG_EXT_PALETTE);
|
||||
|
||||
} else { // Paletas de la pantalla 1 (VRAM_H)
|
||||
|
||||
vramSetBankH(VRAM_H_LCD);
|
||||
address = (0x06898000) + (layer << 13) + (color << 9); // Primer color de la paleta
|
||||
*((u16*)address) = (u16)0xFF00FF;
|
||||
address = (0x06898000) + (layer << 13) + (color << 9) + 2; // Segundo color de la paleta
|
||||
*((u16*)address) = rgb;
|
||||
vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Function NF_SetTextColor();
|
||||
void NF_SetTextColor(u8 screen, u8 layer, u8 color) {
|
||||
|
||||
NF_TEXT[screen][layer].pal = color;
|
||||
|
||||
}
|
430
examples/templates/using_nflib/nflib/source/nf_text16.c
Normal file
430
examples/templates/using_nflib/nflib/source/nf_text16.c
Normal file
@ -0,0 +1,430 @@
|
||||
|
||||
// NightFox LIB - Funciones de Textos de 16 pixeles
|
||||
// Requiere DevkitARM
|
||||
// Codigo por Cesar Rincon "NightFox"
|
||||
// http://www.nightfoxandco.com/
|
||||
// Version 20140413
|
||||
|
||||
|
||||
|
||||
// Includes devKitPro
|
||||
#include <nds.h>
|
||||
#include <filesystem.h>
|
||||
#include <fat.h>
|
||||
|
||||
// Includes C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Includes propios
|
||||
#include "nf_basic.h"
|
||||
#include "nf_2d.h"
|
||||
#include "nf_tiledbg.h"
|
||||
#include "nf_text.h"
|
||||
#include "nf_text16.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_LoadTextFont16();
|
||||
void NF_LoadTextFont16(const char* file, const char* name, u16 width, u16 height, u8 rotation) {
|
||||
|
||||
// Variable temporal del tamaño de la paleta
|
||||
u32 pal_size = 0;
|
||||
|
||||
// Busca un slot libre
|
||||
u16 n = 0;
|
||||
u8 slot = 255;
|
||||
for (n = 0; n < NF_SLOTS_TBG; n ++) { // Busca en todos los slots
|
||||
if (NF_TILEDBG[n].available) { // Si esta libre
|
||||
NF_TILEDBG[n].available = false; // Marcalo como en uso
|
||||
slot = n; // Guarda el slot a usar
|
||||
n = NF_SLOTS_TBG; // Deja de buscar
|
||||
}
|
||||
}
|
||||
// Si no hay ningun slot libre, error
|
||||
if (slot == 255) {
|
||||
NF_Error(103, "Tiled Bg", NF_SLOTS_TBG);
|
||||
}
|
||||
|
||||
// Verifica que el fondo sea multiplo de 256px (32 tiles)
|
||||
if (((width % 256) != 0) || ((height % 256) != 0)) {
|
||||
NF_Error(115, file, 0);
|
||||
}
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_BUFFER_BGMAP[slot]); // Buffer para los mapas
|
||||
NF_BUFFER_BGMAP[slot] = NULL;
|
||||
free(NF_BUFFER_BGTILES[slot]); // Buffer para los tiles
|
||||
NF_BUFFER_BGTILES[slot] = NULL;
|
||||
free(NF_BUFFER_BGPAL[slot]); // Buffer para los paletas
|
||||
NF_BUFFER_BGPAL[slot] = NULL;
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
|
||||
// Carga el archivo .fnt
|
||||
sprintf(filename, "%s/%s.fnt", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
NF_TILEDBG[slot].tilesize = (NF_TEXT_FONT_CHARS_16 << 7); // 1 letra 128 bytes (letras * 128)
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGTILES[slot] = (char*) calloc (NF_TILEDBG[slot].tilesize, sizeof(char));
|
||||
if (NF_BUFFER_BGTILES[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].tilesize);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BUFFER_BGTILES[slot], 1, NF_TILEDBG[slot].tilesize, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
|
||||
// Rota los Gfx de los tiles si es necesario
|
||||
if (rotation > 0) {
|
||||
for (n = 0; n < (NF_TEXT_FONT_CHARS_16 << 1); n ++) {
|
||||
NF_RotateTileGfx(slot, n, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
// Crea un archivo .MAP vacio en RAM
|
||||
// ((ancho / 8) * (alto / 8)) * 2
|
||||
NF_TILEDBG[slot].mapsize = (((width >> 3) * (height >> 3)) << 1);
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGMAP[slot] = (char*) calloc (NF_TILEDBG[slot].mapsize, sizeof(char));
|
||||
if (NF_BUFFER_BGMAP[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].mapsize);
|
||||
}
|
||||
// Y ponlo a 0
|
||||
memset(NF_BUFFER_BGMAP[slot], 0, NF_TILEDBG[slot].mapsize);
|
||||
|
||||
// Carga el archivo .PAL
|
||||
sprintf(filename, "%s/%s.pal", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
pal_size = ftell(file_id);
|
||||
NF_TILEDBG[slot].palsize = pal_size;
|
||||
rewind(file_id);
|
||||
// Si el tamaño es inferior a 512 bytes, ajustalo
|
||||
if (NF_TILEDBG[slot].palsize < 512) NF_TILEDBG[slot].palsize = 512;
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGPAL[slot] = (char*) calloc (NF_TILEDBG[slot].palsize, sizeof(char));
|
||||
if (NF_BUFFER_BGPAL[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].palsize);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BUFFER_BGPAL[slot], 1, pal_size, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
|
||||
// Guarda el nombre del Fondo
|
||||
sprintf(NF_TILEDBG[slot].name, "%s", name);
|
||||
|
||||
// Y las medidas
|
||||
NF_TILEDBG[slot].width = width;
|
||||
NF_TILEDBG[slot].height = height;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_CreateTextLayer16();
|
||||
void NF_CreateTextLayer16(u8 screen, u8 layer, u8 rotation, const char* name) {
|
||||
|
||||
u8 n = 0; // Bucle
|
||||
u8 slot = 255; // Slot seleccionado
|
||||
char bg[32]; // Nombre
|
||||
|
||||
// Crea un fondo para usarlo como capa de texto
|
||||
NF_CreateTiledBg(screen, layer, name);
|
||||
|
||||
// Busca el numero de slot donde esta cargada la fuente
|
||||
sprintf(bg, "%s", name); // Obten el nombre del fondo a buscar
|
||||
for (n = 0; n < NF_SLOTS_TBG; n ++) { // Busca en todos los slots
|
||||
if (strcmp(bg, NF_TILEDBG[n].name) == 0) { // Si lo encuentras
|
||||
slot = n; // Guarda el slot a usar
|
||||
n = NF_SLOTS_TBG; // Deja de buscar
|
||||
}
|
||||
}
|
||||
|
||||
// Guarda si el texto debe ser rotado
|
||||
NF_TEXT[screen][layer].rotation = rotation;
|
||||
|
||||
// Guarda las medidas del fondo en tiles (ultimo numero de tile)
|
||||
switch (rotation) {
|
||||
case 0: // Sin rotacion
|
||||
NF_TEXT[screen][layer].width = ((NF_TILEDBG[slot].width >> 3) - 1);
|
||||
NF_TEXT[screen][layer].height = ((NF_TILEDBG[slot].height >> 4) - 1);
|
||||
break;
|
||||
case 1: // 90º derecha
|
||||
NF_TEXT[screen][layer].width = ((NF_TILEDBG[slot].width >> 4) - 1);
|
||||
NF_TEXT[screen][layer].height = ((NF_TILEDBG[slot].height >> 3) - 1);
|
||||
break;
|
||||
case 2: // 90º izquierda
|
||||
NF_TEXT[screen][layer].width = ((NF_TILEDBG[slot].width >> 4) - 1);
|
||||
NF_TEXT[screen][layer].height = ((NF_TILEDBG[slot].height >> 3) - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
// Almacena el slot donde esta cargada la fuente
|
||||
NF_TEXT[screen][layer].slot = slot;
|
||||
|
||||
// Y marcalo como creado
|
||||
NF_TEXT[screen][layer].exist = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_WriteText16();
|
||||
void NF_WriteText16(u8 screen, u8 layer, u16 x, u16 y, const char* text) {
|
||||
|
||||
// Verifica si la capa de texto de destino existe
|
||||
if (!NF_TEXT[screen][layer].exist) {
|
||||
NF_Error(114, NULL, screen);
|
||||
}
|
||||
|
||||
u16 n = 0; // Variable de uso general
|
||||
|
||||
s16 value = 0; // Valor
|
||||
|
||||
u16 tsize = strlen(text); // Calcula el numero de letras del texto
|
||||
|
||||
u8* string; // Buffer temporal
|
||||
string = NULL;
|
||||
string = (u8*) calloc (tsize, sizeof(u8));
|
||||
|
||||
// Almacena en el buffer temporal el valor de los caracteres
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
value = ((int)(text[n])) - 32; // Resta 32 al valor entrado
|
||||
if (value < 0) value = 0;
|
||||
string[n] = value;
|
||||
// Si es un caracter especial...
|
||||
if (string[n] > 95) {
|
||||
// Resetea el caracter...
|
||||
string[n] = 0;
|
||||
// Verifica caracteres especiales
|
||||
switch (((int)(text[n]))) {
|
||||
// Salto de linea
|
||||
case 10: // \n
|
||||
string[n] = 200;
|
||||
break;
|
||||
// Caracteres especiales
|
||||
case 199: // Ç
|
||||
string[n] = 96;
|
||||
break;
|
||||
case 231: // ç
|
||||
string[n] = 97;
|
||||
break;
|
||||
case 209: // Ñ
|
||||
string[n] = 98;
|
||||
break;
|
||||
case 241: // ñ
|
||||
string[n] = 99;
|
||||
break;
|
||||
// Acentos Mayusculas
|
||||
case 193: // Á
|
||||
string[n] = 100;
|
||||
break;
|
||||
case 201: // É
|
||||
string[n] = 101;
|
||||
break;
|
||||
case 205: // Í
|
||||
string[n] = 102;
|
||||
break;
|
||||
case 211: // Ó
|
||||
string[n] = 103;
|
||||
break;
|
||||
case 218: // Ú
|
||||
string[n] = 104;
|
||||
break;
|
||||
// Acentos Minusculas
|
||||
case 225: // á
|
||||
string[n] = 105;
|
||||
break;
|
||||
case 233: // é
|
||||
string[n] = 106;
|
||||
break;
|
||||
case 237: // í
|
||||
string[n] = 107;
|
||||
break;
|
||||
case 243: // ó
|
||||
string[n] = 108;
|
||||
break;
|
||||
case 250: // ú
|
||||
string[n] = 109;
|
||||
break;
|
||||
// Dieresis
|
||||
case 239: // ï
|
||||
string[n] = 110;
|
||||
break;
|
||||
case 252: // ü
|
||||
string[n] = 111;
|
||||
break;
|
||||
// Admiracion e interrogante (Español)
|
||||
case 161: // ¡
|
||||
string[n] = 112;
|
||||
break;
|
||||
case 191: // ¿
|
||||
string[n] = 113;
|
||||
break;
|
||||
// Caracter invalido
|
||||
default:
|
||||
string[n] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Variable para calcular la posicion del texto
|
||||
s16 pos_x = 0; // Posicion X real en tiles
|
||||
s16 pos_y = 0; // Posicion Y real en tiles
|
||||
s16 tx = 0; // Posicion X del texto
|
||||
s16 ty = 0; // Posicion Y del texto
|
||||
|
||||
switch (NF_TEXT[screen][layer].rotation) {
|
||||
|
||||
case 0: // Sin rotacion
|
||||
// Traspasa las coordenadas
|
||||
tx = x;
|
||||
ty = y;
|
||||
// Copia el texto al buffer letra a letra
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
// Si es un caracter valido
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR_16) {
|
||||
// Calcula la posicion en el tilemap
|
||||
pos_x = tx;
|
||||
pos_y = (ty << 1);
|
||||
// Escribe la letra correspondiente
|
||||
value = ((((int)(string[n] >> 5)) << 5) + string[n]);
|
||||
NF_SetTileOfMap(screen,layer, pos_x, pos_y, ((NF_TEXT[screen][layer].pal << 12) + value));
|
||||
NF_SetTileOfMap(screen,layer, pos_x, (pos_y + 1), ((NF_TEXT[screen][layer].pal << 12) + (value + 32)));
|
||||
// Siguiente letra
|
||||
tx ++;
|
||||
}
|
||||
if ((tx > NF_TEXT[screen][layer].width) || (string[n] == 200)) { // Si llegas al final de linea,
|
||||
tx = 0; // salto de linea
|
||||
ty ++;
|
||||
if (ty > NF_TEXT[screen][layer].height) { // Si estas en la ultima linea,
|
||||
ty = 0; // vuelve a la primera
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // 90º derecha
|
||||
// Traspasa las coordenadas
|
||||
tx = (NF_TEXT[screen][layer].width - y);
|
||||
ty = x;
|
||||
// Copia el texto al buffer letra a letra
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
// Si es un caracter valido
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR_16) {
|
||||
// Calcula la posicion en el tilemap
|
||||
pos_x = (tx << 1);
|
||||
pos_y = ty;
|
||||
// Escribe la letra correspondiente
|
||||
value = ((((int)(string[n] >> 5)) << 5) + string[n]);
|
||||
NF_SetTileOfMap(screen,layer, pos_x, pos_y, ((NF_TEXT[screen][layer].pal << 12) + value));
|
||||
NF_SetTileOfMap(screen,layer, (pos_x - 1), pos_y, ((NF_TEXT[screen][layer].pal << 12) + (value + 32)));
|
||||
// Siguiente letra
|
||||
ty ++;
|
||||
}
|
||||
if ((ty > NF_TEXT[screen][layer].height) || (string[n] == 200)) { // Si llegas al final de linea,
|
||||
ty = 0; // salto de linea
|
||||
tx --;
|
||||
if (tx < 0) { // Si estas en la ultima linea,
|
||||
tx = NF_TEXT[screen][layer].width; // vuelve a la primera
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // 90º izquierda
|
||||
// Traspasa las coordenadas
|
||||
tx = y;
|
||||
ty = (NF_TEXT[screen][layer].height - x);
|
||||
// Copia el texto al buffer letra a letra
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
// Si es un caracter valido
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR_16) {
|
||||
// Calcula la posicion en el tilemap
|
||||
pos_x = (tx << 1);
|
||||
pos_y = ty;
|
||||
// Escribe la letra correspondiente
|
||||
value = ((((int)(string[n] >> 5)) << 5) + string[n]);
|
||||
NF_SetTileOfMap(screen,layer, pos_x, pos_y, ((NF_TEXT[screen][layer].pal << 12) + value));
|
||||
NF_SetTileOfMap(screen,layer, (pos_x + 1), pos_y, ((NF_TEXT[screen][layer].pal << 12) + (value + 32)));
|
||||
// Siguiente letra
|
||||
ty --;
|
||||
}
|
||||
if ((ty < 0) || (string[n] == 200)) { // Si llegas al final de linea,
|
||||
ty = NF_TEXT[screen][layer].height; // Salto de linea
|
||||
tx ++;
|
||||
if (tx > NF_TEXT[screen][layer].width) { // Si llegas a la ultima linea
|
||||
tx = 0; // vuelve a la primera
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Marca esta capa de texto para actualizar
|
||||
NF_TEXT[screen][layer].update = true;
|
||||
|
||||
// Libera el buffer
|
||||
free(string);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Funcion NF_ClearTextLayer16();
|
||||
void NF_ClearTextLayer16(u8 screen, u8 layer) {
|
||||
|
||||
// Verifica si la capa de texto de destino existe
|
||||
if (!NF_TEXT[screen][layer].exist) {
|
||||
NF_Error(114, NULL, screen);
|
||||
}
|
||||
|
||||
// Calcula el tamaño del buffer (segun la rotacion)
|
||||
u32 size = 0;
|
||||
switch (NF_TEXT[screen][layer].rotation) {
|
||||
case 0: // Sin rotacion
|
||||
size = (((NF_TEXT[screen][layer].width + 1) * ((NF_TEXT[screen][layer].height + 1) << 1)) << 1);
|
||||
break;
|
||||
case 1: // 90º a la derecha
|
||||
size = ((((NF_TEXT[screen][layer].width + 1) << 1) * (NF_TEXT[screen][layer].height + 1)) << 1);
|
||||
break;
|
||||
case 2: // 90º a la izquierda
|
||||
size = ((((NF_TEXT[screen][layer].width + 1) << 1) * (NF_TEXT[screen][layer].height + 1)) << 1);
|
||||
break;
|
||||
}
|
||||
|
||||
// Pon a 0 todos los bytes del mapa de la capa de texto
|
||||
memset(NF_BUFFER_BGMAP[NF_TEXT[screen][layer].slot], 0, size);
|
||||
|
||||
// Marca esta capa de texto para actualizar
|
||||
NF_TEXT[screen][layer].update = true;
|
||||
|
||||
}
|
1383
examples/templates/using_nflib/nflib/source/nf_tiledbg.c
Normal file
1383
examples/templates/using_nflib/nflib/source/nf_tiledbg.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
examples/templates/using_nflib/nitrofiles/bg/bg0.img
Normal file
BIN
examples/templates/using_nflib/nitrofiles/bg/bg0.img
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/bg/bg0.map
Normal file
BIN
examples/templates/using_nflib/nitrofiles/bg/bg0.map
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/bg/bg0.pal
Normal file
BIN
examples/templates/using_nflib/nitrofiles/bg/bg0.pal
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/bg/bg1.img
Normal file
BIN
examples/templates/using_nflib/nitrofiles/bg/bg1.img
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/bg/bg1.map
Normal file
BIN
examples/templates/using_nflib/nitrofiles/bg/bg1.map
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/bg/bg1.pal
Normal file
BIN
examples/templates/using_nflib/nitrofiles/bg/bg1.pal
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/bg/bg3.img
Normal file
BIN
examples/templates/using_nflib/nitrofiles/bg/bg3.img
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/bg/bg3.map
Normal file
BIN
examples/templates/using_nflib/nitrofiles/bg/bg3.map
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/bg/bg3.pal
Normal file
BIN
examples/templates/using_nflib/nitrofiles/bg/bg3.pal
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/fnt/default.fnt
Normal file
BIN
examples/templates/using_nflib/nitrofiles/fnt/default.fnt
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/fnt/default.pal
Normal file
BIN
examples/templates/using_nflib/nitrofiles/fnt/default.pal
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/robot.dsm
Normal file
BIN
examples/templates/using_nflib/nitrofiles/robot.dsm
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/robot_wave.dsa
Normal file
BIN
examples/templates/using_nflib/nitrofiles/robot_wave.dsa
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/sprite/bola.img
Normal file
BIN
examples/templates/using_nflib/nitrofiles/sprite/bola.img
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/sprite/bola.pal
Normal file
BIN
examples/templates/using_nflib/nitrofiles/sprite/bola.pal
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera1.img
Normal file
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera1.img
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera1.pal
Normal file
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera1.pal
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera2.img
Normal file
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera2.img
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera2.pal
Normal file
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera2.pal
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera3.img
Normal file
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera3.img
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera3.pal
Normal file
BIN
examples/templates/using_nflib/nitrofiles/sprite/calabera3.pal
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/sprite/personaje.img
Normal file
BIN
examples/templates/using_nflib/nitrofiles/sprite/personaje.img
Normal file
Binary file not shown.
BIN
examples/templates/using_nflib/nitrofiles/sprite/personaje.pal
Normal file
BIN
examples/templates/using_nflib/nitrofiles/sprite/personaje.pal
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
276
examples/templates/using_nflib/source/main.c
Normal file
276
examples/templates/using_nflib/source/main.c
Normal file
@ -0,0 +1,276 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2008-2011, 2019, 2022
|
||||
// SPDX-FileContributor: NightFox, 2009-2011
|
||||
//
|
||||
// This file is part of Nitro Engine
|
||||
|
||||
// NightFox’s Lib (NFlib) is a library that can supports the 2D hardware of the
|
||||
// NDS. It's ideal to complement Nitro Engine, as it only supports the 3D
|
||||
// hardware. The latest version can be found at the following link:
|
||||
//
|
||||
// https://github.com/knightfox75/nds_nflib
|
||||
//
|
||||
// A few notes:
|
||||
//
|
||||
// - Remember to avoid using 3D features of NFlib.
|
||||
//
|
||||
// - You are free to use any features of NFlib in the secondary screen, but you
|
||||
// need to assign VRAM C and D to NFlib to get space for sprites and
|
||||
// backgrounds.
|
||||
//
|
||||
// - You could load 2D background and sprites in the same screen as the 3D
|
||||
// rendering, but you will have to give up VRAM banks A and B. If you also use
|
||||
// banks C and D for the secondary screen, it will leave you without any VRAM
|
||||
// for textures.
|
||||
//
|
||||
// - Including the code of the library with your game (or the prebuilt .a file),
|
||||
// like in this template, isn't good practice. This may change in the near
|
||||
// future if I find a better way to integrate both libraries.
|
||||
//
|
||||
// I have prebuilt NFlib in this example so that it's easier to use it, but
|
||||
// this may cause future problems when there are updates in devkitARM. At
|
||||
// that point, it will be needed to clean NFlib and rebuild it.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <nds.h>
|
||||
#include <NEMain.h>
|
||||
#include <nf_lib.h>
|
||||
|
||||
NE_Camera *Camera;
|
||||
NE_Model *Model;
|
||||
NE_Animation *Animation;
|
||||
NE_Material *Material;
|
||||
|
||||
void Draw3DScene(void)
|
||||
{
|
||||
NE_CameraUse(Camera);
|
||||
|
||||
NE_PolyFormat(31, 0, NE_LIGHT_0, NE_CULL_NONE, 0);
|
||||
NE_ModelDraw(Model);
|
||||
}
|
||||
|
||||
void WaitLoop(void)
|
||||
{
|
||||
while(1)
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
void LoadAndSetupGraphics3D(void)
|
||||
{
|
||||
// When using nflib for the 2D sub screen engine, banks C and H are used for
|
||||
// backgrounds and banks D and I are used for sprites. Nitro Engine only
|
||||
// uses bank E for palettes, so the only thing we need to do is to tell
|
||||
// Nitro Engine to only use banks A and B and leave C and D unused.
|
||||
|
||||
NE_Init3D();
|
||||
NE_TextureSystemReset(0, 0, NE_VRAM_AB);
|
||||
|
||||
// Create objects
|
||||
|
||||
Model = NE_ModelCreate(NE_Animated);
|
||||
Camera = NE_CameraCreate();
|
||||
Material = NE_MaterialCreate();
|
||||
Animation = NE_AnimationCreate();
|
||||
|
||||
// Load assets from the filesystem
|
||||
|
||||
if (NE_ModelLoadDSMFAT(Model, "robot.dsm") == 0)
|
||||
{
|
||||
consoleDemoInit();
|
||||
iprintf("Couldn't load model...");
|
||||
WaitLoop();
|
||||
}
|
||||
|
||||
if (NE_AnimationLoadFAT(Animation, "robot_wave.dsa") == 0)
|
||||
{
|
||||
consoleDemoInit();
|
||||
iprintf("Couldn't load animation...");
|
||||
WaitLoop();
|
||||
}
|
||||
|
||||
if (NE_MaterialTexLoadFAT(Material, NE_A1RGB5, 256, 256, NE_TEXGEN_TEXCOORD,
|
||||
"texture_tex.bin") == 0)
|
||||
{
|
||||
consoleDemoInit();
|
||||
iprintf("Couldn't load texture...");
|
||||
WaitLoop();
|
||||
}
|
||||
|
||||
// Assign material to the model
|
||||
NE_ModelSetMaterial(Model, Material);
|
||||
|
||||
// Assign animation to the model and start it
|
||||
NE_ModelSetAnimation(Model, Animation);
|
||||
NE_ModelAnimStart(Model, NE_ANIM_LOOP, floattof32(0.1));
|
||||
|
||||
// Setup light
|
||||
NE_LightSet(0, NE_White, 0, -1, -1);
|
||||
|
||||
// Setup background color
|
||||
NE_ClearColorSet(NE_Black, 31, 63);
|
||||
|
||||
// Setup camera
|
||||
NE_CameraSet(Camera,
|
||||
6, 3, -4,
|
||||
0, 3, 0,
|
||||
0, 1, 0);
|
||||
}
|
||||
|
||||
void LoadAndSetupGraphics2D(void)
|
||||
{
|
||||
// Initialize sub 2D engine
|
||||
NF_Set2D(1, 0);
|
||||
|
||||
// Initialize sprites for sub screen (it uses VRAM D and I)
|
||||
NF_InitSpriteBuffers();
|
||||
NF_InitSpriteSys(1);
|
||||
|
||||
// Load assets from filesystem to RAM
|
||||
NF_LoadSpriteGfx("sprite/personaje", 1, 64, 64);
|
||||
NF_LoadSpritePal("sprite/personaje", 1);
|
||||
|
||||
// Copy all frames to VRAM
|
||||
NF_VramSpriteGfx(1, 1, 0, false);
|
||||
NF_VramSpritePal(1, 1, 0);
|
||||
|
||||
// Display sprite on the screen
|
||||
NF_CreateSprite(1, 0, 0, 0, 0, 0);
|
||||
|
||||
// Initialize tiled backgrounds and text systems for the 2D sub engine (it
|
||||
// uses VRAM C and H)
|
||||
NF_InitTiledBgBuffers();
|
||||
NF_InitTiledBgSys(1);
|
||||
NF_InitTextSys(1);
|
||||
|
||||
// Load assets from filesystem to RAM
|
||||
NF_LoadTiledBg("bg/bg3", "capa_3", 256, 256);
|
||||
NF_LoadTiledBg("bg/bg1", "capa_1", 1536, 256);
|
||||
NF_LoadTiledBg("bg/bg0", "capa_0", 2048, 256);
|
||||
NF_LoadTextFont("fnt/default", "normal", 256, 256, 0);
|
||||
|
||||
// Create tiled backgrounds
|
||||
NF_CreateTiledBg(1, 3, "capa_3");
|
||||
NF_CreateTiledBg(1, 2, "capa_1");
|
||||
NF_CreateTiledBg(1, 1, "capa_0");
|
||||
|
||||
// Create text layer
|
||||
NF_CreateTextLayer(1, 0, 0, "normal");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Initialize nitroFS before doing anything else
|
||||
NF_Set2D(0, 0);
|
||||
NF_Set2D(1, 0);
|
||||
consoleDemoInit();
|
||||
iprintf("Starting nitroFS...");
|
||||
swiWaitForVBlank();
|
||||
|
||||
// Set the root folder to the nitroFS filesystem
|
||||
NF_SetRootFolder("NITROFS");
|
||||
|
||||
// Setup interrupt handlers
|
||||
irqEnable(IRQ_HBLANK);
|
||||
irqSet(IRQ_VBLANK, NE_VBLFunc);
|
||||
irqSet(IRQ_HBLANK, NE_HBLFunc);
|
||||
|
||||
// Load and setup graphics
|
||||
LoadAndSetupGraphics3D();
|
||||
LoadAndSetupGraphics2D();
|
||||
|
||||
// Initialize variables to control the sprite
|
||||
int pj_x = 0;
|
||||
int pj_y = 127;
|
||||
unsigned int pj_frame = 0;
|
||||
unsigned int pj_anim_ticks = 0;
|
||||
int pj_speed = 1;
|
||||
|
||||
// Initialize variables to control the backgrounds
|
||||
int bg_x[4] = {0, 0, 0};
|
||||
|
||||
// Print instructions for the user
|
||||
NF_WriteText(1, 0, 1, 1, "PAD: Rotate model");
|
||||
NF_WriteText(1, 0, 1, 2, "L/R: Scroll background");
|
||||
NF_WriteText(1, 0, 1, 3, "START: Exit");
|
||||
NF_UpdateTextLayers();
|
||||
|
||||
while (1)
|
||||
{
|
||||
scanKeys();
|
||||
uint32 keys = keysHeld();
|
||||
|
||||
if (keys & KEY_START)
|
||||
break;
|
||||
|
||||
if (keys & KEY_RIGHT)
|
||||
NE_ModelRotate(Model, 0, 2, 0);
|
||||
if (keys & KEY_LEFT)
|
||||
NE_ModelRotate(Model, 0, -2, 0);
|
||||
if (keys & KEY_UP)
|
||||
NE_ModelRotate(Model, 0, 0, 2);
|
||||
if (keys & KEY_DOWN)
|
||||
NE_ModelRotate(Model, 0, 0, -2);
|
||||
|
||||
if (keys & KEY_L)
|
||||
{
|
||||
bg_x[0] -= 2;
|
||||
if (bg_x[0] < 0)
|
||||
bg_x[0] = 0;
|
||||
}
|
||||
|
||||
if (keys & KEY_R)
|
||||
{
|
||||
bg_x[0] += 2;
|
||||
if (bg_x[0] > 1152)
|
||||
bg_x[0] = 1152;
|
||||
}
|
||||
|
||||
// For the parallax effect, calculate the scroll of the second layer
|
||||
// based on the scroll of the first one.
|
||||
bg_x[1] = bg_x[0] / 2;
|
||||
|
||||
// Move sprite
|
||||
pj_x += pj_speed;
|
||||
if ((pj_x < 0) || (pj_x > 191))
|
||||
{
|
||||
pj_speed = -pj_speed;
|
||||
if (pj_speed > 0)
|
||||
NF_HflipSprite(1, 0, false);
|
||||
else
|
||||
NF_HflipSprite(1, 0, true);
|
||||
}
|
||||
NF_MoveSprite(1, 0, pj_x, pj_y);
|
||||
|
||||
// Animate sprite
|
||||
pj_anim_ticks++;
|
||||
if (pj_anim_ticks > 5)
|
||||
{
|
||||
pj_anim_ticks = 0;
|
||||
pj_frame++;
|
||||
if (pj_frame > 11)
|
||||
pj_frame = 0;
|
||||
NF_SpriteFrame(1, 0, pj_frame);
|
||||
}
|
||||
|
||||
// Refresh shadow OAM copy
|
||||
NF_SpriteOamSet(1);
|
||||
|
||||
// Draw scene...
|
||||
NE_Process(Draw3DScene);
|
||||
NE_WaitForVBL(NE_UPDATE_ANIMATIONS);
|
||||
|
||||
// At this point we are in the vertical blank period. This is where 2D
|
||||
// entities have to be updated to avoid flickering.
|
||||
|
||||
// Update the scroll of the backgrounds
|
||||
for (int n = 0; n < 3; n ++)
|
||||
NF_ScrollBg(1, n + 1, bg_x[n], 0);
|
||||
|
||||
// Copy shadow OAM copy to the OAM of the 2D sub engine
|
||||
oamUpdate(&oamSub);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -16,13 +16,20 @@ Features:
|
||||
<https://github.com/AntonioND/dsma-library>`_, which converts MD5 models (with
|
||||
skeletal animation) into a format that can be rendered with hardware
|
||||
acceleration. It can also blend two animations together (for transitions).
|
||||
- Support for all format of textures (except compressed textures).
|
||||
- Support for all format of textures (even compressed textures, but the
|
||||
converter included in this repository doesn't support them yet).
|
||||
- Dual 3D (render 3D to both screens, but at 30 FPS instead of 60 FPS).
|
||||
- Functions to render 2D images accelerated by 3D hardware.
|
||||
- Basic text system.
|
||||
- Basic GUI elements like buttons and scrollbars.
|
||||
- Basic physic system: Axis-aligned bounding boxes (AABB) only.
|
||||
|
||||
Nitro Engine doesn't support any of the 2D hardware of the DS. In order to use
|
||||
the 2D hardware you can use libnds directly, or you can use a library like
|
||||
`NFlib <https://github.com/knightfox75/nds_nflib>`_. There is an example of how
|
||||
to integrate Nitro Engine and NFlib in the same project `here
|
||||
<./examples/templates/using_nflib>`_.
|
||||
|
||||
Setup
|
||||
-----
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user