dsgmLib/source/DSGM_room.c
2015-02-14 16:20:37 +00:00

222 lines
8.5 KiB
C

#include "DSGM.h"
bool DSGM_invalidateRoom = 0;
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 layerNumber;
int group;
int object;
DSGM_Debug("Loading room...\n");
{
bool requiresMode3[2] = {false, false};
for(screen = 0; screen < 2; screen++) {
if(room->layers[screen][3].background == DSGM_DRAWABLE_BACKGROUND || room->layers[screen][3].background->type == BgType_ExRotation) {
DSGM_Debug("Screen %d requires Mode 3\n", screen);
requiresMode3[screen] = true;
}
}
DSGM_InitCustomGFX(requiresMode3[DSGM_TOP], requiresMode3[DSGM_BOTTOM], room->layers[DSGM_TOP][0].background == DSGM_3D_RENDERER);
}
for(screen = 0; screen < 2; screen++) {
// Load backgrounds
for(layerNumber = 0; layerNumber < 4; layerNumber++) {
if(room->layers[screen][layerNumber].background != DSGM_NO_BACKGROUND) {
DSGM_Debug("Screen %d, layerNumber %d, background %p\n", screen, layerNumber, room->layers[screen][layerNumber].background);
if(room->layers[screen][layerNumber].background == DSGM_DEFAULT_FONT) DSGM_InitText(&room->layers[screen][layerNumber]);
else if(room->layers[screen][layerNumber].background == DSGM_DRAWABLE_BACKGROUND) {
if(layerNumber == 3) DSGM_InitDrawableBackground(&room->layers[screen][layerNumber]);
}
else if(room->layers[screen][layerNumber].background != DSGM_3D_RENDERER) {
DSGM_LoadBackgroundFull(&room->layers[screen][layerNumber]);
if(room->layers[screen][layerNumber].background->type == BgType_Text4bpp) DSGM_InitText(&room->layers[screen][layerNumber]);
}
DSGM_ScrollBackgroundFull(&room->view[screen], &room->layers[screen][layerNumber]);
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_ActivateObjectInstance(room, objectInstance);
DSGM_ValidateRoom();
}
}
}
DSGM_Debug("Loaded\n");
}
//int res = 0;
void DSGM_LoopRoom(DSGM_Room *room) {
u8 screen;
int layerNumber;
int group;
int object;
int sound;
int rotset;
//if(!res) {
// mmStop();
// mmStart(/*DSGM_Sounds[FlatOutLies].ID*/0, MM_PLAY_LOOP);
// res = 1;
//}
bool clearWireless = DSGM_newWirelessData;
if(room->handler) room->handler();
DSGM_ValidateRoom();
//+1?
for(sound = 0; sound < DSGM_soundEffectInstanceCount; sound++) {
DSGM_SetSoundInstanceVolumeFull(&DSGM_soundEffectInstances[sound], DSGM_soundEffectInstances[sound].volume);
DSGM_SetSoundInstancePanningFull(&DSGM_soundEffectInstances[sound], DSGM_soundEffectInstances[sound].panning);
}
for(screen = 0; screen < 2; screen++) {
for(layerNumber = 0; layerNumber < 4; layerNumber++) {
if(room->layers[screen][layerNumber].background != DSGM_NO_BACKGROUND) {
DSGM_ScrollBackgroundFull(&room->view[screen], &room->layers[screen][layerNumber]);
if(room->layers[screen][layerNumber].background->type == DSGM_LARGE_BACKGROUND) {
DSGM_LargeBackgroundUpdateFull(&room->view[screen], &room->layers[screen][layerNumber]);
}
}
}
//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++) {
#define objectInstance (&room->objectGroups[screen][group].objectInstances[object])
// Calculate position
int x = objectInstance->x - room->view[screen].x;
int y = objectInstance->y - room->view[screen].y;
if(x < 256 && x > -128 && y < 192 && y > -64 && !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;
}
objectInstance->absoluteX = x;
objectInstance->absoluteY = y;
// Calculate GFX index
objectInstance->gfxIndex = oamGfxPtrToOffset(objectInstance->screen == DSGM_TOP ? &oamMain : &oamSub, (objectInstance->screen == DSGM_TOP ? objectInstance->object->sprite->topTiles : objectInstance->object->sprite->bottomTiles)[objectInstance->frame]);
// Copy into OAM
memcpy(&(objectInstance->screen == DSGM_TOP ? oamMain : oamSub).oamMemory[objectInstance->spriteNumber], &objectInstance->oam, sizeof(DSGM_SpriteEntry));
// Maybe one of these is better than memcpy?
//DC_FlushAll();
//dmaCopy();
//dmaCopyHalfWords();
//swifastcopy();
if(objectInstance->object->loop) objectInstance->object->loop(objectInstance);
DSGM_ValidateRoom();
DSGM_ValidateObjectInstance(objectInstance);
if(screen == DSGM_BOTTOM && objectInstance->object->touch) {
if(DSGM_newpress.Stylus && DSGM_StylusOverObjectInstanceFull(room, objectInstance)) {
objectInstance->object->touch(objectInstance);
DSGM_ValidateRoom();
DSGM_ValidateObjectInstance(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]);
DSGM_ValidateRoom();
DSGM_ValidateObjectInstance(objectInstance);
}
}
}
#undef objectInstance
}
}
for(rotset = 0; rotset < 32; rotset++) {
DSGM_SetRotset(screen, rotset, DSGM_rotations[screen][rotset], DSGM_scales[screen][rotset].x, DSGM_scales[screen][rotset].y);
}
}
if(room->layers[DSGM_TOP][0].background == DSGM_3D_RENDERER) glFlush(0);
if(clearWireless) DSGM_newWirelessData = false;
//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;
int object;
int layerNumber;
for(screen = 0; screen < 2; screen++) {
for(layerNumber = 0; layerNumber < 4; layerNumber++) {
if(room->layers[screen][layerNumber].background->type == DSGM_LARGE_BACKGROUND) {
DSGM_Debug("Freeing large background map %p\n", room->layers[screen][layerNumber].largeBackgroundMap);
free(room->layers[screen][layerNumber].largeBackgroundMap);
}
}
for(group = 0; group < room->objectGroupCount[screen]; group++) {
for(object = 0; object < room->objectGroups[screen][group].objectInstanceCount; object++) {
DSGM_Debug("Freeing object instance custom variables\n");
free(room->objectGroups[screen][group].objectInstances[object].variables);
}
//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 events at %p\n", room->objectGroups[screen][group].object->collisionEvents);
free(room->objectGroups[screen][group].object->collisionEvents);
room->objectGroups[screen][group].object->collisionEvents = NULL;
room->objectGroups[screen][group].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]);
}
}
inline int DSGM_GetRoomNumberFull(DSGM_Room *rooms, DSGM_Room *room) {
return room - rooms;
}