/* * Newer Super Mario Bros. Wii * 2D World Maps * * Wish me luck. That's all I'm saying. --Treeki * Started: 03/06/2010; 11:52pm */ #include "worldmap.h" /* Code */ void PaneSetAllVisible(void *pane, int flag, bool value) { //OSReport("%08X {\n", pane); if (value) ((char*)pane)[0xBB] &= ~(1 << flag); else ((char*)pane)[0xBB] |= (1 << flag); nw4rLinkListNode *firstNode = (nw4rLinkListNode*)(pane+0x14); nw4rLinkListNode *currentNode = (nw4rLinkListNode*)(firstNode->prev); while (currentNode != firstNode) { PaneSetAllVisible(((void*)currentNode) - 4, flag, value); currentNode = (nw4rLinkListNode*)currentNode->prev; } //OSReport("} %08X\n", pane); } void LayoutSetAllVisible(void *layout, int flag, bool value) { // get the rootpane from offset 0x10 PaneSetAllVisible(*((void**)(layout+0x10)), flag, value); } void *LoadFile(FileHandle *handle, char *name) { int entryNum = DVDConvertPathToEntrynum(name); DVDHandle dvdhandle; if (!DVDFastOpen(entryNum, &dvdhandle)) { OSReport("Cannot open file %s\n", name); return 0; } handle->length = dvdhandle.length; handle->filePtr = EGG__Heap__alloc((handle->length+0x1F) & ~0x1F, 0x20, GetArchiveHeap()); int ret = DVDReadPrio(&dvdhandle, handle->filePtr, (handle->length+0x1F) & ~0x1F, 0, 2); //OSReport("retval: %x\n", ret); DVDClose(&dvdhandle); return handle->filePtr; } bool FreeFile(FileHandle *handle) { if (!handle) return false; if (handle->filePtr) EGG__Heap__free(handle->filePtr, GetArchiveHeap()); return true; } void d2DWorldMap_c__LoadLayout(d2DWorldMap_c *self, char *arcName, char *prefix, char *brlytName) { //char *arc = NSMBWLoadFile(&self->fileHandle, arcName, 0, *((void**)0x8042A72C)); //char *arc = NSMBWLoadFile(&self->fileHandle, arcName, 0, 0); char *arc = (char*)LoadFile(&self->fileHandle, arcName); if (arc == 0) { OSReport("Can't load %s :(\n", arcName); while (true) { } } // allocate 0xC0 space for the ArcResourceAccessor // unsure what the actual size is, but we should be safe with that self->ResAcc = AllocFromGameHeap1(0xC0); nsmbw__ArcResourceAccessor__ArcResourceAccessor(self->ResAcc); #ifdef REGION_NTSC *((void**)self->ResAcc) = (void*)0x802FE410; // replace vtable with NSMB's version #endif #ifdef REGION_PAL *((void**)self->ResAcc) = (void*)0x802FE710; // replace vtable with NSMB's version #endif nsmbw__ArcResourceAccessor__Set(self->ResAcc, arc, prefix); char *brlyt = nsmbw__ArcResourceAccessor__GetResource(self->ResAcc, 0x626C7974, brlytName, 0); // allocate 0x20 space for the Layout self->Layout = AllocFromGameHeap1(0x20); lyt__Layout__Layout(self->Layout); lyt__Layout__Build(self->Layout, brlyt, self->ResAcc); // allocate 0x54 space for the DrawInfo self->DrawInfo = (nw4r__lyt__DrawInfo*)AllocFromGameHeap1(0x54); lyt__DrawInfo__DrawInfo(self->DrawInfo); // set up the anims self->BrlanArray = 0; self->BrlanCount = 0; //PSMTXTransApply(self->DrawInfo->matrix, self->DrawInfo->matrix, 304, 228, 0); /*self->DrawInfo->left = 0; self->DrawInfo->top = 0; self->DrawInfo->right = 608; self->DrawInfo->bottom = 456;*/ } void d2DWorldMap_c__LoadAnims(d2DWorldMap_c *self, const char **brlanNames, int brlanCount) { //OSReport("Loading anims\n"); void *buf = __nwa(brlanCount*0x1C + 0x10); //OSReport("Alloced buffer: %08X\n", buf); // function params are BrlanHandler_ctor, BrlanHandler_dtor self->BrlanArray = construct_new_array(buf, (void*)0x800C9150, (void*)0x800C91A0, 0x1C, brlanCount); //OSReport("Constructed array: %08X\n", self->BrlanArray); // huge hack coming up struct TrickClass_t { void *pad1; void *resacc; void *pad2; void *pad3; void *pad4; void *pad5; void *pad6; void *pad7; } TrickClass; TrickClass.resacc = self->ResAcc; //OSReport("Created TrickClass\n"); for (int i = 0; i < brlanCount; i++) { //OSReport("b@%08X\n", self->BrlanArray+(0x1C*i)); //OSReport("Loading brlan %d %s\n", i, brlanNames[i]); NSMBWBrlan__Load(self->BrlanArray+(0x1C*i), brlanNames[i], (void*)(&TrickClass), self->Layout, 1); //OSReport("Done loading brlan %d %s\n", i, brlanNames[i]); //OSReport("a@%08X\n", self->BrlanArray+(0x1C*i)); } OSReport("Done loading brlans\n"); /*char *brlan = nsmbw__ArcResourceAccessor__GetResource(self->ResAcc, 0x616e696d, brlanName, 0); OSReport("grabbed brlan %s to %08X\n", brlanName, brlan); // call CreateAnimTransform CreateAnimTransformFunc CreateAnimTransform = (*((CreateAnimTransformFunc**)self->Layout))[5]; void *atf = CreateAnimTransform(self->Layout, brlan, self->ResAcc); // call BindAnimation BindAnimationFunc BindAnimation = (*((BindAnimationFunc**)self->Layout))[7]; BindAnimation(self->Layout, atf); return atf;*/ } void d2DWorldMap_c__SetAnimationEnable(d2DWorldMap_c *self, void *anim, bool val) { SetAnimationEnableFunc SetAnimationEnable = (*((SetAnimationEnableFunc**)self->Layout))[11]; SetAnimationEnable(self->Layout, anim, val); } void d2DWorldMap_c__FreeLayout(d2DWorldMap_c *self) { if (self->BrlanArray) { for (int i = 0; i < self->BrlanCount; i++) { NSMBWBrlan__Free(self->BrlanArray+(0x1C*i)); } // function param is BrlanHandler_dtor DeleteArray(self->BrlanArray, (void*)0x800C91A0); } lyt__Layout__dt(self->Layout, 0); nsmbw__ArcResourceAccessor__dt(self->ResAcc, 0); lyt__DrawInfo__dt(self->DrawInfo, 0); FreeFromGameHeap1(self->ResAcc); FreeFromGameHeap1(self->Layout); FreeFromGameHeap1(self->DrawInfo); //NSMBWFreeFile(&self->fileHandle); FreeFile(&self->fileHandle); } const char *bannerStart = "banner_start.brlan"; const char *bannerLoop = "banner_loop.brlan"; bool d2DWorldMap_c__onCreate(d2DWorldMap_c *self) { OSReport("Starting\n"); //d2DWorldMap_c__LoadLayout(self, testArc, "arc", "messageWindow_02.brlyt"); d2DWorldMap_c__LoadLayout(self, "/NewerRes/wmap.arc", "arc", "banner.brlyt"); OSReport("Loaded\n"); //d2DWorldMap_c__LoadLayout(self, "/NewerRes/wmap.arc", "arc", "openingTitle_EU_00.brlyt"); //d2DWorldMap_c__LoadLayout(self, "/NewerRes/wmap.arc", "arc", "pauseMenu_16.brlyt"); //self->StartAnim = d2DWorldMap_c__LoadAnim(self, "banner_start.brlan"); //OSReport("startanim: %X\n", self->StartAnim); //self->LoopAnim = d2DWorldMap_c__LoadAnim(self, "banner_loop.brlan"); const char* anims[2]; anims[0] = bannerStart; anims[1] = bannerLoop; OSReport("Set anims\n"); d2DWorldMap_c__LoadAnims(self, anims, 2); OSReport("Loaded anims\n"); OSReport("layout is at %8X\n", self->Layout); // 815e7450 OSReport("Enabled anims\n"); d2DWorldMap_c__SetAnimationEnable(self, (void*)0x815ED040, true); //LayoutMakeAllVisible(self->Layout, true); /*bool (*idk)(int) = (bool(*)(int))0x800B0DB0; idk(0); bool (*idk2)(int*) = (bool(*)(int*))0x800E4940; int blah = 0xFF; idk2(&blah);*/ return true; } bool d2DWorldMap_c__onDelete(d2DWorldMap_c *self) { //d2DWorldMap_c__FreeLayout(self); return true; } bool d2DWorldMap_c__onExecute(d2DWorldMap_c *self) { // call Animate() AnimateFunc Animate = (*((AnimateFunc**)self->Layout))[14]; Animate(self->Layout, true); return true; } bool d2DWorldMap_c__onDraw(d2DWorldMap_c *self) { MTX44 matrix; MTXOrtho(matrix, 228, -228, -304, 304, 0, 1); GXSetProjection(matrix, GX_ORTHOGRAPHIC); // call CalculateMtx() CalculateMtxFunc CalculateMtx = (*((CalculateMtxFunc**)self->Layout))[12]; CalculateMtx(self->Layout, self->DrawInfo); // call Draw() DrawFunc Draw = (*((DrawFunc**)self->Layout))[13]; Draw(self->Layout, self->DrawInfo); return true; }