commit 524bda167352d3ef3ecd434834c781de35673576 Author: James Garner Date: Fri Jul 4 12:35:52 2014 +0100 Existing source. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..27c33d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +dsgmLib/build/ +examples/RoomPersistency/build/ +examples/RoomPersistency/RoomPersistency.elf +examples/Collision/build/ +examples/Collision/Collision.elf +examples/Priority/build/ +examples/Priority/Priority.elf \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..af36e38 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 DS Game Maker + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..12f443c --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +DS Game Maker Library (dsgmLib) +=============================== +Object Orientation library for Nintendo DS games. \ No newline at end of file diff --git a/buildall.bat b/buildall.bat new file mode 100644 index 0000000..5160672 --- /dev/null +++ b/buildall.bat @@ -0,0 +1,18 @@ +pushd DSGMLib +make +pause +popd +pushd examples +pushd RoomPersistency +make +rem start "" "RoomPersistency.nds" +popd +pushd Collision +make +rem start "" "Collision.nds" +popd +pushd Priority +make +rem start "" "Priority.nds" +popd +popd \ No newline at end of file diff --git a/dsgmLib/Makefile b/dsgmLib/Makefile new file mode 100644 index 0000000..5cf8338 --- /dev/null +++ b/dsgmLib/Makefile @@ -0,0 +1,132 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +include $(DEVKITARM)/ds_rules + +# Uncomment for debug mode +#DSGMDEBUG := -DDEBUG + +#--------------------------------------------------------------------------------- +# 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 +#--------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR)) +BUILD := build +SOURCES := gfx source data +INCLUDES := include build + +#--------------------------------------------------------------------------------- +# 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 -DBUILDINGLIB $(DSGMDEBUG) +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 +#--------------------------------------------------------------------------------- +#LIBS := -lnds9 +LIBS := -lnds + + +#--------------------------------------------------------------------------------- +# 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)/$(TARGET).a +#export OUTPUT := $(CURDIR)/b.a + +export VPATH := $(foreach dir,$(SOURCES),$(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,$(SOURCES),$(notdir $(wildcard $(dir)/*.bin))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(BINFILES:.bin=.o) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(TARGET).ds.gba + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +#$(OUTPUT).nds : $(OUTPUT).elf +#$(OUTPUT).elf : $(OFILES) +$(OUTPUT) : $(OFILES) + +#--------------------------------------------------------------------------------- +%.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/dsgmLib/build.bat b/dsgmLib/build.bat new file mode 100644 index 0000000..8182ff5 --- /dev/null +++ b/dsgmLib/build.bat @@ -0,0 +1,2 @@ +make +pause \ No newline at end of file diff --git a/dsgmLib/clean.bat b/dsgmLib/clean.bat new file mode 100644 index 0000000..8f3b4fa --- /dev/null +++ b/dsgmLib/clean.bat @@ -0,0 +1,2 @@ +make clean +pause \ No newline at end of file diff --git a/dsgmLib/include/DSGM.h b/dsgmLib/include/DSGM.h new file mode 100644 index 0000000..4e08a11 --- /dev/null +++ b/dsgmLib/include/DSGM.h @@ -0,0 +1,44 @@ +#pragma once + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "DSGM_malloc.h" +#include "DSGM_file.h" +#include "DSGM_input.h" +#include "DSGM_alarm.h" +#include "DSGM_view.h" +#include "DSGM_background.h" +#include "DSGM_text.h" +#include "DSGM_palette.h" +#include "DSGM_sprite.h" +#include "DSGM_object.h" +#include "DSGM_sound.h" +#include "DSGM_room.h" + +#ifndef BUILDINGLIB + #include "project.h" +#endif + +#define DSGM_TOP 1 +#define DSGM_BOTTOM 0 + +void DSGM_Debug(char *text, ...); + +void DSGM_InitGFX(void); +void DSGM_InitRand(void); +void DSGM_InitNitro(void); + +inline int DSGM_Random(int min, int max); + +void DSGM_Update(void); diff --git a/dsgmLib/include/DSGM_alarm.h b/dsgmLib/include/DSGM_alarm.h new file mode 100644 index 0000000..ce139bf --- /dev/null +++ b/dsgmLib/include/DSGM_alarm.h @@ -0,0 +1,7 @@ +#pragma once + +extern int DSGM_alarmCount; +extern int *DSGM_alarms; + +void DSGM_InitAlarms(void); +void DSGM_AddAlarm(void); diff --git a/dsgmLib/include/DSGM_background.h b/dsgmLib/include/DSGM_background.h new file mode 100644 index 0000000..f99e2eb --- /dev/null +++ b/dsgmLib/include/DSGM_background.h @@ -0,0 +1,56 @@ +#pragma once + +#define DSGM_NO_BACKGROUND NULL +#define DSGM_TEXT_BACKGROUND (void *)1 + +#define DSGM_FORM_RAM_BACKGROUND(background, size, type)\ +{ NULL, NULL, NULL, (u8 *)&background##_Tiles_bin, (u32 *)&background##_Tiles_bin_size, (u8 *)&background##_Map_bin, (u32 *)&background##_Map_bin_size, (u8 *)&background##_Pal_bin, (u32 *)&background##_Pal_bin_size, size, type } + +#define DSGM_FORM_NITRO_BACKGROUND(background, size, type)\ +{ #background "_Tiles.bin", #background "_Map.bin", #background "_Pal.bin", NULL, NULL, NULL, NULL, NULL, NULL, size, type } + +typedef struct { + char *nitroTilesFilename; + char *nitroMapFilename; + char *nitroPaletteFilename; + + u8 *tiles; + u32 *tilesLength; + + u8 *map; + u32 *mapLength; + + u8 *palette; + u32 *paletteLength; + + BgSize size; + BgType type; +} DSGM_Background; + +typedef struct { + DSGM_Background *background; + + u8 screen; + int layer; + bool attachedToView; + int x; + int y; + int vramId; +} DSGM_BackgroundInstance; + +void DSGM_LockBackgroundPalette(u8 screen); +void DSGM_UnlockBackgroundPalette(u8 screen); + +inline bool DSGM_BackgroundIsNitroFull(DSGM_Background *background); + +void DSGM_LoadBackgroundFull(DSGM_BackgroundInstance *backgroundInstance); + +void DSGM_LoadBackgroundNitroFull(DSGM_BackgroundInstance *background); +void DSGM_LoadBackgroundRAMFull(DSGM_BackgroundInstance *background); + +void DSGM_ScrollBackgroundFull(DSGM_View *view, DSGM_BackgroundInstance *background); + +inline BgSize DSGM_GetBGSize(u8 screen, int layer); +int DSGM_GetBGWidth(u8 screen, int layer); +int DSGM_GetBGHeight(u8 screen, int layer); +inline u16 DSGM_GetTile(DSGM_BackgroundInstance *background, int x, int y); diff --git a/dsgmLib/include/DSGM_file.h b/dsgmLib/include/DSGM_file.h new file mode 100644 index 0000000..dce7b7f --- /dev/null +++ b/dsgmLib/include/DSGM_file.h @@ -0,0 +1,7 @@ +#pragma once + +#define DSGM_AUTO_LENGTH 0 + +size_t DSGM_GetFileLength(char *filename); +void DSGM_ReadFileManual(void *destination, int start, size_t length, char *filename); +char *DSGM_ReadFile(char *filename); diff --git a/dsgmLib/include/DSGM_input.h b/dsgmLib/include/DSGM_input.h new file mode 100644 index 0000000..d051d34 --- /dev/null +++ b/dsgmLib/include/DSGM_input.h @@ -0,0 +1,26 @@ +#pragma once + +#define DSGM_NOT_HOLDING_3(k1, k2, k3) (!(DSGM_held.k1 || DSGM_held.k2 || DSGM_held.k3)) +#define DSGM_NOT_HOLDING_DPAD() (!(DSGM_held.Left || DSGM_held.Right || DSGM_held.Up || DSGM_held.Down)) + +typedef struct { + bool A; + bool B; + bool Select; + bool Start; + bool Right; + bool Left; + bool Up; + bool Down; + bool R; + bool L; + bool X; + bool Y; + bool Touch; + bool Lid; +} DSGM_Input; + +extern DSGM_Input DSGM_newpress, DSGM_held, DSGM_release; +extern touchPosition DSGM_stylus; + +void DSGM_UpdateInput(void); diff --git a/dsgmLib/include/DSGM_malloc.h b/dsgmLib/include/DSGM_malloc.h new file mode 100644 index 0000000..09150e6 --- /dev/null +++ b/dsgmLib/include/DSGM_malloc.h @@ -0,0 +1,15 @@ +#pragma once + +#define DSGM_ALLOCATION_LIMIT 128 + +typedef struct { + void **memory; + bool tracked; +} DSGM_Heap; + +extern DSGM_Heap DSGM_toFree[DSGM_ALLOCATION_LIMIT]; +extern int DSGM_toFreeCount; + +void *DSGM_TrackedAlloc(void **tracker, size_t length); +void *DSGM_Alloc(size_t length); +void DSGM_FreeAll(void); diff --git a/dsgmLib/include/DSGM_object.h b/dsgmLib/include/DSGM_object.h new file mode 100644 index 0000000..1363ffb --- /dev/null +++ b/dsgmLib/include/DSGM_object.h @@ -0,0 +1,61 @@ +#pragma once + +#define DSGM_NO_EVENT NULL + +struct DSGM_objectInstance; + +typedef void (*DSGM_Event)(struct DSGM_objectInstance *me); +typedef void (*DSGM_CollisionEventFunction)(struct DSGM_objectInstance *me, struct DSGM_objectInstance *collider); + +typedef struct { + struct DSGM_object *collider; + DSGM_CollisionEventFunction function; +} DSGM_CollisionEvent; + +typedef struct DSGM_object { + DSGM_Sprite *sprite; + + DSGM_Event create; + DSGM_Event loop; + DSGM_Event destroy; + DSGM_Event touch; + + DSGM_CollisionEvent *collisionEvents; + unsigned int collisionEventCount; +} DSGM_Object; + +typedef struct DSGM_objectInstance { + DSGM_Object *object; + u8 screen; + int x, y; + + int spriteNumber; + u8 frame; + int animationTimer; + bool hFlip; + bool vFlip; + int *angle; + bool hide; + ObjPriority priority; +} DSGM_ObjectInstance; + +typedef struct { + DSGM_ObjectInstance *objectInstances; + int objectInstanceCount; +} DSGM_ObjectGroup; + +#include "DSGM_room.h" + +void DSGM_SetupObjectGroups(DSGM_Room *room, u8 screen, int objectGroupCount); +void DSGM_SetupObjectInstances(DSGM_ObjectGroup *group, DSGM_Object *object, u8 screen, int objectInstanceCount, ...); +DSGM_ObjectGroup *DSGM_GetObjectGroupFull(DSGM_Room *room, u8 screen, DSGM_Object *object); +void DSGM_AddCollisionEvent(DSGM_Object *object, DSGM_Object *collider, DSGM_CollisionEventFunction function); + +inline bool DSGM_StylusOverObjectInstanceFull(DSGM_Room *room, DSGM_ObjectInstance *me); +inline bool DSGM_ObjectInstanceCollision(DSGM_ObjectInstance *me, DSGM_ObjectInstance *collider); + +inline int DSGM_GetObjectInstanceRotset(DSGM_ObjectInstance *me); +void DSGM_InitObjectInstanceRotation(DSGM_ObjectInstance *me); +void DSGM_InitSharedObjectInstanceRotation(DSGM_ObjectInstance *me, int rotset); +void DSGM_AnimateObjectInstance(DSGM_ObjectInstance *me, int startFrame, int endFrame, int frequency); +void DSGM_ReturnAnimateObjectInstance(DSGM_ObjectInstance *me, int returnFrame, int startFrame, int endFrame, int frequency); diff --git a/dsgmLib/include/DSGM_palette.h b/dsgmLib/include/DSGM_palette.h new file mode 100644 index 0000000..da7a411 --- /dev/null +++ b/dsgmLib/include/DSGM_palette.h @@ -0,0 +1,65 @@ +#pragma once + +#define DSGM_NO_PALETTE -1 + +#define DSGM_GetPalette(palette)\ +DSGM_Palettes[palette] + +#define DSGM_FORM_RAM_PALETTE(palette)\ +{ (u8 *)&palette##_Pal_bin, (u32 *)&palette##_Pal_bin_size } + +#define DSGM_FORM_NITRO_PALETTE(palette)\ +{ NULL, 0, #palette "_Pal.bin" } + +#define DSGM_LOAD_TOP_PALETTE_RAM(paletteName, paletteNumber)\ +DSGM_LoadTopPaletteRAM(paletteName##_Pal_bin, paletteName##_Pal_bin_size, paletteNumber) + +#define DSGM_LOAD_BOTTOM_PALETTE_RAM(paletteName, paletteNumber)\ +DSGM_LoadBottomPaletteRAM(paletteName##_Pal_bin, paletteName##_Pal_bin_size, paletteNumber) + +#define DSGM_LOAD_TOP_PALETTE_NITRO(paletteName, paletteNumber)\ +DSGM_LoadTopPaletteNitro(#paletteName "_Pal.bin", paletteNumber) + +#define DSGM_LOAD_BOTTOM_PALETTE_NITRO(paletteName, paletteNumber)\ +DSGM_LoadBottomPaletteNitro(#paletteName "_Pal.bin", paletteNumber) + +typedef struct { + u8 *palette; + u32 *paletteLength; + char *nitroFilename; + + int paletteNumber[2]; +} DSGM_Palette; + +extern int DSGM_nextPalette[2]; + +void DSGM_UnlockSpritePalette(u8 screen); +void DSGM_LockSpritePalette(u8 screen); + +inline int DSGM_NextFreePalette(u8 screen); + +inline bool DSGM_PaletteLoaded(u8 screen, DSGM_Palette *palette); + +//bool DSGM_PaletteTopLoaded(int palette); +//bool DSGM_PaletteBottomLoaded(int palette); + +//u8 DSGM_GetNextTopPalette(void); +//u8 DSGM_GetNextBottomPalette(void); + +//bool DSGM_PaletteIsNitro(int palette); + +inline bool DSGM_PaletteIsNitro(DSGM_Palette *palette); + +//void DSGM_ClearPalettes(void); + +void DSGM_ClearPalettes(DSGM_Palette *palettes, int paletteCount); + +//void DSGM_LoadTopPalette(int palette); +//void DSGM_LoadBottomPalette(int palette); + +void DSGM_LoadPaletteFull(u8 screen, DSGM_Palette *Palette); + +/*void DSGM_LoadTopPaletteRAM(u16 *palette, u32 paletteSize, DSGM_Palette *palette); +void DSGM_LoadBottomPaletteRAM(u16 *palette, u32 paletteSize, DSGM_Palette *palette); +void DSGM_LoadTopPaletteNitro(char *filename, DSGM_Palette *palette); +void DSGM_LoadBottomPaletteNitro(char *filename, DSGM_Palette *palette);*/ diff --git a/dsgmLib/include/DSGM_projectHelper.h b/dsgmLib/include/DSGM_projectHelper.h new file mode 100644 index 0000000..4921680 --- /dev/null +++ b/dsgmLib/include/DSGM_projectHelper.h @@ -0,0 +1,71 @@ +#pragma once + +#include "DSGM.h" + +#define DSGM_ALL_ROOMS -1 + +void DSGM_Init(void) { + DSGM_InitGFX(); + DSGM_InitRand(); + DSGM_InitNitro(); + DSGM_InitSoundFull(DSGM_SOUND_STREAM_COUNT); + + DSGM_ClearPalettes(DSGM_Palettes, DSGM_PALETTE_COUNT); + DSGM_SetupRooms(DSGM_ALL_ROOMS); +} + +inline DSGM_ObjectGroup *DSGM_GetGroup(DSGM_ObjectInstance *objectInstance) { + return DSGM_GetObjectGroupFull(&DSGM_Rooms[DSGM_currentRoom], objectInstance->screen, objectInstance->object); +} + +inline DSGM_ObjectGroup *DSGM_GetObjectGroup(u8 screen, DSGM_Object *object) { + return DSGM_GetObjectGroupFull(&DSGM_Rooms[DSGM_currentRoom], screen, object); +} + +inline DSGM_SoundInstance *DSGM_PlaySound(int sound) { + return DSGM_PlaySoundFull(&DSGM_Sounds[sound]); +} + +inline DSGM_SoundInstance *DSGM_PlaySoundAdvanced(int sound, u8 volume, u8 panning) { + return DSGM_PlaySoundAdvancedFull(&DSGM_Sounds[sound], volume, panning); +} + +inline bool DSGM_BackgroundIsNitro(int background) { + return DSGM_BackgroundIsNitroFull(&DSGM_Backgrounds[background]); +} + +void DSGM_LoadBackground(u8 screen, int layer, int background, bool attachedToView) { + DSGM_BackgroundInstance backgroundInstance; + backgroundInstance.background = &DSGM_Backgrounds[background]; + backgroundInstance.screen = screen; + backgroundInstance.layer = layer; + backgroundInstance.attachedToView = attachedToView; + backgroundInstance.x = 0; + backgroundInstance.y = 0; + DSGM_LoadBackgroundFull(&backgroundInstance); +} + +void DSGM_ScrollBackground(u8 screen, int layer, int x, int y) { + DSGM_Rooms[DSGM_currentRoom].backgroundInstances[screen][layer].x = x; + DSGM_Rooms[DSGM_currentRoom].backgroundInstances[screen][layer].y = y; +} + +void DSGM_SwitchRoom(int room, bool reset) { + //DSGM_LeaveRoom(&DSGM_Rooms[DSGM_currentRoom]); + + DSGM_ClearText(DSGM_TOP); + DSGM_ClearText(DSGM_BOTTOM); + DSGM_ResetSprites(DSGM_Sprites, DSGM_SPRITE_COUNT); + DSGM_ClearPalettes(DSGM_Palettes, DSGM_PALETTE_COUNT); + DSGM_ResetSound(); + DSGM_FreeAll(); + + DSGM_currentRoom = room; + //DSGM_switchingRooms = 1; + + if(reset) { + DSGM_SetupRooms(room); + } + + DSGM_LoadRoom(&DSGM_Rooms[room]); +} diff --git a/dsgmLib/include/DSGM_room.h b/dsgmLib/include/DSGM_room.h new file mode 100644 index 0000000..da44ab4 --- /dev/null +++ b/dsgmLib/include/DSGM_room.h @@ -0,0 +1,17 @@ +#pragma once + +typedef struct { + DSGM_BackgroundInstance backgroundInstances[2][4]; + + DSGM_View initialView[2]; + DSGM_View view[2]; + + DSGM_ObjectGroup *objectGroups[2]; + int objectGroupCount[2]; +} DSGM_Room; + +void DSGM_SetupViews(DSGM_Room *room); + +void DSGM_LoadRoom(DSGM_Room *room); +void DSGM_LoopRoom(DSGM_Room *room); +void DSGM_LeaveRoom(DSGM_Room *room); diff --git a/dsgmLib/include/DSGM_sound.h b/dsgmLib/include/DSGM_sound.h new file mode 100644 index 0000000..0eccc21 --- /dev/null +++ b/dsgmLib/include/DSGM_sound.h @@ -0,0 +1,41 @@ +#pragma once + +#define DSGM_MAX_SOUNDS 32 +#define DSGM_RESERVED_STREAMS 1 + +#define DSGM_SOUND_STREAM 0 +#define DSGM_SOUND_EFFECT 1 + +#define DSGM_FORM_SOUND_STREAM(sound)\ +{ DSGM_SOUND_STREAM, sound } + +#define DSGM_FORM_SOUND_EFFECT(sound)\ +{ DSGM_SOUND_EFFECT, sound } + +typedef struct { + u8 type; + int ID; + bool loaded; +} DSGM_Sound; + +typedef struct { + DSGM_Sound *sound; + int effectNumber; + + u8 volume; + u8 panning; +} DSGM_SoundInstance; + +extern int DSGM_soundStreamCount; + +extern DSGM_SoundInstance DSGM_soundInstances[DSGM_MAX_SOUNDS]; +extern int DSGM_soundInstanceCount; + +void DSGM_InitSoundFull(int soundStreamCount); +void DSGM_ResetSound(void); +DSGM_SoundInstance *DSGM_AddSoundInstance(DSGM_Sound *sound); + +DSGM_SoundInstance *DSGM_PlaySoundFull(DSGM_Sound *sound); +DSGM_SoundInstance *DSGM_PlaySoundAdvancedFull(DSGM_Sound *sound, u8 volume, u8 panning); +void DSGM_SetSoundInstanceVolumeFull(DSGM_SoundInstance *soundInstance, int volume); +void DSGM_SetSoundInstancePanningFull(DSGM_SoundInstance *soundInstance, int panning); diff --git a/dsgmLib/include/DSGM_sprite.h b/dsgmLib/include/DSGM_sprite.h new file mode 100644 index 0000000..42ecc3f --- /dev/null +++ b/dsgmLib/include/DSGM_sprite.h @@ -0,0 +1,56 @@ +#pragma once + +#define DSGM_NO_SPRITE NULL + +#define DSGM_FORM_RAM_SPRITE(sprite, palette, size, frames)\ +{ (u8 *)&sprite##_Sprite_bin, (u32 *)&sprite##_Sprite_bin_size, NULL, &DSGM_Palettes[palette], size, frames, NULL } + +#define DSGM_FORM_NITRO_SPRITE(sprite, palette, size, frames)\ +{ NULL, 0, #sprite "_Sprite.bin", &DSGM_Palettes[palette], size, frames, NULL } + +typedef struct { + u8 *tiles; + u32 *tilesLength; + char *nitroFilename; + DSGM_Palette *palette; + SpriteSize size; + u8 frames; + + u16 **topTiles; + u16 **bottomTiles; +} DSGM_Sprite; + +typedef struct { + u8 width; + u8 height; +} DSGM_Size; + +extern int DSGM_nextFreeSprite[2]; +extern int DSGM_nextFreeRotset[2]; + +extern int DSGM_rotations[2][32]; + +extern const DSGM_Size DSGM_Sizes[3][4]; + +inline int DSGM_NextFreeSpriteNumber(u8 screen); +inline int DSGM_NextFreeRotset(u8 screen); + +inline int DSGM_GetSpriteWidth(DSGM_Sprite *sprite); +inline int DSGM_GetSpriteHeight(DSGM_Sprite *sprite); + +inline bool DSGM_SpriteIsNitro(DSGM_Sprite *sprite); +inline bool DSGM_SpriteLoaded(u8 screen, DSGM_Sprite *sprite); + +void DSGM_ResetSprites(DSGM_Sprite *sprites, int spriteCount); + +void DSGM_LoadSpriteFull(u8 screen, DSGM_Sprite *sprite); + +void DSGM_CreateSprite(u8 screen, int spriteNumber, int x, int y, ObjPriority priority, int frame, bool hFlip, bool vFlip, DSGM_Sprite *sprite); +//void DSGM_CreateSprite(DSGM_ObjectInstance *instance); + +void DSGM_SetSpriteXY(u8 screen, int spriteNumber, int x, int y); +void DSGM_SetSpriteFrame(u8 screen, int spriteNumber, DSGM_Sprite *sprite, u8 frame); +void DSGM_SetSpriteHFlip(u8 screen, int spriteNumber, bool flip); +void DSGM_SetSpriteVFlip(u8 screen, int spriteNumber, bool flip); +void DSGM_SetSpritePriority(u8 screen, int spriteNumber, ObjPriority priority); +void DSGM_SetRotsetRotation(u8 screen, int rotset, int angle); diff --git a/dsgmLib/include/DSGM_text.h b/dsgmLib/include/DSGM_text.h new file mode 100644 index 0000000..51fdd7e --- /dev/null +++ b/dsgmLib/include/DSGM_text.h @@ -0,0 +1,7 @@ +#pragma once + +extern PrintConsole DSGM_text[2]; + +void DSGM_InitText(DSGM_BackgroundInstance *backgroundInstance); +void DSGM_ClearText(u8 screen); +void DSGM_DrawText(u8 screen, int x, int y, const char *format, ...); diff --git a/dsgmLib/include/DSGM_view.h b/dsgmLib/include/DSGM_view.h new file mode 100644 index 0000000..3cf6af6 --- /dev/null +++ b/dsgmLib/include/DSGM_view.h @@ -0,0 +1,6 @@ +#pragma once + +typedef struct { + int x; + int y; +} DSGM_View; diff --git a/dsgmLib/source/DSGM.c b/dsgmLib/source/DSGM.c new file mode 100644 index 0000000..8681c1e --- /dev/null +++ b/dsgmLib/source/DSGM.c @@ -0,0 +1,60 @@ +#include "DSGM.h" + +void DSGM_Debug(char *text, ...) { + #ifdef DEBUG + char buff[1024]; + va_list args; + va_start(args, text); + vsprintf(buff, text, args); + va_end(args); + nocashMessage(buff); + while(!DSGM_newpress.Start) DSGM_UpdateInput(); + while(DSGM_newpress.Start) DSGM_UpdateInput(); + #endif +} + +void DSGM_InitGFX(void) { + videoSetMode(MODE_0_2D); + videoSetModeSub(MODE_0_2D); + vramSetBankA(VRAM_A_MAIN_BG_0x06000000); + vramSetBankB(VRAM_B_MAIN_SPRITE_0x06400000); + vramSetBankC(VRAM_C_SUB_BG_0x06200000); + vramSetBankD(VRAM_D_SUB_SPRITE); + vramSetBankE(VRAM_E_BG_EXT_PALETTE); + vramSetBankF(VRAM_F_SPRITE_EXT_PALETTE); + vramSetBankG(VRAM_G_LCD); + vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE); + vramSetBankI(VRAM_I_SUB_SPRITE_EXT_PALETTE); + + bgExtPaletteEnable(); + bgExtPaletteEnableSub(); + + oamInit(&oamMain, SpriteMapping_1D_128, true); + oamInit(&oamSub, SpriteMapping_1D_128, true); +} + +void DSGM_InitRand(void) { + srand(time(NULL)); +} + +void DSGM_InitNitro(void) { + if(!nitroFSInit(NULL)) { + DSGM_Debug("NitroFS failed"); + } + chdir("nitro:/"); +} + +inline int DSGM_Random(int min, int max) { + return (rand() % max) + min; +} + +void DSGM_Update(void) { + DSGM_UpdateInput(); + + swiWaitForVBlank(); + + bgUpdate(); + + oamUpdate(&oamMain); + oamUpdate(&oamSub); +} diff --git a/dsgmLib/source/DSGM_background.c b/dsgmLib/source/DSGM_background.c new file mode 100644 index 0000000..3a119d9 --- /dev/null +++ b/dsgmLib/source/DSGM_background.c @@ -0,0 +1,160 @@ +#include "DSGM.h" + +void DSGM_UnlockBackgroundPalette(u8 screen) { + switch(screen) { + case DSGM_TOP: + vramSetBankE(VRAM_E_LCD); + break; + + case DSGM_BOTTOM: + vramSetBankH(VRAM_H_LCD); + break; + } +} + +void DSGM_LockBackgroundPalette(u8 screen) { + switch(screen) { + case DSGM_TOP: + vramSetBankE(VRAM_E_BG_EXT_PALETTE); + break; + + case DSGM_BOTTOM: + vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE); + break; + } +} + +inline bool DSGM_BackgroundIsNitroFull(DSGM_Background *background) { + return !background->tiles; +} + +void DSGM_LoadBackgroundFull(DSGM_BackgroundInstance *backgroundInstance) { + switch(backgroundInstance->screen) { + case DSGM_TOP: + backgroundInstance->vramId = bgInit(backgroundInstance->layer, backgroundInstance->background->type, backgroundInstance->background->size, backgroundInstance->layer + 28, backgroundInstance->layer * 2); + break; + + case DSGM_BOTTOM: + backgroundInstance->vramId = bgInitSub(backgroundInstance->layer, backgroundInstance->background->type, backgroundInstance->background->size, backgroundInstance->layer + 28, backgroundInstance->layer * 2); + break; + } + + bgHide(backgroundInstance->vramId); + + if(DSGM_BackgroundIsNitroFull(backgroundInstance->background)) { + DSGM_LoadBackgroundNitroFull(backgroundInstance); + } + else { + DSGM_LoadBackgroundRAMFull(backgroundInstance); + } + + //DSGM_ScrollBackgroundFull(backgroundInstance); + + bgUpdate(); + bgShow(backgroundInstance->vramId); +} + +void DSGM_LoadBackgroundNitroFull(DSGM_BackgroundInstance *backgroundInstance/*, char *nitroTilesFilename, char *nitroMapFilename, char *nitroPaletteFilename*/) { + DSGM_ReadFileManual(bgGetGfxPtr(backgroundInstance->vramId), 0, DSGM_AUTO_LENGTH, backgroundInstance->background->nitroTilesFilename); + DSGM_ReadFileManual(bgGetMapPtr(backgroundInstance->vramId), 0, DSGM_AUTO_LENGTH, backgroundInstance->background->nitroMapFilename); + DSGM_UnlockBackgroundPalette(backgroundInstance->screen); + switch(backgroundInstance->screen) { + case DSGM_TOP: + DSGM_ReadFileManual(&VRAM_E_EXT_PALETTE[backgroundInstance->layer][0], 0, DSGM_AUTO_LENGTH, backgroundInstance->background->nitroPaletteFilename); + break; + + case DSGM_BOTTOM: + DSGM_ReadFileManual(&VRAM_H_EXT_PALETTE[backgroundInstance->layer][0], 0, DSGM_AUTO_LENGTH, backgroundInstance->background->nitroPaletteFilename); + break; + } + DSGM_LockBackgroundPalette(backgroundInstance->screen); +} + +void DSGM_LoadBackgroundRAMFull(DSGM_BackgroundInstance *backgroundInstance) { + dmaCopy(backgroundInstance->background->tiles, bgGetGfxPtr(backgroundInstance->vramId), *backgroundInstance->background->tilesLength); + dmaCopy(backgroundInstance->background->map, bgGetMapPtr(backgroundInstance->vramId), *backgroundInstance->background->mapLength); + DSGM_UnlockBackgroundPalette(backgroundInstance->screen); + switch(backgroundInstance->screen) { + case DSGM_TOP: + dmaCopy(backgroundInstance->background->palette, &VRAM_E_EXT_PALETTE[backgroundInstance->layer][0], *backgroundInstance->background->paletteLength); + break; + + case DSGM_BOTTOM: + dmaCopy(backgroundInstance->background->palette, &VRAM_H_EXT_PALETTE[backgroundInstance->layer][0], *backgroundInstance->background->paletteLength); + break; + } + DSGM_LockBackgroundPalette(backgroundInstance->screen); +} + +void DSGM_ScrollBackgroundFull(DSGM_View *view, DSGM_BackgroundInstance *background) { + //DSGM_Debug("Scrolling to Y: %d\n", background->y - background->attachedToView ? view->y : 0); + //DSGM_Debug("DScrolling to Y: %d\n", view[DSGM_BOTTOM].y); + //DSGM_Debug("Scrolling bg s %d, l %d\n", background->screen, background->layer); + if(background != NULL/* && background != DSGM_TEXT_BACKGROUND*/) { + if(background->background != NULL) { + if(background->vramId != 0) { + bgSetScroll(background->vramId, background->x - background->attachedToView ? view->x : 0, background->y - background->attachedToView ? view->y : 0); + //DSGM_Debug("S s %d, l %d", background->screen, background->layer); + } + } + } +} + +inline BgSize DSGM_GetBGSize(u8 screen, int layer) { + return bgState[layer + ((screen == DSGM_BOTTOM) * 4)].size; +} + +int DSGM_GetBGWidth(u8 screen, int layer) { + switch(DSGM_GetBGSize(screen, layer)) { + case BgSize_T_256x256: + case BgSize_T_256x512: + return 256; + break; + + case BgSize_T_512x256: + case BgSize_T_512x512: + return 512; + break; + + default: + break; + } + return 512; +} + +int DSGM_GetBGHeight(u8 screen, int layer) { + switch(DSGM_GetBGSize(screen, layer)) { + case BgSize_T_256x256: + case BgSize_T_512x256: + return 256; + break; + + case BgSize_T_256x512: + case BgSize_T_512x512: + return 512; + break; + + default: + break; + } + return 512; +} + +//inline u16 DSGM_GetTile(u8 screen, int layer, int x, int y) { +inline u16 DSGM_GetTile(DSGM_BackgroundInstance *background, int x, int y) { + while(y > 31) { + y -= 32; + x += 64; + } + //x += 64 * ((y - 31) / 32); + //y %= 32; + while(x > 31) { + x -= 32; + y += 32; + } + //y += 64 * ((y - 31) / 32); + //x %= 32; + //int t = y * DSGM_GetBGWidth(screen, layer) / 16 + x; + //return bgGetMapPtr(background->vramId)[y * DSGM_GetBGWidth(screen, layer) / 16 + x]; + return bgGetMapPtr(background->vramId)[y * DSGM_GetBGWidth(background->screen, background->layer) / 16 + x]; +} diff --git a/dsgmLib/source/DSGM_file.c b/dsgmLib/source/DSGM_file.c new file mode 100644 index 0000000..3b74210 --- /dev/null +++ b/dsgmLib/source/DSGM_file.c @@ -0,0 +1,62 @@ +#include "DSGM.h" + +size_t DSGM_GetFileLength(char *filename) { + FILE *f = NULL; + size_t s = 0; + + f = fopen(filename, "rb"); + if(!f) { + DSGM_Debug("Failed to open file!"); + } + + fseek(f, 0, SEEK_END); + s = ftell(f); + + fclose(f); + + return s; +} + +void DSGM_ReadFileManual(void *destination, int start, size_t length, char *filename) { + FILE *f = NULL; + + f = fopen(filename, "rb"); + if(!f) { + DSGM_Debug("Failed to open file!"); + } + + fseek(f, start, SEEK_SET); + + if(length != DSGM_AUTO_LENGTH) { + fread(destination, length, 1, f); + } + else { + fread(destination, DSGM_GetFileLength(filename), 1, f); + } + + fclose(f); +} + +char *DSGM_ReadFile(char *filename) { + FILE *f = NULL; + size_t s = 0; + char *destination = NULL; + + f = fopen(filename, "rb"); + if(!f) { + DSGM_Debug("Failed to open file!"); + } + + fseek(f, 0, SEEK_END); + s = ftell(f); + rewind(f); + + destination = DSGM_Alloc(s + 1); + + fread(destination, s, 1, f); + fclose(f); + + destination[s] = '\0'; + + return destination; +} diff --git a/dsgmLib/source/DSGM_input.c b/dsgmLib/source/DSGM_input.c new file mode 100644 index 0000000..3b0a4e7 --- /dev/null +++ b/dsgmLib/source/DSGM_input.c @@ -0,0 +1,36 @@ +#include "DSGM.h" + +DSGM_Input DSGM_newpress, DSGM_held, DSGM_release; +touchPosition DSGM_stylus; + +void DSGM_UpdateInput(void) { + scanKeys(); + + int newpress = keysDown(); + int held = keysHeld(); + int release = keysUp(); + + touchRead(&DSGM_stylus); + + #define MAP_KEY(DSGMKey, libndsKey)\ + DSGM_newpress.DSGMKey = (newpress & libndsKey);\ + DSGM_held.DSGMKey = (held & libndsKey);\ + DSGM_release.DSGMKey = (release & libndsKey) + + MAP_KEY(A, KEY_A); + MAP_KEY(B, KEY_B); + MAP_KEY(Select, KEY_SELECT); + MAP_KEY(Start, KEY_START); + MAP_KEY(Right, KEY_RIGHT); + MAP_KEY(Left, KEY_LEFT); + MAP_KEY(Up, KEY_UP); + MAP_KEY(Down, KEY_DOWN); + MAP_KEY(R, KEY_R); + MAP_KEY(L, KEY_L); + MAP_KEY(X, KEY_X); + MAP_KEY(Y, KEY_Y); + MAP_KEY(Touch, KEY_TOUCH); + MAP_KEY(Lid, KEY_LID); + + #undef MAP_KEY +} diff --git a/dsgmLib/source/DSGM_malloc.c b/dsgmLib/source/DSGM_malloc.c new file mode 100644 index 0000000..c50a919 --- /dev/null +++ b/dsgmLib/source/DSGM_malloc.c @@ -0,0 +1,48 @@ +#include "DSGM.h" + +DSGM_Heap DSGM_toFree[DSGM_ALLOCATION_LIMIT]; +int DSGM_toFreeCount = 0; + +void *DSGM_TrackedAlloc(void **tracker, size_t length) { + if(DSGM_toFreeCount == DSGM_ALLOCATION_LIMIT) { + DSGM_Debug("Too many allocations!"); + return NULL; + } + + void *data = malloc(length); + *tracker = data; + DSGM_toFree[DSGM_toFreeCount].memory = tracker; + DSGM_toFree[DSGM_toFreeCount].tracked = true; + DSGM_toFreeCount++; + + return data; +} + +void *DSGM_Alloc(size_t length) { + if(DSGM_toFreeCount == DSGM_ALLOCATION_LIMIT) { + DSGM_Debug("Too many allocations!"); + return NULL; + } + + void *data = malloc(length); + DSGM_toFree[DSGM_toFreeCount].memory = data; + DSGM_toFree[DSGM_toFreeCount].tracked = false; + DSGM_toFreeCount++; + + return data; +} + +void DSGM_FreeAll(void) { + int i; + for(i = 0; i < DSGM_toFreeCount; i++) { + if(DSGM_toFree[i].tracked) { + free(*DSGM_toFree[i].memory); + *DSGM_toFree[i].memory = NULL; + } + else { + free(DSGM_toFree[i].memory); + DSGM_toFree[i].memory = NULL; + } + } + DSGM_toFreeCount = 0; +} diff --git a/dsgmLib/source/DSGM_object.c b/dsgmLib/source/DSGM_object.c new file mode 100644 index 0000000..f6b6494 --- /dev/null +++ b/dsgmLib/source/DSGM_object.c @@ -0,0 +1,107 @@ +#include "DSGM.h" + +void DSGM_SetupObjectGroups(DSGM_Room *room, u8 screen, int objectGroupCount) { + room->objectGroupCount[screen] = objectGroupCount; + if(objectGroupCount > 0) { + DSGM_Debug("Allocating %d object group(s) on %s screen\n", objectGroupCount, screen == DSGM_TOP ? "top" : "bottom"); + room->objectGroups[screen] = malloc(objectGroupCount * sizeof(DSGM_ObjectGroup)); + DSGM_Debug("Address %p was given\n", room->objectGroups[screen]); + } + else room->objectGroups[screen] = NULL; +} + +void DSGM_SetupObjectInstances(DSGM_ObjectGroup *group, DSGM_Object *object, u8 screen, int objectInstanceCount, ...) { + va_list properties; + int i; + group->objectInstanceCount = objectInstanceCount; + if(objectInstanceCount > 0) { + DSGM_Debug("Allocating %d object instance(s) on %s screen\n", objectInstanceCount, screen == DSGM_TOP ? "top" : "bottom"); + group->objectInstances = malloc(objectInstanceCount * sizeof(DSGM_ObjectInstance)); + DSGM_Debug("Address %p was given\n", group->objectInstances); + } + else group->objectInstances = NULL; + va_start(properties, objectInstanceCount); + for(i = 0; i < objectInstanceCount; i++) { + group->objectInstances[i].object = object; + group->objectInstances[i].screen = screen; + group->objectInstances[i].x = va_arg(properties, int); + group->objectInstances[i].y = va_arg(properties, int); + group->objectInstances[i].spriteNumber = 0; + group->objectInstances[i].frame = 0; + group->objectInstances[i].animationTimer = 0; + group->objectInstances[i].hFlip = false; + group->objectInstances[i].vFlip = false; + group->objectInstances[i].angle = NULL; + group->objectInstances[i].hide = false; + } + va_end(properties); +} + +DSGM_ObjectGroup *DSGM_GetObjectGroupFull(DSGM_Room *room, u8 screen, DSGM_Object *object) { + int i; + for(i = 0; i < room->objectGroupCount[screen]; i++) { + if(room->objectGroups[screen][i].objectInstanceCount > 0) { + if(room->objectGroups[screen][i].objectInstances[0].object == object) return &room->objectGroups[screen][i]; + } + } + return NULL; +} + +void DSGM_AddCollisionEvent(DSGM_Object *object, DSGM_Object *collider, DSGM_CollisionEventFunction function) { + DSGM_Debug("Adding collision event\n"); + object->collisionEvents = realloc(object->collisionEvents, (object->collisionEventCount + 1) * sizeof(DSGM_CollisionEvent)); + object->collisionEvents[object->collisionEventCount].collider = collider; + object->collisionEvents[object->collisionEventCount].function = function; + object->collisionEventCount++; +} + +inline bool DSGM_StylusOverObjectInstanceFull(DSGM_Room *room, DSGM_ObjectInstance *me) { + return DSGM_stylus.px >= me->x - room->view[me->screen].x && DSGM_stylus.px <= me->x - room->view[me->screen].x + DSGM_GetSpriteWidth(me->object->sprite) && DSGM_stylus.py >= me->y - room->view[me->screen].y && DSGM_stylus.py <= me->y - room->view[me->screen].y + DSGM_GetSpriteHeight(me->object->sprite); +} + +inline bool DSGM_ObjectInstanceCollision(DSGM_ObjectInstance *me, DSGM_ObjectInstance *collider) { + int w1 = DSGM_GetSpriteWidth(me->object->sprite); + int w2 = DSGM_GetSpriteWidth(collider->object->sprite); + int h1 = DSGM_GetSpriteHeight(me->object->sprite); + int h2 = DSGM_GetSpriteHeight(collider->object->sprite); + + return ((collider->x > me->x - w2) && (collider->x < me->x + w1)) && ((collider->y > me->y - h2) && (collider->y < me->y + h1)); +} + +inline int DSGM_GetObjectInstanceRotset(DSGM_ObjectInstance *me) { + return ((unsigned int)me->angle - (unsigned int)DSGM_rotations[me->screen]) / sizeof(me->angle); +} + +void DSGM_InitObjectInstanceRotation(DSGM_ObjectInstance *me) { + int rotset = DSGM_NextFreeRotset(me->screen); + me->angle = &DSGM_rotations[me->screen][rotset]; + (me->screen == DSGM_TOP ? oamMain : oamSub).oamMemory[me->spriteNumber].rotationIndex = rotset; + (me->screen == DSGM_TOP ? oamMain : oamSub).oamMemory[me->spriteNumber].isSizeDouble = true; + (me->screen == DSGM_TOP ? oamMain : oamSub).oamMemory[me->spriteNumber].isRotateScale = true; +} + +void DSGM_InitSharedObjectInstanceRotation(DSGM_ObjectInstance *me, int rotset) { + me->angle = &DSGM_rotations[me->screen][rotset]; + (me->screen == DSGM_TOP ? oamMain : oamSub).oamMemory[me->spriteNumber].rotationIndex = rotset; + (me->screen == DSGM_TOP ? oamMain : oamSub).oamMemory[me->spriteNumber].isSizeDouble = true; + (me->screen == DSGM_TOP ? oamMain : oamSub).oamMemory[me->spriteNumber].isRotateScale = true; +} + +void DSGM_AnimateObjectInstance(DSGM_ObjectInstance *me, int startFrame, int endFrame, int frequency) { + me->animationTimer++; + if(me->animationTimer == frequency) { + if(me->frame > endFrame || me->frame < startFrame) me->frame = startFrame; + if(me->frame < endFrame) me->frame++; + else me->frame = startFrame; + me->animationTimer = 0; + } +} + +void DSGM_ReturnAnimateObjectInstance(DSGM_ObjectInstance *me, int returnFrame, int startFrame, int endFrame, int frequency) { + me->animationTimer++; + if((me->animationTimer % (frequency / 2)) == 0) me->frame = returnFrame; + if((me->animationTimer % frequency) == 0) { + if(startFrame + me->animationTimer / frequency > endFrame) me->animationTimer = 0; + me->frame = startFrame + me->animationTimer / frequency; + } +} diff --git a/dsgmLib/source/DSGM_palette.c b/dsgmLib/source/DSGM_palette.c new file mode 100644 index 0000000..abb24b2 --- /dev/null +++ b/dsgmLib/source/DSGM_palette.c @@ -0,0 +1,65 @@ +#include "DSGM.h" + +int DSGM_nextPalette[2] = { 0, 0 }; + +void DSGM_UnlockSpritePalette(u8 screen) { + switch(screen) { + case DSGM_TOP: + vramSetBankF(VRAM_F_LCD); + break; + + case DSGM_BOTTOM: + vramSetBankI(VRAM_I_LCD); + break; + } +} + +void DSGM_LockSpritePalette(u8 screen) { + switch(screen) { + case DSGM_TOP: + vramSetBankF(VRAM_F_SPRITE_EXT_PALETTE); + break; + + case DSGM_BOTTOM: + vramSetBankI(VRAM_I_SUB_SPRITE_EXT_PALETTE); + break; + } +} + +inline int DSGM_NextFreePalette(u8 screen) { + return DSGM_nextPalette[screen]++; +} + +inline bool DSGM_PaletteLoaded(u8 screen, DSGM_Palette *palette) { + return palette->paletteNumber[screen] != DSGM_NO_PALETTE; +} + +inline bool DSGM_PaletteIsNitro(DSGM_Palette *palette) { + return !palette->palette; +} + +void DSGM_ClearPalettes(DSGM_Palette *palettes, int paletteCount) { + int i; + + DSGM_nextPalette[DSGM_TOP] = 0; + DSGM_nextPalette[DSGM_BOTTOM] = 0; + + for(i = 0; i < paletteCount; i++) { + palettes[i].paletteNumber[DSGM_TOP] = DSGM_NO_PALETTE; + palettes[i].paletteNumber[DSGM_BOTTOM] = DSGM_NO_PALETTE; + } +} + +void DSGM_LoadPaletteFull(u8 screen, DSGM_Palette *palette) { + DSGM_UnlockSpritePalette(screen); + palette->paletteNumber[screen] = DSGM_NextFreePalette(screen); + if(DSGM_PaletteIsNitro(palette)) { + if(screen == DSGM_TOP) DSGM_ReadFileManual(VRAM_F_EXT_SPR_PALETTE[palette->paletteNumber[screen]], 0, DSGM_AUTO_LENGTH, palette->nitroFilename); + if(screen == DSGM_BOTTOM) DSGM_ReadFileManual(VRAM_I_EXT_SPR_PALETTE[palette->paletteNumber[screen]], 0, DSGM_AUTO_LENGTH, palette->nitroFilename); + } + else { + if(screen == DSGM_TOP) dmaCopy(palette, VRAM_F_EXT_SPR_PALETTE[palette->paletteNumber[screen]], *palette->paletteLength); + if(screen == DSGM_BOTTOM) dmaCopy(palette, VRAM_I_EXT_SPR_PALETTE[palette->paletteNumber[screen]], *palette->paletteLength); + } + DSGM_LockSpritePalette(screen); +} diff --git a/dsgmLib/source/DSGM_room.c b/dsgmLib/source/DSGM_room.c new file mode 100644 index 0000000..0848458 --- /dev/null +++ b/dsgmLib/source/DSGM_room.c @@ -0,0 +1,204 @@ +#include "DSGM.h" + +void DSGM_SetupViews(DSGM_Room *room) { + room->view[DSGM_TOP].x = room->initialView[DSGM_TOP].x; + room->view[DSGM_BOTTOM].x = room->initialView[DSGM_BOTTOM].x; + room->view[DSGM_TOP].y = room->initialView[DSGM_TOP].y; + room->view[DSGM_BOTTOM].y = room->initialView[DSGM_BOTTOM].y; +} + +void DSGM_LoadRoom(DSGM_Room *room) { + u8 screen; + int layer; + int group; + int object; + + DSGM_Debug("Loading room...\n"); + + for(screen = 0; screen < 2; screen++) { + // Load backgrounds + for(layer = 0; layer < 4; layer++) { + if(room->backgroundInstances[screen][layer].background != DSGM_NO_BACKGROUND) { + DSGM_Debug("Screen %d, layer %d, background %p\n", screen, layer, room->backgroundInstances[screen][layer].background); + if(room->backgroundInstances[screen][layer].background == DSGM_TEXT_BACKGROUND) DSGM_InitText(&room->backgroundInstances[screen][layer]); + else DSGM_LoadBackgroundFull(&room->backgroundInstances[screen][layer]); + DSGM_ScrollBackgroundFull(&room->view[screen], &room->backgroundInstances[screen][layer]); + bgUpdate(); + } + } + } + + for(screen = 0; screen < 2; screen++) { + // Load sprites (all DSGM_ObjectInstances who have a sprite) + for(group = 0; group < room->objectGroupCount[screen]; group++) { + for(object = 0; object < room->objectGroups[screen][group].objectInstanceCount; object++) { + DSGM_ObjectInstance *objectInstance = &room->objectGroups[screen][group].objectInstances[object]; + DSGM_Sprite *sprite = objectInstance->object->sprite; + DSGM_Palette *palette = sprite->palette; + int spriteNumber = -1; + + if(sprite != DSGM_NO_SPRITE) { + spriteNumber = DSGM_NextFreeSpriteNumber(screen); + objectInstance->spriteNumber = spriteNumber; + objectInstance->screen = screen; + + if(!DSGM_PaletteLoaded(screen, palette)) { + DSGM_LoadPaletteFull(screen, palette); + } + + if(!DSGM_SpriteLoaded(screen, sprite)) { + DSGM_LoadSpriteFull(screen, sprite); + } + + int x = objectInstance->x - room->view[screen].x; + int y = objectInstance->y - room->view[screen].y; + if(x < 256 && x > -128 && y < 192 && y > -128 && !objectInstance->hide) { + x = objectInstance->angle ? x - DSGM_GetSpriteWidth(objectInstance->object->sprite) / 2 : x; + y = objectInstance->angle ? y - DSGM_GetSpriteHeight(objectInstance->object->sprite) / 2 : y; + } + else { + x = 255; + y = 191; + } + + // Run create event before creating sprite so the create event can change the position, frame, flipping, etc... + if(objectInstance->object->create) objectInstance->object->create(objectInstance); + + DSGM_CreateSprite(screen, spriteNumber, x, y, objectInstance->priority, objectInstance->frame, objectInstance->hFlip, objectInstance->vFlip, sprite); + } + } + } + } + + DSGM_Debug("Loaded\n"); +} + +//int res = 0; + +void DSGM_LoopRoom(DSGM_Room *room) { + u8 screen; + int layer; + int group; + int object; + int sound; + int rotset; + + //if(!res) { + // mmStop(); + // mmStart(/*DSGM_Sounds[FlatOutLies].ID*/0, MM_PLAY_LOOP); + // res = 1; + //} + + //+1? + for(sound = 0; sound < DSGM_soundInstanceCount; sound++) { + DSGM_SetSoundInstanceVolumeFull(&DSGM_soundInstances[sound], DSGM_soundInstances[sound].volume); + DSGM_SetSoundInstancePanningFull(&DSGM_soundInstances[sound], DSGM_soundInstances[sound].panning); + } + + for(screen = 0; screen < 2; screen++) { + for(layer = 0; layer < 4; layer++) { + if(room->backgroundInstances[screen][layer].background != DSGM_NO_BACKGROUND) { + DSGM_ScrollBackgroundFull(&room->view[screen], &room->backgroundInstances[screen][layer]); + } + } + + for(rotset = 0; rotset < 32; rotset++) { + DSGM_SetRotsetRotation(screen, rotset, DSGM_rotations[screen][rotset]); + } + + //DSGM_Debug("Group count %d\n", room->objectGroupCount[screen]); + for(group = 0; group < room->objectGroupCount[screen]; group++) { + for(object = 0; object < room->objectGroups[screen][group].objectInstanceCount; object++) { + DSGM_ObjectInstance *objectInstance = &room->objectGroups[screen][group].objectInstances[object]; + + int x = objectInstance->x - room->view[screen].x; + int y = objectInstance->y - room->view[screen].y; + if(x < 256 && x > -128 && y < 192 && y > -128 && !objectInstance->hide) DSGM_SetSpriteXY(screen, objectInstance->spriteNumber, objectInstance->angle ? x - DSGM_GetSpriteWidth(objectInstance->object->sprite) / 2 : x, objectInstance->angle ? y - DSGM_GetSpriteHeight(objectInstance->object->sprite) / 2 : y); + else DSGM_SetSpriteXY(screen, objectInstance->spriteNumber, 255, 191); + DSGM_SetSpriteFrame(screen, objectInstance->spriteNumber, objectInstance->object->sprite, objectInstance->frame); + DSGM_SetSpriteHFlip(screen, objectInstance->spriteNumber, objectInstance->hFlip); + DSGM_SetSpriteVFlip(screen, objectInstance->spriteNumber, objectInstance->vFlip); + DSGM_SetSpritePriority(screen, objectInstance->spriteNumber, objectInstance->priority); + + if(objectInstance->object->loop) objectInstance->object->loop(objectInstance); + + if(screen == DSGM_BOTTOM && objectInstance->object->touch) { + if(DSGM_newpress.Touch && DSGM_StylusOverObjectInstanceFull(room, objectInstance)) objectInstance->object->touch(objectInstance); + } + + int collisionEvent; + for(collisionEvent = 0; collisionEvent < objectInstance->object->collisionEventCount; collisionEvent++) { + int collider; + DSGM_ObjectGroup *colliderGroup = DSGM_GetObjectGroupFull(room, screen, objectInstance->object->collisionEvents[collisionEvent].collider); + for(collider = 0; collider < colliderGroup->objectInstanceCount; collider++) { + if(DSGM_ObjectInstanceCollision(objectInstance, &colliderGroup->objectInstances[collider])) { + objectInstance->object->collisionEvents[collisionEvent].function(objectInstance, &colliderGroup->objectInstances[collider]); + } + } + } + } + } + } + + //if(!res) { + // mmStop(); + // mmStart(/*DSGM_Sounds[FlatOutLies].ID*/0, MM_PLAY_LOOP); + // res = 1; + //} +} + +void DSGM_LeaveRoom(DSGM_Room *room) { + DSGM_Debug("Leaving room\n"); + + u8 screen; + int group; + + for(screen = 0; screen < 2; screen++) { + for(group = 0; group < room->objectGroupCount[screen]; group++) { + DSGM_Debug("Freeing object events at %p\n", room->objectGroups[screen][group].objectInstances[0].object->collisionEvents); + free(room->objectGroups[screen][group].objectInstances[0].object->collisionEvents); + room->objectGroups[screen][group].objectInstances[0].object->collisionEvents = NULL; + room->objectGroups[screen][group].objectInstances[0].object->collisionEventCount = 0; + DSGM_Debug("Freeing object instances at address %p on %s screen\n", room->objectGroups[screen][group].objectInstances, screen == DSGM_TOP ? "top" : "bottom"); + free(room->objectGroups[screen][group].objectInstances); + } + + DSGM_Debug("Freeing object groups at address %p on %s screen\n", room->objectGroups[screen], screen == DSGM_TOP ? "top" : "bottom"); + free(room->objectGroups[screen]); + } +} + +unsigned char DSGM_SaveRoom(DSGM_Room *room, char *filename) { + /*u8 screen; + int layer; + int group; + int object; + FILE *f = fopen(filename, "ab"); + if(!f) return 0; + + DSGM_Debug("Saving room...\n"); + + for(screen = 0; screen < 2; screen++) { + // Save backgrounds + for(layer = 0; layer < 4; layer++) { + // Store pointer to background + fwrite(&room->backgroundInstances[screen][layer].background, sizeof(DSGM_Background *), 1, f) { + } + } + + for(screen = 0; screen < 2; screen++) { + // Save object instances + for(group = 0; group < room->objectGroupCount[screen]; group++) { + for(object = 0; object < room->objectGroups[screen][group].objectInstanceCount; object++) { + DSGM_ObjectInstance *objectInstance = &room->objectGroups[screen][group].objectInstances[object]; + fwrite(objectInstance, sizeof(DSGM_ObjectInstance), 1, f); + } + } + } + + fclose(f); + + DSGM_Debug("Saved\n");*/ + + return 1; +} diff --git a/dsgmLib/source/DSGM_saving.c b/dsgmLib/source/DSGM_saving.c new file mode 100644 index 0000000..e69de29 diff --git a/dsgmLib/source/DSGM_sound.c b/dsgmLib/source/DSGM_sound.c new file mode 100644 index 0000000..aa2efb0 --- /dev/null +++ b/dsgmLib/source/DSGM_sound.c @@ -0,0 +1,100 @@ +#include "DSGM.h" + +int DSGM_soundStreamCount = 0; + +DSGM_SoundInstance DSGM_soundInstances[DSGM_MAX_SOUNDS]; +int DSGM_soundInstanceCount = 0; + +void DSGM_InitSoundFull(int soundStreamCount) { + mmInitDefault("nitro:/soundbank.bin"); + DSGM_soundStreamCount = soundStreamCount; +} + +void DSGM_ResetSound(void) { + /*mmStop(); + mmEffectCancelAll(); + + int i; + for(i = 0; i < DSGM_soundInstanceCount; i++) { + if(DSGM_soundInstances[i].sound->type == DSGM_SOUND_STREAM) { + // MaxMod is broken :( + //mmUnload(DSGM_soundInstances[i].sound->ID); + //DSGM_soundInstances[i].sound->loaded = false; + } + else { + //mmUnloadEffect(DSGM_soundInstances[i].sound->ID - DSGM_soundStreamCount); + //DSGM_soundInstances[i].sound->loaded = false; + } + } + + DSGM_soundInstanceCount = 0;*/ +} + +DSGM_SoundInstance *DSGM_AddSoundInstance(DSGM_Sound *sound) { + // still playing? + if(DSGM_soundInstanceCount == DSGM_MAX_SOUNDS) DSGM_soundInstanceCount = sound->type == DSGM_SOUND_STREAM ? 0 : DSGM_RESERVED_STREAMS; + return &DSGM_soundInstances[DSGM_soundInstanceCount++]; +} + +DSGM_SoundInstance *DSGM_PlaySoundFull(DSGM_Sound *sound) { + DSGM_SoundInstance *soundInstance = DSGM_AddSoundInstance(sound); + + if(sound->type == DSGM_SOUND_STREAM) { + if(!sound->loaded) { + mmLoad(sound->ID); + sound->loaded = true; + } + mmStart(sound->ID, MM_PLAY_LOOP); + } + else { + if(!sound->loaded) { + mmLoadEffect(sound->ID - DSGM_soundStreamCount); + sound->loaded = true; + } + soundInstance->effectNumber = mmEffect(sound->ID - DSGM_soundStreamCount); + mmEffectRelease(soundInstance->effectNumber); + } + + soundInstance->volume = 255; + soundInstance->panning = 128; + + return soundInstance; +} + +DSGM_SoundInstance *DSGM_PlaySoundAdvancedFull(DSGM_Sound *sound, u8 volume, u8 panning) { + DSGM_SoundInstance *soundInstance = DSGM_AddSoundInstance(sound); + + if(sound->type == DSGM_SOUND_STREAM) { + if(!sound->loaded) { + mmLoad(sound->ID); + sound->loaded = true; + } + mmStart(sound->ID, MM_PLAY_LOOP); + } + else { + if(!sound->loaded) { + mmLoadEffect(sound->ID - DSGM_soundStreamCount); + sound->loaded = true; + } + mm_sound_effect effect = { + { sound->ID - DSGM_soundStreamCount } , + (int)(1.0f * (1<<10)), // rate + 0, // handle + soundInstance->volume = volume, // volume (255 = max) + soundInstance->panning = panning, // panning (128 = center) + }; + soundInstance->effectNumber = mmEffectEx(&effect); + mmEffectRelease(soundInstance->effectNumber); + } + + return soundInstance; +} + +void DSGM_SetSoundInstanceVolumeFull(DSGM_SoundInstance *soundInstance, int volume) { + if(soundInstance->sound->type == DSGM_SOUND_STREAM) mmSetModuleVolume(volume); + if(soundInstance->sound->type == DSGM_SOUND_EFFECT) mmEffectVolume(soundInstance->effectNumber, volume); +} + +void DSGM_SetSoundInstancePanningFull(DSGM_SoundInstance *soundInstance, int panning) { + if(soundInstance->sound->type == DSGM_SOUND_EFFECT) mmEffectPanning(soundInstance->effectNumber, panning); +} diff --git a/dsgmLib/source/DSGM_sprite.c b/dsgmLib/source/DSGM_sprite.c new file mode 100644 index 0000000..5738d0d --- /dev/null +++ b/dsgmLib/source/DSGM_sprite.c @@ -0,0 +1,168 @@ +#include "DSGM.h" + +/* + oam->oamMemory[id].shape = SPRITE_SIZE_SHAPE(size); + oam->oamMemory[id].size = SPRITE_SIZE_SIZE(size); + oam->oamMemory[id].x = x; + oam->oamMemory[id].y = y; + oam->oamMemory[id].palette = palette_alpha; + oam->oamMemory[id].priority = priority; + oam->oamMemory[id].hFlip = hflip; + oam->oamMemory[id].vFlip = vflip; + oam->oamMemory[id].isMosaic = mosaic; + oam->oamMemory[id].gfxIndex = oamGfxPtrToOffset(oam, gfxOffset); +*/ + +int DSGM_nextFreeSprite[2] = { 0, 0 }; +int DSGM_nextFreeRotset[2] = { 0, 0 }; + +int DSGM_rotations[2][32]; + +const DSGM_Size DSGM_Sizes[3][4] = {{{8, 8}, {16, 16}, {32, 32}, {64, 64}}, {{16, 8}, {32, 8}, {32, 16}, {64, 32}}, {{8, 16}, {8, 32}, {16, 32}, {32, 64}}}; + +inline int DSGM_NextFreeSpriteNumber(u8 screen) { + return DSGM_nextFreeSprite[screen]++; +} + +inline int DSGM_NextFreeRotset(u8 screen) { + return DSGM_nextFreeRotset[screen]++; +} + +inline int DSGM_GetSpriteWidth(DSGM_Sprite *sprite) { + u16 atr0 = SPRITE_SIZE_SHAPE(sprite->size); + u16 atr1 = SPRITE_SIZE_SIZE(sprite->size); + return DSGM_Sizes[atr0][atr1].width; +} + +inline int DSGM_GetSpriteHeight(DSGM_Sprite *sprite) { + u16 atr0 = SPRITE_SIZE_SHAPE(sprite->size); + u16 atr1 = SPRITE_SIZE_SIZE(sprite->size); + return DSGM_Sizes[atr0][atr1].width; +} + +inline bool DSGM_SpriteIsNitro(DSGM_Sprite *sprite) { + return !sprite->tiles; +} + +inline bool DSGM_SpriteLoaded(u8 screen, DSGM_Sprite *sprite) { + if(screen == DSGM_TOP) return sprite->topTiles != NULL; + else return sprite->bottomTiles != NULL; +} + +void DSGM_ResetSprites(DSGM_Sprite *sprites, int spriteCount) { + int i, j; + for(i = 0; i < spriteCount; i++) { + if(sprites[i].topTiles) { + for(j = 0; j < sprites[i].frames; j++) { + oamFreeGfx(&oamMain, sprites[i].topTiles[j]); + sprites[i].topTiles[j] = NULL; + } + free(sprites[i].topTiles); + sprites[i].topTiles = NULL; + } + + if(sprites[i].bottomTiles) { + for(j = 0; j < sprites[i].frames; j++) { + oamFreeGfx(&oamSub, sprites[i].bottomTiles[j]); + sprites[i].bottomTiles[j] = NULL; + } + free(sprites[i].bottomTiles); + sprites[i].bottomTiles = NULL; + } + } + + for(i = 0; i < 32; i++) { + DSGM_rotations[DSGM_TOP][i] = 0; + DSGM_rotations[DSGM_BOTTOM][i] = 0; + } + + DSGM_nextFreeSprite[DSGM_TOP] = 0; + DSGM_nextFreeSprite[DSGM_BOTTOM] = 0; + DSGM_nextFreeRotset[DSGM_TOP] = 0; + DSGM_nextFreeRotset[DSGM_BOTTOM] = 0; + + for(i = 0; i < 128; i++) { + //oamSet(&oamMain, i, 0, 0, 0, 0, SpriteSize_32x32, SpriteColorFormat_256Color, NULL, -1, false, true, false, false, false); + //oamSet(&oamSub, i, 0, 0, 0, 0, SpriteSize_32x32, SpriteColorFormat_256Color, NULL, -1, false, true, false, false, false); + } +} + +void DSGM_LoadSpriteFull(u8 screen, DSGM_Sprite *sprite) { + int i; + switch(screen) { + case DSGM_TOP: + //sprite->topTiles = DSGM_TrackedAlloc((void **)&sprite->topTiles, sizeof(u16 *) * sprite->frames); + sprite->topTiles = malloc(sizeof(u16 *) * sprite->frames); + for(i = 0; i < sprite->frames; i++) { + sprite->topTiles[i] = oamAllocateGfx(&oamMain, sprite->size, SpriteColorFormat_256Color); + if(DSGM_SpriteIsNitro(sprite)) { + DSGM_ReadFileManual(sprite->topTiles[i], i * (DSGM_GetSpriteWidth(sprite) * DSGM_GetSpriteHeight(sprite)), DSGM_GetSpriteWidth(sprite) * DSGM_GetSpriteHeight(sprite)/*32 * 32*//*DSGM_AUTO_LENGTH*/, sprite->nitroFilename); + } + else { + dmaCopy(sprite->tiles + (i * DSGM_GetSpriteWidth(sprite) * DSGM_GetSpriteHeight(sprite)), sprite->topTiles[i], *sprite->tilesLength); + } + } + break; + + case DSGM_BOTTOM: + //sprite->bottomTiles = DSGM_TrackedAlloc((void **)&sprite->bottomTiles, sizeof(u16 *) * sprite->frames); + sprite->bottomTiles = malloc(sizeof(u16 *) * sprite->frames); + for(i = 0; i < sprite->frames; i++) { + sprite->bottomTiles[i] = oamAllocateGfx(&oamSub, sprite->size, SpriteColorFormat_256Color); + if(DSGM_SpriteIsNitro(sprite)) { + DSGM_ReadFileManual(sprite->bottomTiles[i], i * (DSGM_GetSpriteWidth(sprite) * DSGM_GetSpriteHeight(sprite)), DSGM_GetSpriteWidth(sprite) * DSGM_GetSpriteHeight(sprite)/*DSGM_AUTO_LENGTH*/, sprite->nitroFilename); + } + else { + dmaCopy(sprite->tiles + (i * DSGM_GetSpriteWidth(sprite) * DSGM_GetSpriteHeight(sprite)), sprite->bottomTiles[i], *sprite->tilesLength); + } + } + break; + } +} + +void DSGM_CreateSprite(u8 screen, int spriteNumber, int x, int y, ObjPriority priority, int frame, bool hFlip, bool vFlip, DSGM_Sprite *sprite) { + //oamSet(screen == DSGM_TOP ? &oamMain : &oamSub, spriteNumber, 255, 191, 0, sprite->palette->paletteNumber[screen], sprite->size, SpriteColorFormat_256Color, screen == DSGM_TOP ? sprite->topTiles[0] : sprite->bottomTiles[0], -1, false, false, false, false, false); + //swiWaitForVBlank(); + //oamUpdate(screen == DSGM_TOP ? &oamMain : &oamSub); + //DSGM_SetSpriteXY(screen, spriteNumber, x, y); + oamSet(screen == DSGM_TOP ? &oamMain : &oamSub, spriteNumber, x, y, priority, sprite->palette->paletteNumber[screen], sprite->size, SpriteColorFormat_256Color, screen == DSGM_TOP ? sprite->topTiles[frame] : sprite->bottomTiles[frame], -1, false, false, hFlip, vFlip, false); + oamUpdate(screen == DSGM_TOP ? &oamMain : &oamSub); +} + +void DSGM_SetSpriteXY(u8 screen, int spriteNumber, int x, int y) { + switch(screen) { + case DSGM_TOP: + oamMain.oamMemory[spriteNumber].x = x; + oamMain.oamMemory[spriteNumber].y = y; + break; + + case DSGM_BOTTOM: + oamSub.oamMemory[spriteNumber].x = x; + oamSub.oamMemory[spriteNumber].y = y; + break; + } +} + +void DSGM_SetSpriteFrame(u8 screen, int spriteNumber, DSGM_Sprite *sprite, u8 frame) { + if(screen == DSGM_TOP) oamMain.oamMemory[spriteNumber].gfxIndex = oamGfxPtrToOffset(&oamMain, sprite->topTiles[frame]); + if(screen == DSGM_BOTTOM) oamSub.oamMemory[spriteNumber].gfxIndex = oamGfxPtrToOffset(&oamSub, sprite->bottomTiles[frame]); +} + +void DSGM_SetSpriteHFlip(u8 screen, int spriteNumber, bool flip) { + if(screen == DSGM_TOP) oamMain.oamMemory[spriteNumber].hFlip = flip; + if(screen == DSGM_BOTTOM) oamSub.oamMemory[spriteNumber].hFlip = flip; +} + +void DSGM_SetSpriteVFlip(u8 screen, int spriteNumber, bool flip) { + if(screen == DSGM_TOP) oamMain.oamMemory[spriteNumber].vFlip = flip; + if(screen == DSGM_BOTTOM) oamSub.oamMemory[spriteNumber].vFlip = flip; +} + +void DSGM_SetSpritePriority(u8 screen, int spriteNumber, ObjPriority priority) { + if(screen == DSGM_TOP) oamMain.oamMemory[spriteNumber].priority = priority; + if(screen == DSGM_BOTTOM) oamSub.oamMemory[spriteNumber].priority = priority; +} + +void DSGM_SetRotsetRotation(u8 screen, int rotset, int angle) { + oamRotateScale(screen == DSGM_TOP ? &oamMain : &oamSub, rotset, angle, intToFixed(1, 8), intToFixed(1, 8)); +} diff --git a/dsgmLib/source/DSGM_text.c b/dsgmLib/source/DSGM_text.c new file mode 100644 index 0000000..ca6aba8 --- /dev/null +++ b/dsgmLib/source/DSGM_text.c @@ -0,0 +1,27 @@ +#include "DSGM.h" + +PrintConsole DSGM_text[2]; + +void DSGM_InitText(DSGM_BackgroundInstance *backgroundInstance) { + consoleInit(&DSGM_text[backgroundInstance->screen], backgroundInstance->layer, BgType_Text4bpp, BgSize_T_256x256, backgroundInstance->layer + 28, 0, backgroundInstance->screen, 1); + consoleSelect(&DSGM_text[backgroundInstance->screen]); + consoleClear(); + backgroundInstance->vramId = DSGM_text[backgroundInstance->screen].bgId; + DSGM_Debug("Init text screen %d, layer %d, vramId %d\n", backgroundInstance->screen, backgroundInstance->layer, DSGM_text[backgroundInstance->screen].bgId/*backgroundInstance->vramId*/); +} + +void DSGM_ClearText(u8 screen) { + consoleSelect(&DSGM_text[screen]); + consoleClear(); +} + +void DSGM_DrawText(u8 screen, int x, int y, const char *format, ...) { + consoleSelect(&DSGM_text[screen]); + DSGM_text[screen].cursorX = x; + DSGM_text[screen].cursorY = y; + + va_list arg; + va_start(arg, format); + vfprintf(stdout, format, arg); + va_end(arg); +} diff --git a/examples/Collision/Collision.nds b/examples/Collision/Collision.nds new file mode 100644 index 0000000..7280f1a Binary files /dev/null and b/examples/Collision/Collision.nds differ diff --git a/examples/Collision/Makefile b/examples/Collision/Makefile new file mode 100644 index 0000000..34daad2 --- /dev/null +++ b/examples/Collision/Makefile @@ -0,0 +1,143 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +include $(DEVKITARM)/ds_rules + +DSGMLibInclude := ../../DSGMLib/include +DSGMLibLib := ../../../DSGMLib/DSGMLib.a + +#--------------------------------------------------------------------------------- +# 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 +# MAXMOD_SOUNDBANK contains a directory of music and sound effect files +#--------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +INCLUDES := include $(DSGMLibInclude) +NITRODATA := nitrofiles +MAXMOD_SOUNDBANK := music + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -mthumb -mthumb-interwork -march=armv5te -mtune=arm946e-s + +CFLAGS := -g -Wall -O2\ + -fomit-frame-pointer\ + -ffast-math \ + $(ARCH) + +CFLAGS += $(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 := $(DSGMLibLib) -lfilesystem -lfat -lnds9 -lmm9 + + +#--------------------------------------------------------------------------------- +# 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)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +ifneq ($(strip $(NITRODATA)),) + export NITRO_FILES := $(CURDIR)/$(NITRODATA) +endif + +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)/*.*))) + +export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MAXMOD_SOUNDBANK)/*.*)),$(CURDIR)/$(MAXMOD_SOUNDBANK)/$(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) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds + +#--------------------------------------------------------------------------------- +else + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).nds : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) soundbank.h + +soundbank.h: ../$(NITRODATA)/soundbank.bin + +../$(NITRODATA)/soundbank.bin: $(AUDIOFILES) +#--------------------------------------------------------------------------------- + mmutil $^ -d -o../$(NITRODATA)/soundbank.bin -hsoundbank.h + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPSDIR)/*.d + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/examples/Collision/build.bat b/examples/Collision/build.bat new file mode 100644 index 0000000..8182ff5 --- /dev/null +++ b/examples/Collision/build.bat @@ -0,0 +1,2 @@ +make +pause \ No newline at end of file diff --git a/examples/Collision/include/project.h b/examples/Collision/include/project.h new file mode 100644 index 0000000..cf52971 --- /dev/null +++ b/examples/Collision/include/project.h @@ -0,0 +1,52 @@ +#pragma once + +#define DSGM_SOUND_STREAM_COUNT 0 +#define DSGM_SOUND_EFFECT_COUNT 0 +#define DSGM_SOUND_COUNT (DSGM_SOUND_STREAM_COUNT + DSGM_SOUND_EFFECT_COUNT) +#define DSGM_BACKGROUND_COUNT 0 +#define DSGM_PALETTE_COUNT 1 +#define DSGM_SPRITE_COUNT 2 +#define DSGM_OBJECT_COUNT 2 +#define DSGM_ROOM_COUNT 1 + +// Include backgrounds, palettes and sprites to be loaded from RAM + +// No sounds, no enum +//typedef enum { +//} DSGM_SoundNames; + +// No backgrounds, no enum +//typedef enum { +//} DSGM_BackgroundNames; + +typedef enum { + DSGMPal0, +} DSGM_PaletteNames; + +typedef enum { + taptapman, + ballSprite, +} DSGM_SpriteNames; + +typedef enum { + player, + ball, +} DSGM_ObjectNames; + +typedef enum { + Room_1, +} DSGM_RoomNames; + +extern DSGM_Sound DSGM_Sounds[DSGM_SOUND_COUNT]; +extern DSGM_Background DSGM_Backgrounds[DSGM_BACKGROUND_COUNT]; +extern DSGM_Palette DSGM_Palettes[DSGM_PALETTE_COUNT]; +extern DSGM_Sprite DSGM_Sprites[DSGM_SPRITE_COUNT]; +extern DSGM_Object DSGM_Objects[DSGM_OBJECT_COUNT]; +extern DSGM_Room DSGM_Rooms[DSGM_ROOM_COUNT]; + +extern int DSGM_currentRoom; + +void DSGM_SetupRooms(int room); + +void player_loop(DSGM_ObjectInstance *me); +void player_collide_ball(DSGM_ObjectInstance *me, DSGM_ObjectInstance *collider); diff --git a/examples/Collision/nitrofiles/DSGMPal0_Pal.bin b/examples/Collision/nitrofiles/DSGMPal0_Pal.bin new file mode 100644 index 0000000..30d7ec9 Binary files /dev/null and b/examples/Collision/nitrofiles/DSGMPal0_Pal.bin differ diff --git a/examples/Collision/nitrofiles/ball_Sprite.bin b/examples/Collision/nitrofiles/ball_Sprite.bin new file mode 100644 index 0000000..ed3e997 Binary files /dev/null and b/examples/Collision/nitrofiles/ball_Sprite.bin differ diff --git a/examples/Collision/nitrofiles/taptapman_Sprite.bin b/examples/Collision/nitrofiles/taptapman_Sprite.bin new file mode 100644 index 0000000..7ad7377 Binary files /dev/null and b/examples/Collision/nitrofiles/taptapman_Sprite.bin differ diff --git a/examples/Collision/source/main.c b/examples/Collision/source/main.c new file mode 100644 index 0000000..eff39e0 --- /dev/null +++ b/examples/Collision/source/main.c @@ -0,0 +1,17 @@ +#include "DSGM.h" + +void DSGM_Init(void); + +int main(int argc, char **argv) { + DSGM_Init(); + + DSGM_LoadRoom(&DSGM_Rooms[DSGM_currentRoom]); + + while(1) { + DSGM_LoopRoom(&DSGM_Rooms[DSGM_currentRoom]); + + DSGM_Update(); + } + + return 0; +} diff --git a/examples/Collision/source/project.c b/examples/Collision/source/project.c new file mode 100644 index 0000000..4d5be6a --- /dev/null +++ b/examples/Collision/source/project.c @@ -0,0 +1,218 @@ +#include "DSGM.h" + +#include "DSGM_projectHelper.h" + +// User variables / declarations +u8 direction = 0; + +// Resources +DSGM_Sound DSGM_Sounds[DSGM_SOUND_COUNT] = { +}; + +DSGM_Background DSGM_Backgrounds[DSGM_BACKGROUND_COUNT] = { +}; + +DSGM_Palette DSGM_Palettes[DSGM_PALETTE_COUNT] = { + DSGM_FORM_NITRO_PALETTE(DSGMPal0), +}; + +DSGM_Sprite DSGM_Sprites[DSGM_SPRITE_COUNT] = { + DSGM_FORM_NITRO_SPRITE(taptapman, DSGMPal0, SpriteSize_32x32, 9), + DSGM_FORM_NITRO_SPRITE(ball, DSGMPal0, SpriteSize_32x32, 1), +}; + +DSGM_Object DSGM_Objects[DSGM_OBJECT_COUNT] = { + // player + { + &DSGM_Sprites[taptapman], + DSGM_NO_EVENT, + player_loop, + DSGM_NO_EVENT, + DSGM_NO_EVENT, + + NULL, 0 + }, + // ball + { + &DSGM_Sprites[ballSprite], + DSGM_NO_EVENT, + DSGM_NO_EVENT, + DSGM_NO_EVENT, + DSGM_NO_EVENT, + + NULL, 0 + }, +}; + +DSGM_Room DSGM_Rooms[DSGM_ROOM_COUNT] = { + // Room_1 + { + // Backgrounds + { + // Bottom screen + { + // Layer 0 + { + DSGM_TEXT_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 0, // Layer + false, // Attached to view system + 0, 0, 0 + }, + + // Layer 1 + { + DSGM_NO_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 1, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 2 + { + DSGM_NO_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 2, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 3 + { + DSGM_NO_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 3, // Layer + true, // Attached to view system + 0, 0, 0 + }, + }, + + // Top screen + { + // Layer 0 + { + DSGM_TEXT_BACKGROUND, // Background + DSGM_TOP, // Screen + 0, // Layer + false, // Attached to view system + 0, 0, 0 + }, + + // Layer 1 + { + DSGM_NO_BACKGROUND, // Background + DSGM_TOP, // Screen + 1, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 2 + { + DSGM_NO_BACKGROUND, // Background + DSGM_TOP, // Screen + 2, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 3 + { + DSGM_NO_BACKGROUND, // Background + DSGM_TOP, // Screen + 3, // Layer + true, // Attached to view system + 0, 0, 0 + }, + } + }, + + // Initial views + { + // Bottom screen + { + 0, 0 + }, + + // Top screen + { + 0, 0 + } + }, + + // Views + { + // Bottom screen + { + 0, 0 + }, + + // Top screen + { + 0, 0 + } + }, + + // Object groups are dynamic, so must be set up at run time, see DSGM_SetupRooms. + { + NULL, + NULL + }, + { + 0, + 0 + } + }, +}; + +int DSGM_currentRoom = Room_1; + +void DSGM_SetupRooms(int room) { + if(room != DSGM_ALL_ROOMS) { + switch(room) { + case Room_1: goto Room_1; break; + } + } + + Room_1: + DSGM_Debug("Room_1 reset\n"); + DSGM_LeaveRoom(&DSGM_Rooms[Room_1]); + + DSGM_SetupViews(&DSGM_Rooms[Room_1]); + + DSGM_SetupObjectGroups(&DSGM_Rooms[Room_1], DSGM_TOP, 0); + + DSGM_SetupObjectGroups(&DSGM_Rooms[Room_1], DSGM_BOTTOM, 2); + + DSGM_SetupObjectInstances(&DSGM_Rooms[Room_1].objectGroups[DSGM_BOTTOM][0], &DSGM_Objects[player], DSGM_BOTTOM, 1, + 64, 64 + ); + + DSGM_SetupObjectInstances(&DSGM_Rooms[Room_1].objectGroups[DSGM_BOTTOM][1], &DSGM_Objects[ball], DSGM_BOTTOM, 2, + 120, 80, + 20, 50 + ); + + DSGM_AddCollisionEvent(&DSGM_Objects[player], &DSGM_Objects[ball], player_collide_ball); + + if(room != DSGM_ALL_ROOMS) return; +} + +void player_loop(DSGM_ObjectInstance *me) { + DSGM_ClearText(DSGM_BOTTOM); + + if(direction == 0) { + me->x++; + } + else { + me->x--; + } + + if(me->x == 223 || me->x == 0) direction = !direction; +} + +void player_collide_ball(DSGM_ObjectInstance *me, DSGM_ObjectInstance *collider) { + DSGM_DrawText(DSGM_BOTTOM, 1, 1, "Collision!"); + collider->y += 1; +} diff --git a/examples/Priority/Makefile b/examples/Priority/Makefile new file mode 100644 index 0000000..34daad2 --- /dev/null +++ b/examples/Priority/Makefile @@ -0,0 +1,143 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +include $(DEVKITARM)/ds_rules + +DSGMLibInclude := ../../DSGMLib/include +DSGMLibLib := ../../../DSGMLib/DSGMLib.a + +#--------------------------------------------------------------------------------- +# 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 +# MAXMOD_SOUNDBANK contains a directory of music and sound effect files +#--------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +INCLUDES := include $(DSGMLibInclude) +NITRODATA := nitrofiles +MAXMOD_SOUNDBANK := music + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -mthumb -mthumb-interwork -march=armv5te -mtune=arm946e-s + +CFLAGS := -g -Wall -O2\ + -fomit-frame-pointer\ + -ffast-math \ + $(ARCH) + +CFLAGS += $(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 := $(DSGMLibLib) -lfilesystem -lfat -lnds9 -lmm9 + + +#--------------------------------------------------------------------------------- +# 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)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +ifneq ($(strip $(NITRODATA)),) + export NITRO_FILES := $(CURDIR)/$(NITRODATA) +endif + +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)/*.*))) + +export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MAXMOD_SOUNDBANK)/*.*)),$(CURDIR)/$(MAXMOD_SOUNDBANK)/$(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) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds + +#--------------------------------------------------------------------------------- +else + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).nds : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) soundbank.h + +soundbank.h: ../$(NITRODATA)/soundbank.bin + +../$(NITRODATA)/soundbank.bin: $(AUDIOFILES) +#--------------------------------------------------------------------------------- + mmutil $^ -d -o../$(NITRODATA)/soundbank.bin -hsoundbank.h + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPSDIR)/*.d + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/examples/Priority/Priority.nds b/examples/Priority/Priority.nds new file mode 100644 index 0000000..daa0ea3 Binary files /dev/null and b/examples/Priority/Priority.nds differ diff --git a/examples/Priority/build.bat b/examples/Priority/build.bat new file mode 100644 index 0000000..8182ff5 --- /dev/null +++ b/examples/Priority/build.bat @@ -0,0 +1,2 @@ +make +pause \ No newline at end of file diff --git a/examples/Priority/include/project.h b/examples/Priority/include/project.h new file mode 100644 index 0000000..8b77b69 --- /dev/null +++ b/examples/Priority/include/project.h @@ -0,0 +1,53 @@ +#pragma once + +#define DSGM_SOUND_STREAM_COUNT 0 +#define DSGM_SOUND_EFFECT_COUNT 0 +#define DSGM_SOUND_COUNT (DSGM_SOUND_STREAM_COUNT + DSGM_SOUND_EFFECT_COUNT) +#define DSGM_BACKGROUND_COUNT 0 +#define DSGM_PALETTE_COUNT 1 +#define DSGM_SPRITE_COUNT 2 +#define DSGM_OBJECT_COUNT 1 +#define DSGM_ROOM_COUNT 1 + +// Include backgrounds, palettes and sprites to be loaded from RAM + +// No sounds, no enum +//typedef enum { +//} DSGM_SoundNames; + +// No backgrounds, no enum +//typedef enum { +//} DSGM_BackgroundNames; + +typedef enum { + DSGMPal0, +} DSGM_PaletteNames; + +typedef enum { + taptapman, + ballSprite, +} DSGM_SpriteNames; + +typedef enum { + player, + ball, +} DSGM_ObjectNames; + +typedef enum { + Room_1, +} DSGM_RoomNames; + +extern DSGM_Sound DSGM_Sounds[DSGM_SOUND_COUNT]; +extern DSGM_Background DSGM_Backgrounds[DSGM_BACKGROUND_COUNT]; +extern DSGM_Palette DSGM_Palettes[DSGM_PALETTE_COUNT]; +extern DSGM_Sprite DSGM_Sprites[DSGM_SPRITE_COUNT]; +extern DSGM_Object DSGM_Objects[DSGM_OBJECT_COUNT]; +extern DSGM_Room DSGM_Rooms[DSGM_ROOM_COUNT]; + +extern int DSGM_currentRoom; + +void DSGM_SetupRooms(int room); + +void ball_create(DSGM_ObjectInstance *me); +void ball_loop(DSGM_ObjectInstance *me); +void ball_touch(DSGM_ObjectInstance *me); diff --git a/examples/Priority/nitrofiles/DSGMPal0_Pal.bin b/examples/Priority/nitrofiles/DSGMPal0_Pal.bin new file mode 100644 index 0000000..30d7ec9 Binary files /dev/null and b/examples/Priority/nitrofiles/DSGMPal0_Pal.bin differ diff --git a/examples/Priority/nitrofiles/ball_Sprite.bin b/examples/Priority/nitrofiles/ball_Sprite.bin new file mode 100644 index 0000000..ed3e997 Binary files /dev/null and b/examples/Priority/nitrofiles/ball_Sprite.bin differ diff --git a/examples/Priority/nitrofiles/taptapman_Sprite.bin b/examples/Priority/nitrofiles/taptapman_Sprite.bin new file mode 100644 index 0000000..7ad7377 Binary files /dev/null and b/examples/Priority/nitrofiles/taptapman_Sprite.bin differ diff --git a/examples/Priority/source/main.c b/examples/Priority/source/main.c new file mode 100644 index 0000000..eff39e0 --- /dev/null +++ b/examples/Priority/source/main.c @@ -0,0 +1,17 @@ +#include "DSGM.h" + +void DSGM_Init(void); + +int main(int argc, char **argv) { + DSGM_Init(); + + DSGM_LoadRoom(&DSGM_Rooms[DSGM_currentRoom]); + + while(1) { + DSGM_LoopRoom(&DSGM_Rooms[DSGM_currentRoom]); + + DSGM_Update(); + } + + return 0; +} diff --git a/examples/Priority/source/project.c b/examples/Priority/source/project.c new file mode 100644 index 0000000..6c81b7b --- /dev/null +++ b/examples/Priority/source/project.c @@ -0,0 +1,194 @@ +#include "DSGM.h" + +#include "DSGM_projectHelper.h" + +// User variables / declarations +int timer = 0; + +// Resources +DSGM_Sound DSGM_Sounds[DSGM_SOUND_COUNT] = { +}; + +DSGM_Background DSGM_Backgrounds[DSGM_BACKGROUND_COUNT] = { +}; + +DSGM_Palette DSGM_Palettes[DSGM_PALETTE_COUNT] = { + DSGM_FORM_NITRO_PALETTE(DSGMPal0), +}; + +DSGM_Sprite DSGM_Sprites[DSGM_SPRITE_COUNT] = { + DSGM_FORM_NITRO_SPRITE(taptapman, DSGMPal0, SpriteSize_32x32, 9), + DSGM_FORM_NITRO_SPRITE(ball, DSGMPal0, SpriteSize_32x32, 1), +}; + +DSGM_Object DSGM_Objects[DSGM_OBJECT_COUNT] = { + // ball + { + &DSGM_Sprites[ballSprite], + ball_create, + ball_loop, + DSGM_NO_EVENT, + ball_touch, + + NULL, 0 + }, +}; + +DSGM_Room DSGM_Rooms[DSGM_ROOM_COUNT] = { + // Room_1 + { + // Backgrounds + { + // Bottom screen + { + // Layer 0 + { + DSGM_TEXT_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 0, // Layer + false, // Attached to view system + 0, 0, 0 + }, + + // Layer 1 + { + DSGM_NO_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 1, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 2 + { + DSGM_NO_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 2, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 3 + { + DSGM_NO_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 3, // Layer + true, // Attached to view system + 0, 0, 0 + }, + }, + + // Top screen + { + // Layer 0 + { + DSGM_TEXT_BACKGROUND, // Background + DSGM_TOP, // Screen + 0, // Layer + false, // Attached to view system + 0, 0, 0 + }, + + // Layer 1 + { + DSGM_NO_BACKGROUND, // Background + DSGM_TOP, // Screen + 1, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 2 + { + DSGM_NO_BACKGROUND, // Background + DSGM_TOP, // Screen + 2, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 3 + { + DSGM_NO_BACKGROUND, // Background + DSGM_TOP, // Screen + 3, // Layer + true, // Attached to view system + 0, 0, 0 + }, + } + }, + + // Initial views + { + // Bottom screen + { + 0, 0 + }, + + // Top screen + { + 0, 0 + } + }, + + // Views + { + // Bottom screen + { + 0, 0 + }, + + // Top screen + { + 0, 0 + } + }, + + // Object groups are dynamic, so must be set up at run time, see DSGM_SetupRooms. + { + NULL, + NULL + }, + { + 0, + 0 + } + }, +}; + +int DSGM_currentRoom = Room_1; + +void DSGM_SetupRooms(int room) { + if(room != DSGM_ALL_ROOMS) { + switch(room) { + case Room_1: goto Room_1; break; + } + } + + Room_1: + DSGM_Debug("Room_1 reset\n"); + DSGM_LeaveRoom(&DSGM_Rooms[Room_1]); + + DSGM_SetupViews(&DSGM_Rooms[Room_1]); + + DSGM_SetupObjectGroups(&DSGM_Rooms[Room_1], DSGM_TOP, 0); + + DSGM_SetupObjectGroups(&DSGM_Rooms[Room_1], DSGM_BOTTOM, 1); + + DSGM_SetupObjectInstances(&DSGM_Rooms[Room_1].objectGroups[DSGM_BOTTOM][0], &DSGM_Objects[player], DSGM_BOTTOM, 2, + 64, 64, + 84, 64 + ); + + if(room != DSGM_ALL_ROOMS) return; +} + +void ball_loop(DSGM_ObjectInstance *me) { + // Only change first instance of ball + if(me == &DSGM_GetGroup(me)->objectInstances[0]) { + timer++; + timer %= 120; + // priority can be 0 - 3 + me->priority = timer / 60; + } +} diff --git a/examples/RoomPersistency/Makefile b/examples/RoomPersistency/Makefile new file mode 100644 index 0000000..34daad2 --- /dev/null +++ b/examples/RoomPersistency/Makefile @@ -0,0 +1,143 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +include $(DEVKITARM)/ds_rules + +DSGMLibInclude := ../../DSGMLib/include +DSGMLibLib := ../../../DSGMLib/DSGMLib.a + +#--------------------------------------------------------------------------------- +# 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 +# MAXMOD_SOUNDBANK contains a directory of music and sound effect files +#--------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +INCLUDES := include $(DSGMLibInclude) +NITRODATA := nitrofiles +MAXMOD_SOUNDBANK := music + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -mthumb -mthumb-interwork -march=armv5te -mtune=arm946e-s + +CFLAGS := -g -Wall -O2\ + -fomit-frame-pointer\ + -ffast-math \ + $(ARCH) + +CFLAGS += $(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 := $(DSGMLibLib) -lfilesystem -lfat -lnds9 -lmm9 + + +#--------------------------------------------------------------------------------- +# 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)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +ifneq ($(strip $(NITRODATA)),) + export NITRO_FILES := $(CURDIR)/$(NITRODATA) +endif + +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)/*.*))) + +export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MAXMOD_SOUNDBANK)/*.*)),$(CURDIR)/$(MAXMOD_SOUNDBANK)/$(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) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds + +#--------------------------------------------------------------------------------- +else + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).nds : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) soundbank.h + +soundbank.h: ../$(NITRODATA)/soundbank.bin + +../$(NITRODATA)/soundbank.bin: $(AUDIOFILES) +#--------------------------------------------------------------------------------- + mmutil $^ -d -o../$(NITRODATA)/soundbank.bin -hsoundbank.h + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPSDIR)/*.d + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/examples/RoomPersistency/RoomPersistency.nds b/examples/RoomPersistency/RoomPersistency.nds new file mode 100644 index 0000000..5e8eac8 Binary files /dev/null and b/examples/RoomPersistency/RoomPersistency.nds differ diff --git a/examples/RoomPersistency/build.bat b/examples/RoomPersistency/build.bat new file mode 100644 index 0000000..8182ff5 --- /dev/null +++ b/examples/RoomPersistency/build.bat @@ -0,0 +1,2 @@ +make +pause \ No newline at end of file diff --git a/examples/RoomPersistency/include/project.h b/examples/RoomPersistency/include/project.h new file mode 100644 index 0000000..fc05b90 --- /dev/null +++ b/examples/RoomPersistency/include/project.h @@ -0,0 +1,57 @@ +#pragma once + +#define DSGM_SOUND_STREAM_COUNT 1 +#define DSGM_SOUND_EFFECT_COUNT 2 +#define DSGM_SOUND_COUNT (DSGM_SOUND_STREAM_COUNT + DSGM_SOUND_EFFECT_COUNT) +#define DSGM_BACKGROUND_COUNT 3 +#define DSGM_PALETTE_COUNT 1 +#define DSGM_SPRITE_COUNT 2 +#define DSGM_OBJECT_COUNT 1 +#define DSGM_ROOM_COUNT 2 + +// Include backgrounds, palettes and sprites to be loaded from RAM + + +typedef enum { + FlatOutLies, + Ambulance, + Boom, +} DSGM_SoundNames; + +typedef enum { + odale, + cloud, + space, +} DSGM_BackgroundNames; + +typedef enum { + DSGMPal0, +} DSGM_PaletteNames; + +typedef enum { + taptapman, +} DSGM_SpriteNames; + +typedef enum { + player, +} DSGM_ObjectNames; + +typedef enum { + Room_1, + Room_2, +} DSGM_RoomNames; + +extern DSGM_Sound DSGM_Sounds[DSGM_SOUND_COUNT]; +extern DSGM_Background DSGM_Backgrounds[DSGM_BACKGROUND_COUNT]; +extern DSGM_Palette DSGM_Palettes[DSGM_PALETTE_COUNT]; +extern DSGM_Sprite DSGM_Sprites[DSGM_SPRITE_COUNT]; +extern DSGM_Object DSGM_Objects[DSGM_OBJECT_COUNT]; +extern DSGM_Room DSGM_Rooms[DSGM_ROOM_COUNT]; + +extern int DSGM_currentRoom; + +void DSGM_SetupRooms(int room); + +void player_create(DSGM_ObjectInstance *me); +void player_loop(DSGM_ObjectInstance *me); +void player_touch(DSGM_ObjectInstance *me); diff --git a/examples/RoomPersistency/music/Ambulance.wav b/examples/RoomPersistency/music/Ambulance.wav new file mode 100644 index 0000000..e3efc25 Binary files /dev/null and b/examples/RoomPersistency/music/Ambulance.wav differ diff --git a/examples/RoomPersistency/music/Boom.wav b/examples/RoomPersistency/music/Boom.wav new file mode 100644 index 0000000..1d8665b Binary files /dev/null and b/examples/RoomPersistency/music/Boom.wav differ diff --git a/examples/RoomPersistency/music/FlatOutLies.mod b/examples/RoomPersistency/music/FlatOutLies.mod new file mode 100644 index 0000000..7b06f97 Binary files /dev/null and b/examples/RoomPersistency/music/FlatOutLies.mod differ diff --git a/examples/RoomPersistency/nitrofiles/DSGMPal0_Pal.bin b/examples/RoomPersistency/nitrofiles/DSGMPal0_Pal.bin new file mode 100644 index 0000000..86355b8 Binary files /dev/null and b/examples/RoomPersistency/nitrofiles/DSGMPal0_Pal.bin differ diff --git a/examples/RoomPersistency/nitrofiles/cloud_Map.bin b/examples/RoomPersistency/nitrofiles/cloud_Map.bin new file mode 100644 index 0000000..8ed8d43 Binary files /dev/null and b/examples/RoomPersistency/nitrofiles/cloud_Map.bin differ diff --git a/examples/RoomPersistency/nitrofiles/cloud_Pal.bin b/examples/RoomPersistency/nitrofiles/cloud_Pal.bin new file mode 100644 index 0000000..7957cec Binary files /dev/null and b/examples/RoomPersistency/nitrofiles/cloud_Pal.bin differ diff --git a/examples/RoomPersistency/nitrofiles/cloud_Tiles.bin b/examples/RoomPersistency/nitrofiles/cloud_Tiles.bin new file mode 100644 index 0000000..4a38f77 Binary files /dev/null and b/examples/RoomPersistency/nitrofiles/cloud_Tiles.bin differ diff --git a/examples/RoomPersistency/nitrofiles/odale_Map.bin b/examples/RoomPersistency/nitrofiles/odale_Map.bin new file mode 100644 index 0000000..e54edd6 Binary files /dev/null and b/examples/RoomPersistency/nitrofiles/odale_Map.bin differ diff --git a/examples/RoomPersistency/nitrofiles/odale_Pal.bin b/examples/RoomPersistency/nitrofiles/odale_Pal.bin new file mode 100644 index 0000000..3ea8899 Binary files /dev/null and b/examples/RoomPersistency/nitrofiles/odale_Pal.bin differ diff --git a/examples/RoomPersistency/nitrofiles/odale_Tiles.bin b/examples/RoomPersistency/nitrofiles/odale_Tiles.bin new file mode 100644 index 0000000..17cbfcd --- /dev/null +++ b/examples/RoomPersistency/nitrofiles/odale_Tiles.bin @@ -0,0 +1,35 @@ +                                                                 + + +  +     + + +               + + +  +  + +  +    + + + + + +   + + + + + + +                             + + +  +  + +    +                                                                                                                                                !"! !"! !"! !"! !"! !"! !"! !"! """"# """"# """"# """"# """"# """"# """"# """"# """"""""""""""""""""""""""""''''''''' """"""""""""""""""""""""""""""""''''''' ''""""""""$%%%%%%%%%&&&&&%&&&&&%&&&&&%&(&(&%(&(&(""""""""%%%%%%%%%&&&&&%&&&&&%&&&&&%(&(&(%&(&(&%!"!!"!!"!!"!!"!!"!!"!!"! !"! !"! !"! !"! !"! !"! !"! !"!'' (((('' &&&&'' &&&&'' &&&&'' ''''''' %'%'% " %'%'(((( ''&&&& ''&&&& ''&&&& '' ''''''''''%'%'%'%'%'%'%%&(&(&%%(((((%(((((%(((((%"%%%%%%%""""""""(&(&(%%(((((%(((((%(((((%%%%%%%%%""""""""" !"! """  ###  ###  ###  ###  ###  """"# """"# !##### "##### "##### "##### "#####  "" %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!!!!!!!!########################################!"! """ ### ### ### ### ###                                    )  ))             ) )) ))) ))) ))) ))))))))))))))))))  )))))))))))))))))) ) )) ))) ))) ))) ))))))))))))) )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) )     )))  ))))))))))))))))) )           ))               ))     \ No newline at end of file diff --git a/examples/RoomPersistency/nitrofiles/soundbank.bin b/examples/RoomPersistency/nitrofiles/soundbank.bin new file mode 100644 index 0000000..176ceb5 Binary files /dev/null and b/examples/RoomPersistency/nitrofiles/soundbank.bin differ diff --git a/examples/RoomPersistency/nitrofiles/space_Map.bin b/examples/RoomPersistency/nitrofiles/space_Map.bin new file mode 100644 index 0000000..720bd0d Binary files /dev/null and b/examples/RoomPersistency/nitrofiles/space_Map.bin differ diff --git a/examples/RoomPersistency/nitrofiles/space_Pal.bin b/examples/RoomPersistency/nitrofiles/space_Pal.bin new file mode 100644 index 0000000..4f5cd88 Binary files /dev/null and b/examples/RoomPersistency/nitrofiles/space_Pal.bin differ diff --git a/examples/RoomPersistency/nitrofiles/space_Tiles.bin b/examples/RoomPersistency/nitrofiles/space_Tiles.bin new file mode 100644 index 0000000..b659a1d Binary files /dev/null and b/examples/RoomPersistency/nitrofiles/space_Tiles.bin differ diff --git a/examples/RoomPersistency/nitrofiles/taptapman_Sprite.bin b/examples/RoomPersistency/nitrofiles/taptapman_Sprite.bin new file mode 100644 index 0000000..7ad7377 Binary files /dev/null and b/examples/RoomPersistency/nitrofiles/taptapman_Sprite.bin differ diff --git a/examples/RoomPersistency/source/main.c b/examples/RoomPersistency/source/main.c new file mode 100644 index 0000000..eff39e0 --- /dev/null +++ b/examples/RoomPersistency/source/main.c @@ -0,0 +1,17 @@ +#include "DSGM.h" + +void DSGM_Init(void); + +int main(int argc, char **argv) { + DSGM_Init(); + + DSGM_LoadRoom(&DSGM_Rooms[DSGM_currentRoom]); + + while(1) { + DSGM_LoopRoom(&DSGM_Rooms[DSGM_currentRoom]); + + DSGM_Update(); + } + + return 0; +} diff --git a/examples/RoomPersistency/source/project.c b/examples/RoomPersistency/source/project.c new file mode 100644 index 0000000..bc8bc93 --- /dev/null +++ b/examples/RoomPersistency/source/project.c @@ -0,0 +1,467 @@ +#include "DSGM.h" + +#include "DSGM_projectHelper.h" + +// User variables / declarations +#define LEFT 0 +#define RIGHT 1 +#define UP 2 +#define DOWN 3 + +int direction = DOWN; + +bool walkableTile(u16 tile) { + switch(tile) { + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x0D: + case 0x0E: + case 0x0F: + case 0x10: + case 0x2F: + case 0x30: + case 0x38: + case 0x39: + case 0x5C: + case 0x5D: + case 0x5E: + case 0x5F: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x407: + case 0x410: + case 0x40D: + case 0x464: + case 0x80E: + case 0x808: + case 0x809: + case 0x864: + case 0xC0D: + return true; + break; + } + return false; +} + +// Resources +DSGM_Sound DSGM_Sounds[DSGM_SOUND_COUNT] = { + DSGM_FORM_SOUND_STREAM(FlatOutLies), + DSGM_FORM_SOUND_EFFECT(Ambulance), + DSGM_FORM_SOUND_EFFECT(Boom), +}; + +DSGM_Background DSGM_Backgrounds[DSGM_BACKGROUND_COUNT] = { + DSGM_FORM_NITRO_BACKGROUND(odale, BgSize_T_512x512, BgType_Text8bpp), + DSGM_FORM_NITRO_BACKGROUND(cloud, BgSize_T_256x256, BgType_Text8bpp), + DSGM_FORM_NITRO_BACKGROUND(space, BgSize_T_256x256, BgType_Text8bpp), +}; + +DSGM_Palette DSGM_Palettes[DSGM_PALETTE_COUNT] = { + DSGM_FORM_NITRO_PALETTE(DSGMPal0), +}; + +DSGM_Sprite DSGM_Sprites[DSGM_SPRITE_COUNT] = { + DSGM_FORM_NITRO_SPRITE(taptapman, DSGMPal0, SpriteSize_32x32, 9), +}; + +DSGM_Object DSGM_Objects[DSGM_OBJECT_COUNT] = { + // player + { + &DSGM_Sprites[taptapman], + player_create, + player_loop, + DSGM_NO_EVENT, + player_touch, + + NULL, 0 + }, +}; + +DSGM_Room DSGM_Rooms[DSGM_ROOM_COUNT] = { + // Room_1 + { + // Backgrounds + { + // Bottom screen + { + // Layer 0 + { + DSGM_TEXT_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 0, // Layer + false, // Attached to view system + 0, 0, 0 + }, + + // Layer 1 + { + &DSGM_Backgrounds[odale], // Background + DSGM_BOTTOM, // Screen + 1, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 2 + { + DSGM_NO_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 2, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 3 + { + DSGM_NO_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 3, // Layer + true, // Attached to view system + 0, 0, 0 + }, + }, + + // Top screen + { + // Layer 0 + { + DSGM_TEXT_BACKGROUND, // Background + DSGM_TOP, // Screen + 0, // Layer + false, // Attached to view system + 0, 0, 0 + }, + + // Layer 1 + { + DSGM_NO_BACKGROUND, // Background + DSGM_TOP, // Screen + 1, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 2 + { + DSGM_NO_BACKGROUND, // Background + DSGM_TOP, // Screen + 2, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 3 + { + DSGM_NO_BACKGROUND, // Background + DSGM_TOP, // Screen + 3, // Layer + true, // Attached to view system + 0, 0, 0 + }, + } + }, + + // Initial views + { + // Bottom screen + { + 128, 128 + }, + + // Top screen + { + 0, 0 + } + }, + + // Views + { + // Bottom screen + { + 128, 128 + }, + + // Top screen + { + 0, 0 + } + }, + + // Object groups are dynamic, so must be set up at run time, see DSGM_SetupRooms. + { + NULL, + NULL + }, + { + 0, + 0 + } + }, + + // Room_2 + { + // Backgrounds + { + // Bottom screen + { + // Layer 0 + { + DSGM_TEXT_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 0, // Layer + false, // Attached to view system + 0, 0, 0 + }, + + // Layer 1 + { + &DSGM_Backgrounds[odale], // Background + DSGM_BOTTOM, // Screen + 1, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 2 + { + DSGM_NO_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 2, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 3 + { + DSGM_NO_BACKGROUND, // Background + DSGM_BOTTOM, // Screen + 3, // Layer + true, // Attached to view system + 0, 0, 0 + }, + }, + + // Top screen + { + // Layer 0 + { + /*//DSGM_TEXT_BACKGROUND, // Background*/ + DSGM_NO_BACKGROUND, + DSGM_TOP, // Screen + 0, // Layer + false, // Attached to view system + 0, 0, 0 + }, + + // Layer 1 + { + /*DSGM_NO_BACKGROUND, // Background*/ + DSGM_TEXT_BACKGROUND, + DSGM_TOP, // Screen + 1, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 2 + { + DSGM_NO_BACKGROUND, // Background + DSGM_TOP, // Screen + 2, // Layer + true, // Attached to view system + 0, 0, 0 + }, + + // Layer 3 + { + DSGM_NO_BACKGROUND, // Background + DSGM_TOP, // Screen + 3, // Layer + true, // Attached to view system + 0, 0, 0 + }, + } + }, + + // Initial views + { + // Bottom screen + { + 128, 128 + }, + + // Top screen + { + 0, 0 + } + }, + + // Views + { + // Bottom screen + { + 128, 128 + }, + + // Top screen + { + 0, 0 + } + }, + + // Object groups are dynamic, so must be set up at run time, see DSGM_SetupRooms. + { + NULL, + NULL + }, + { + 0, + 0 + } + }, +}; + +int DSGM_currentRoom = Room_1; + +void DSGM_SetupRooms(int room) { + if(room != DSGM_ALL_ROOMS) { + switch(room) { + case Room_1: goto Room_1; break; + case Room_2: goto Room_2; break; + } + } + + Room_1: + DSGM_Debug("Room_1 reset\n"); + DSGM_LeaveRoom(&DSGM_Rooms[Room_1]); + + DSGM_SetupViews(&DSGM_Rooms[Room_1]); + + DSGM_SetupObjectGroups(&DSGM_Rooms[Room_1], DSGM_TOP, 0); + + DSGM_SetupObjectGroups(&DSGM_Rooms[Room_1], DSGM_BOTTOM, 1); + + DSGM_SetupObjectInstances(&DSGM_Rooms[Room_1].objectGroups[DSGM_BOTTOM][0], &DSGM_Objects[player], DSGM_BOTTOM, 1, + 239, 207 + ); + + if(room != DSGM_ALL_ROOMS) return; + + Room_2: + DSGM_Debug("Room 2 reset\n"); + DSGM_LeaveRoom(&DSGM_Rooms[Room_2]); + + DSGM_SetupViews(&DSGM_Rooms[Room_1]); + + DSGM_SetupObjectGroups(&DSGM_Rooms[Room_2], DSGM_TOP, 0); + + DSGM_SetupObjectGroups(&DSGM_Rooms[Room_2], DSGM_BOTTOM, 1); + + DSGM_SetupObjectInstances(&DSGM_Rooms[Room_2].objectGroups[DSGM_BOTTOM][0], &DSGM_Objects[player], DSGM_BOTTOM, 1, + 239, 207 + ); + + if(room != DSGM_ALL_ROOMS) return; +} + +void player_create(DSGM_ObjectInstance *me) { + DSGM_DrawText(DSGM_BOTTOM, 18, 22, "DS Game Maker"); + DSGM_DrawText(DSGM_TOP, 1, 1, "Room persistency demo"); + DSGM_DrawText(DSGM_TOP, 1, 3, "Touch player to switch rooms"); + if(DSGM_currentRoom == Room_1) { + DSGM_DrawText(DSGM_TOP, 1, 5, "Room_1"); + } + else { + DSGM_DrawText(DSGM_TOP, 1, 5, "Room_2"); + } + DSGM_PlaySound(FlatOutLies); + + direction = DOWN; + me->frame = 0; + me->hFlip = false; +} + +void player_loop(DSGM_ObjectInstance *me) { + // Position the player to be in the centre of the screen + me->x = DSGM_Rooms[DSGM_currentRoom].view[DSGM_BOTTOM].x + 111; + me->y = DSGM_Rooms[DSGM_currentRoom].view[DSGM_BOTTOM].y + 79; + + // Change direction + if(DSGM_held.Left && DSGM_NOT_HOLDING_3(Right, Up, Down) && direction != LEFT) { + me->animationTimer = 11; + direction = LEFT; + me->hFlip = true; + } + if(DSGM_held.Right && DSGM_NOT_HOLDING_3(Left, Up, Down) && direction != RIGHT) { + me->animationTimer = 11; + direction = RIGHT; + me->hFlip = false; + } + if(DSGM_held.Up && DSGM_NOT_HOLDING_3(Left, Right, Down) && direction != UP) { + me->animationTimer = 11; + direction = UP; + me->hFlip = false; + } + if(DSGM_held.Down && DSGM_NOT_HOLDING_3(Left, Right, Up) && direction != DOWN) { + me->animationTimer = 11; + direction = DOWN; + me->hFlip = false; + } + + // Move + if(direction == LEFT && DSGM_held.Left) { + if(\ + walkableTile(DSGM_GetTile(&DSGM_Rooms[DSGM_currentRoom].backgroundInstances[DSGM_BOTTOM][1], (me->x + 8) / 8, (me->y + 16) / 8)) &&\ + walkableTile(DSGM_GetTile(&DSGM_Rooms[DSGM_currentRoom].backgroundInstances[DSGM_BOTTOM][1], (me->x + 8) / 8, (me->y + 31) / 8))\ + ) DSGM_Rooms[DSGM_currentRoom].view[DSGM_BOTTOM].x--; + DSGM_ReturnAnimateObjectInstance(me, 3, 4, 5, 12); + } + if(direction == RIGHT && DSGM_held.Right) { + if(\ + walkableTile(DSGM_GetTile(&DSGM_Rooms[DSGM_currentRoom].backgroundInstances[DSGM_BOTTOM][1], (me->x + 24) / 8, (me->y + 16) / 8)) &&\ + walkableTile(DSGM_GetTile(&DSGM_Rooms[DSGM_currentRoom].backgroundInstances[DSGM_BOTTOM][1], (me->x + 24) / 8, (me->y + 31) / 8))\ + ) DSGM_Rooms[DSGM_currentRoom].view[DSGM_BOTTOM].x++; + DSGM_ReturnAnimateObjectInstance(me, 3, 4, 5, 12); + } + if(direction == UP && DSGM_held.Up) { + if(\ + walkableTile(DSGM_GetTile(&DSGM_Rooms[DSGM_currentRoom].backgroundInstances[DSGM_BOTTOM][1], (me->x + 9) / 8, (me->y + 15) / 8)) &&\ + walkableTile(DSGM_GetTile(&DSGM_Rooms[DSGM_currentRoom].backgroundInstances[DSGM_BOTTOM][1], (me->x + 23) / 8, (me->y + 15) / 8))\ + ) DSGM_Rooms[DSGM_currentRoom].view[DSGM_BOTTOM].y--; + DSGM_ReturnAnimateObjectInstance(me, 6, 7, 8, 12); + } + if(direction == DOWN && DSGM_held.Down) { + if(\ + walkableTile(DSGM_GetTile(&DSGM_Rooms[DSGM_currentRoom].backgroundInstances[DSGM_BOTTOM][1], (me->x + 9) / 8, (me->y + 32) / 8)) &&\ + walkableTile(DSGM_GetTile(&DSGM_Rooms[DSGM_currentRoom].backgroundInstances[DSGM_BOTTOM][1], (me->x + 23) / 8, (me->y + 32) / 8))\ + ) DSGM_Rooms[DSGM_currentRoom].view[DSGM_BOTTOM].y++; + DSGM_ReturnAnimateObjectInstance(me, 0, 1, 2, 12); + } + + // Stand still + if(DSGM_NOT_HOLDING_DPAD()) { + if(direction == LEFT || direction == RIGHT) me->frame = 3; + if(direction == UP) me->frame = 6; + if(direction == DOWN) me->frame = 0; + } +} + +void player_touch(DSGM_ObjectInstance *me) { + //mmStop(); + //DSGM_Sounds[FlatOutLies].loaded = false; + //DSGM_PlaySound(FlatOutLies); + //mmLoad(DSGM_Sounds[FlatOutLies].ID); + //swiWaitForVBlank(); + //mmStart(DSGM_Sounds[FlatOutLies].ID, MM_PLAY_LOOP); + if(DSGM_currentRoom == Room_1) { + DSGM_SwitchRoom(Room_2, false); + } + else if(DSGM_currentRoom == Room_2) { + DSGM_SwitchRoom(Room_1, false); + } +}