//Used for defining minimap sectors on a large map void Minimap_GetSectorDefinitions(){ //MiniMap_DefineSector(int map, int sector, int dmap, int xoff, int yoff) //Safe ranges for 16x8 maps: // X: -16, 16 // Y: -20, 20 } const int MINIMAP_LAYER = 7; //Layer the minimap is drawn to //X and Y position of the minimap on the subscreen const int MINIMAP_X = 27; const int MINIMAP_Y = 16; const int MINIMAP_SQUARESIZE = 6; //Width/Height of a minimap square in pixels //Width and height of the minimap in screens const int MINIMAP_TILEWIDTH = 7; const int MINIMAP_TILEHEIGHT = 5; const int MINIMAP_MAPWIDTH = 16; //Max width of a map const int MINIMAP_MAPS = 10; //First of 4 maps used for minimaps const int MINIMAP_MARKERMAPS = 14; //First of 4 maps used for minimap markers const int MINIMAP_USELEVELNUM = 1; //Set to 1 to use level numbers instead of DMaps for getting reference maps const int MINIMAP_CLAMPPOSITION = 0; //Set to 1 to clamp the position of the minimap to the play area, if 0, Link's position will always be centered const int MINIMAP_MARKERSREQUIREVISITED = 1; //Set to 1 to make it so markers require you have visited the screen to display const int MINIMAP_REQUIREDUNGEONMAP = 1; //Set to 1 to require the dungeon map to view unexplored (not hidden) rooms const int MINIMAP_REQUIRECOMPASS = 1; //Set to 1 to require the compass to view map markers const int MINIMAP_LARGEMAP_ENABLED = 1; //Set to 1 to enable opening the large map with the "Map" button const int MINIMAP_LARGEMAP_OPENCLOSEFRAMES = 32; //Frames taken to open the large map const int MINIMAP_LARGEMAP_FRAMEDRAWCAP = 500; //Rough maximum of draw instructions to run per frame when loading the large map const int MINIMAP_LARGEMAP_DEBUG = 0; //Set to 1 to show all hidden squares on the large map const int C_MINIMAP_OUTLINE = 0x01; //Outline color for the minimap const int C_MINIMAP_BG = 0x0F; //Background color for the minimap const int C_MINIMAP_DEBUG = 0x02; //Color used for debug draws const int CF_HIDDENROOM = 98; //Combo flag marking minimap screens as hidden const int DMF_ENABLEMINIMAP = 1; //DMap flag used for minimaps (1-5, Script 1 by default) //Two off-screen bitmaps (0-6) to use for drawing the large map const int RT_LARGEMAP1 = 0; const int RT_LARGEMAP2 = 1; const int FFC_SCREENFREEZEA = 31; const int CMB_SCREENFREEZEA = 2; const int FFC_SCREENFREEZEB = 32; const int CMB_SCREENFREEZEB = 3; //Functions for freezing/unfreezing the screen void FreezeScreen(){ ffc a = Screen->LoadFFC(FFC_SCREENFREEZEA); a->Data = CMB_SCREENFREEZEA; ffc b = Screen->LoadFFC(FFC_SCREENFREEZEB); b->Data = CMB_SCREENFREEZEB; } void UnfreezeScreen(){ ffc a = Screen->LoadFFC(FFC_SCREENFREEZEA); a->Data = 0; ffc b = Screen->LoadFFC(FFC_SCREENFREEZEB); b->Data = 0; } const int _LML_BGCMB = 0; const int _LML_BGCS = 2304; const int _LML_LAYOUTCMB = 4608; const int _LML_LAYOUTCS = 6912; const int _LML_MARKERCMB = 9216; const int _LML_MARKERCS = 11520; int LargeMapLayout[13824]; //Size should be 48*48*6 //Indices for global variables const int _LMD_CURDRAWINDEX = 0; const int _LMD_DRAWCOUNT = 1; const int _LMD_MINX = 2; const int _LMD_MAXX = 3; const int _LMD_MINY = 4; const int _LMD_MAXY = 5; const int _LMD_LINKPOS = 6; const int _LMD_LARGEMAPSTATE = 7; const int _LMD_LARGEMAPFRAMES = 8; const int _LMD_MAPVIEWX = 9; const int _LMD_MAPVIEWY = 10; const int _LMD_MAPDEFS = 16; //Indices for map sectors (3-dimensional, map x sector x index) const int _LMD_DMAP = 0; const int _LMD_XOFF = 1; const int _LMD_YOFF = 2; const int _LMD_SECTORSIZE = 3; // const int _LMD_MAXMAPS = 4; //Max number of large maps const int _LMD_MAXMAPSECTORS = 32; //Max number of sectors for maps int LargeMapData[400]; //Size should be at least _LMD_MAPDEFS+_LMD_MAXMAPS*_LMD_MAXMAPSECTORS*_LMD_SECTORSIZE void MiniMap_Init(){ LargeMapData[_LMD_LARGEMAPSTATE] = 0; for(int i=0; i<_LMD_MAXMAPS*_LMD_MAXMAPSECTORS; ++i){ LargeMapData[_LMD_MAPDEFS+_LMD_SECTORSIZE*i+_LMD_DMAP] = -1; } Minimap_GetSectorDefinitions(); } //Defines a single sector in the large map void MiniMap_DefineSector(int map, int sector, int dmap, int xoff, int yoff){ LargeMapData[_LMD_MAPDEFS+_LMD_MAXMAPSECTORS*_LMD_SECTORSIZE*map+_LMD_SECTORSIZE*sector+_LMD_DMAP] = dmap; LargeMapData[_LMD_MAPDEFS+_LMD_MAXMAPSECTORS*_LMD_SECTORSIZE*map+_LMD_SECTORSIZE*sector+_LMD_XOFF] = 16+xoff; LargeMapData[_LMD_MAPDEFS+_LMD_MAXMAPSECTORS*_LMD_SECTORSIZE*map+_LMD_SECTORSIZE*sector+_LMD_YOFF] = 20+yoff; } void Minimap_Update(){ //Don't bother with either map if the flag is checked if(!(Game->DMapFlags[Game->GetCurDMap()]&(1<<(10+DMF_ENABLEMINIMAP)))||Game->GetCurScreen()>=0x80){ if(MINIMAP_LARGEMAP_ENABLED){ Link->InputMap = false; Link->PressMap = false; } return; } Minimap_UpdateMapSubscreen(); //Don't bother with the minimap if the large map is open if(LargeMapData[_LMD_LARGEMAPSTATE]!=0) return; int refMap; int refMarkerMap; int refScrn; //Get the maps to reference for map drawing if(MINIMAP_USELEVELNUM){ refMap = MINIMAP_MAPS+Floor(Game->GetCurLevel()/128); refMarkerMap = MINIMAP_MARKERMAPS+Floor(Game->GetCurLevel()/128); refScrn = Game->GetCurLevel()%128; } else{ refMap = MINIMAP_MAPS+Floor(Game->GetCurDMap()/128); refMarkerMap = MINIMAP_MARKERMAPS+Floor(Game->GetCurDMap()/128); refScrn = Game->GetCurDMap()%128; } int dmapOffset = Game->DMapOffset[Game->GetCurDMap()]; //Get the map X and Y position of the top-left corner of the minimap int offX = (Game->GetCurDMapScreen()%16)-Floor((MINIMAP_TILEWIDTH-1)/2); int offY = Floor(Game->GetCurDMapScreen()/16)-Floor((MINIMAP_TILEHEIGHT-1)/2); if(MINIMAP_CLAMPPOSITION){ offX = Clamp(offX, 0, MINIMAP_MAPWIDTH-MINIMAP_TILEWIDTH); offY = Clamp(offY, 0, 8-MINIMAP_TILEHEIGHT); } int bgCD = Game->GetComboData(refMap, refScrn, 160); int roomX; int roomY; int roomPos; int roomVisited; int markerState; int roomCD; int roomCS; int roomCF; int markerCD; int markerCS; int markerCT; //Draw the rectangle background if(C_MINIMAP_BG) Screen->Rectangle(MINIMAP_LAYER, MINIMAP_X, MINIMAP_Y-56, MINIMAP_X+MINIMAP_SQUARESIZE*MINIMAP_TILEWIDTH, MINIMAP_Y-56+MINIMAP_SQUARESIZE*MINIMAP_TILEHEIGHT, C_MINIMAP_BG, 1, 0, 0, 0, true, 128); //Cycle through all minimap squares to draw for(int x=0; x<MINIMAP_TILEWIDTH; ++x){ for(int y=0; y<MINIMAP_TILEHEIGHT; ++y){ roomX = offX+x; roomY = offY+y; roomPos = roomX+roomY*16; if(roomX>=0&&roomX<=MINIMAP_MAPWIDTH-1&&roomY>=0&&roomY<=7){ roomCD = Game->GetComboData(refMap, refScrn, roomPos); roomCS = Game->GetComboCSet(refMap, refScrn, roomPos); roomCF = Game->GetComboFlag(refMap, refScrn, roomPos); markerCD = Game->GetComboData(refMarkerMap, refScrn, roomPos); markerCS = Game->GetComboCSet(refMarkerMap, refScrn, roomPos); markerCT = Game->GetComboType(refMarkerMap, refScrn, roomPos); roomVisited = 0; markerState = 0; //Check if Link has visited or is in this screen if(roomPos==Game->GetCurDMapScreen()) roomVisited = 2; else if(roomPos+dmapOffset<0x80&&Game->GetScreenState(Game->GetCurMap(), roomPos+dmapOffset, ST_VISITED)) roomVisited = 1; //Hidden rooms are marked with a flag so they're visible in the editor but not in normal play until visited if(roomCF==CF_HIDDENROOM&&roomVisited==0) roomCD = 0; //Prevent showing unvisited rooms without the map if(!(Game->LItems[Game->GetCurLevel()]&LI_MAP)&&MINIMAP_REQUIREDUNGEONMAP&&roomVisited==0) roomCD = 0; //If the combo at that position >0, this is a valid screen to draw if(roomCD){ //If the background combo was set, draw that under the screen first if(bgCD){ Screen->FastCombo(MINIMAP_LAYER, MINIMAP_X+x*MINIMAP_SQUARESIZE, MINIMAP_Y-56+y*MINIMAP_SQUARESIZE, bgCD-1+roomVisited, roomCS, 128); Screen->FastCombo(MINIMAP_LAYER, MINIMAP_X+x*MINIMAP_SQUARESIZE, MINIMAP_Y-56+y*MINIMAP_SQUARESIZE, roomCD, roomCS, 128); } else Screen->FastCombo(MINIMAP_LAYER, MINIMAP_X+x*MINIMAP_SQUARESIZE, MINIMAP_Y-56+y*MINIMAP_SQUARESIZE, roomCD+roomVisited, roomCS, 128); //Check for markers on the layer screen if(markerCD&&(roomVisited||!MINIMAP_MARKERSREQUIREVISITED)&&(Game->LItems[Game->GetCurLevel()]&LI_COMPASS||!MINIMAP_REQUIRECOMPASS)&&roomPos+dmapOffset<0x80){ //Item or Special Item if(markerCT==CT_CHEST){ if(Game->GetScreenState(Game->GetCurMap(), roomPos+dmapOffset, ST_ITEM)||Game->GetScreenState(Game->GetCurMap(), roomPos+dmapOffset, ST_SPECIALITEM)) markerState = 1; } //Item and Special Item (4 states) else if(markerCT==CT_BOSSCHEST){ if(Game->GetScreenState(Game->GetCurMap(), roomPos+dmapOffset, ST_SPECIALITEM)) ++markerState; if(Game->GetScreenState(Game->GetCurMap(), roomPos+dmapOffset, ST_ITEM)) markerState += 2; } //Boss level state else if(markerCT==CT_DAMAGE1){ if(Game->LItems[Game->GetCurLevel()]&LI_BOSS) markerState = 1; } //Lock block else if(markerCT==CT_LOCKBLOCK){ if(Game->GetScreenState(Game->GetCurMap(), roomPos+dmapOffset, ST_LOCKBLOCK)) markerState = 1; } //Boss lock else if(markerCT==CT_BOSSLOCKBLOCK){ if(Game->GetScreenState(Game->GetCurMap(), roomPos+dmapOffset, ST_BOSSLOCKBLOCK)) markerState = 1; } //Secret combo else if(markerCT==CT_STEP){ if(Game->GetScreenState(Game->GetCurMap(), roomPos+dmapOffset, ST_SECRET)) markerState = 1; } Screen->FastCombo(MINIMAP_LAYER, MINIMAP_X+x*MINIMAP_SQUARESIZE, MINIMAP_Y-56+y*MINIMAP_SQUARESIZE, markerCD+markerState, markerCS, 128); } } } } } //Draw the rectangle outline if(C_MINIMAP_OUTLINE) Screen->Rectangle(MINIMAP_LAYER, MINIMAP_X, MINIMAP_Y-56, MINIMAP_X+MINIMAP_SQUARESIZE*MINIMAP_TILEWIDTH, MINIMAP_Y-56+MINIMAP_SQUARESIZE*MINIMAP_TILEHEIGHT, C_MINIMAP_OUTLINE, 1, 0, 0, 0, false, 128); } void Minimap_UpdateMapSubscreen(){ int i; int j; if(!MINIMAP_LARGEMAP_ENABLED) return; if(LargeMapData[_LMD_LARGEMAPSTATE]==0){ //Map is closed if(Link->PressMap){ LargeMapData[_LMD_LARGEMAPSTATE] = 1; LargeMapData[_LMD_LARGEMAPFRAMES] = 0; FreezeScreen(); int currentMap = Minimap_GetCurrentLargeMap(); for(i=0; i<2304; ++i){ LargeMapLayout[_LML_BGCMB+i] = 0; LargeMapLayout[_LML_LAYOUTCMB+i] = 0; LargeMapLayout[_LML_MARKERCMB+i] = 0; } //If the current DMap isn't in the map array, just load that one if(currentMap==-1){ Minimap_Overlay(Game->GetCurDMap(), 16, 20); } //Else load every other DMap in the same large map else{ for(i=0; i<_LMD_MAXMAPSECTORS; ++i){ int dmap = LargeMapData[_LMD_MAPDEFS+_LMD_MAXMAPSECTORS*_LMD_SECTORSIZE*currentMap+_LMD_SECTORSIZE*i+_LMD_DMAP]; if(dmap>-1){ int xoff = LargeMapData[_LMD_MAPDEFS+_LMD_MAXMAPSECTORS*_LMD_SECTORSIZE*currentMap+_LMD_SECTORSIZE*i+_LMD_XOFF]; int yoff = LargeMapData[_LMD_MAPDEFS+_LMD_MAXMAPSECTORS*_LMD_SECTORSIZE*currentMap+_LMD_SECTORSIZE*i+_LMD_YOFF]; Minimap_Overlay(dmap, xoff, yoff); } } } Screen->SetRenderTarget(RT_LARGEMAP1); Screen->Rectangle(0, 0, 0, 511, 511, 0x00, 1, 0, 0, 0, true, 128); Screen->SetRenderTarget(RT_LARGEMAP2); Screen->Rectangle(0, 0, 0, 511, 511, 0x00, 1, 0, 0, 0, true, 128); LargeMapData[_LMD_CURDRAWINDEX] = 0; LargeMapData[_LMD_DRAWCOUNT] = 0; LargeMapData[_LMD_MINX] = -1; LargeMapData[_LMD_MINY] = -1; LargeMapData[_LMD_MAXX] = -1; LargeMapData[_LMD_MAXY] = -1; } } else if(LargeMapData[_LMD_LARGEMAPSTATE]==1){ //Map is opening Minimap_LoadLargeMapData(); if(LargeMapData[_LMD_LARGEMAPFRAMES]>MINIMAP_LARGEMAP_OPENCLOSEFRAMES*0.6666){ Screen->Rectangle(MINIMAP_LAYER, 0, -56, 255, 175, C_MINIMAP_BG, 1, 0, 0, 0, true, 128); } else{ if(LargeMapData[_LMD_LARGEMAPFRAMES]>MINIMAP_LARGEMAP_OPENCLOSEFRAMES*0.3333) Screen->Rectangle(MINIMAP_LAYER, 0, -56, 255, 175, C_MINIMAP_BG, 1, 0, 0, 0, true, 64); Screen->Rectangle(MINIMAP_LAYER, 0, -56, 255, 175, C_MINIMAP_BG, 1, 0, 0, 0, true, 64); } if(LargeMapData[_LMD_LARGEMAPFRAMES]<MINIMAP_LARGEMAP_OPENCLOSEFRAMES) ++LargeMapData[_LMD_LARGEMAPFRAMES]; else{ LargeMapData[_LMD_LARGEMAPSTATE] = 2; //Position the camera in the center of the map LargeMapData[_LMD_MAPVIEWX] = Floor((LargeMapData[_LMD_MINX]+LargeMapData[_LMD_MAXX]+1)*MINIMAP_SQUARESIZE/2)-128; LargeMapData[_LMD_MAPVIEWY] = Floor((LargeMapData[_LMD_MINY]+LargeMapData[_LMD_MAXY]+1)*MINIMAP_SQUARESIZE/2)-128; } } else if(LargeMapData[_LMD_LARGEMAPSTATE]==2){ //Map is open Screen->Rectangle(MINIMAP_LAYER, 0, -56, 255, 175, C_MINIMAP_BG, 1, 0, 0, 0, true, 128); Minimap_DrawBitmaps(LargeMapData[_LMD_MAPVIEWX], LargeMapData[_LMD_MAPVIEWY]); if(Link->PressMap){ LargeMapData[_LMD_LARGEMAPSTATE] = 3; LargeMapData[_LMD_LARGEMAPFRAMES] = MINIMAP_LARGEMAP_OPENCLOSEFRAMES; } //Allow the camera to pan around LargeMapData[_LMD_MAPVIEWX] += Cond(Link->InputLeft, -2, 0) + Cond(Link->InputRight, 2, 0); LargeMapData[_LMD_MAPVIEWY] += Cond(Link->InputUp, -2, 0) + Cond(Link->InputDown, 2, 0); int edgeDist = 48; if(LargeMapData[_LMD_MAPVIEWX]<LargeMapData[_LMD_MINX]*MINIMAP_SQUARESIZE-edgeDist&&LargeMapData[_LMD_MAPVIEWX]>(LargeMapData[_LMD_MAXX]+1)*MINIMAP_SQUARESIZE+edgeDist-256) LargeMapData[_LMD_MAPVIEWX] = Floor((LargeMapData[_LMD_MINX]+LargeMapData[_LMD_MAXX]+1)*MINIMAP_SQUARESIZE/2)-128; else if(LargeMapData[_LMD_MAPVIEWX]<LargeMapData[_LMD_MINX]*MINIMAP_SQUARESIZE-edgeDist) LargeMapData[_LMD_MAPVIEWX] = LargeMapData[_LMD_MINX]*MINIMAP_SQUARESIZE-edgeDist; else if(LargeMapData[_LMD_MAPVIEWX]>(LargeMapData[_LMD_MAXX]+1)*MINIMAP_SQUARESIZE+edgeDist-256) LargeMapData[_LMD_MAPVIEWX] = (LargeMapData[_LMD_MAXX]+1)*MINIMAP_SQUARESIZE+edgeDist-256; if(LargeMapData[_LMD_MAPVIEWY]<LargeMapData[_LMD_MINY]*MINIMAP_SQUARESIZE-edgeDist&&LargeMapData[_LMD_MAPVIEWY]>(LargeMapData[_LMD_MAXY]+1)*MINIMAP_SQUARESIZE+24+edgeDist-256) LargeMapData[_LMD_MAPVIEWY] = Floor((LargeMapData[_LMD_MINY]+LargeMapData[_LMD_MAXY]+1)*MINIMAP_SQUARESIZE/2)-128; else if(LargeMapData[_LMD_MAPVIEWY]<LargeMapData[_LMD_MINY]*MINIMAP_SQUARESIZE-edgeDist) LargeMapData[_LMD_MAPVIEWY] = LargeMapData[_LMD_MINY]*MINIMAP_SQUARESIZE-edgeDist; else if(LargeMapData[_LMD_MAPVIEWY]>(LargeMapData[_LMD_MAXY]+1)*MINIMAP_SQUARESIZE+24+edgeDist-256) LargeMapData[_LMD_MAPVIEWY] = (LargeMapData[_LMD_MAXY]+1)*MINIMAP_SQUARESIZE+24+edgeDist-256; } else if(LargeMapData[_LMD_LARGEMAPSTATE]==3){ //Map is closed if(LargeMapData[_LMD_LARGEMAPFRAMES]>MINIMAP_LARGEMAP_OPENCLOSEFRAMES*0.6666){ Screen->Rectangle(MINIMAP_LAYER, 0, -56, 255, 175, C_MINIMAP_BG, 1, 0, 0, 0, true, 128); } else{ if(LargeMapData[_LMD_LARGEMAPFRAMES]>MINIMAP_LARGEMAP_OPENCLOSEFRAMES*0.3333) Screen->Rectangle(MINIMAP_LAYER, 0, -56, 255, 175, C_MINIMAP_BG, 1, 0, 0, 0, true, 64); Screen->Rectangle(MINIMAP_LAYER, 0, -56, 255, 175, C_MINIMAP_BG, 1, 0, 0, 0, true, 64); } if(LargeMapData[_LMD_LARGEMAPFRAMES]) --LargeMapData[_LMD_LARGEMAPFRAMES]; else{ LargeMapData[_LMD_LARGEMAPSTATE] = 0; UnfreezeScreen(); } } Screen->SetRenderTarget(RT_SCREEN); Link->InputMap = false; Link->PressMap = false; } void Minimap_DrawBitmaps(int x, int y){ int origX = x; int origY = y; int sx = 0; int sy = 0; int w = 256; int h = 256; int offsc; //Allow the bitmap draws to go off the edges of the bitmap. //I don't like this math and I don't trust it. //Me and spatial awareness never got along great. if(x<0){ offsc = -x; x = 0; sx += offsc; w -= offsc; } else if(x+w-1>511){ offsc = ((x+w-1)-511); w -= offsc; } if(y<0){ offsc = -y; y = 0; sy += offsc; h -= offsc; } else if(y+h-1>511){ offsc = ((y+h-1)-511); h -= offsc; } //Draw Link's position to the bitmap so it can animate (this is the only exception for animated icons on the large map) Screen->SetRenderTarget(RT_LARGEMAP1); int linkPos = LargeMapData[_LMD_LINKPOS]; int roomX = (linkPos%48)*MINIMAP_SQUARESIZE; int roomY = Floor(linkPos/48)*MINIMAP_SQUARESIZE; if(LargeMapLayout[_LML_LAYOUTCMB+linkPos]){ if(LargeMapLayout[_LML_BGCMB+linkPos]){ Screen->FastCombo(0, roomX, roomY, LargeMapLayout[_LML_BGCMB+linkPos]+1, LargeMapLayout[_LML_LAYOUTCS+linkPos], 128); Screen->FastCombo(0, roomX, roomY, LargeMapLayout[_LML_LAYOUTCMB+linkPos], LargeMapLayout[_LML_LAYOUTCS+linkPos], 128); } else{ Screen->FastCombo(0, roomX, roomY, LargeMapLayout[_LML_LAYOUTCMB+linkPos]+1, LargeMapLayout[_LML_LAYOUTCS+linkPos], 128); } } Screen->SetRenderTarget(RT_SCREEN); Screen->DrawBitmap(MINIMAP_LAYER, RT_LARGEMAP1, x, y, w, h, sx, -56+sy, w, h, 0, true); Screen->DrawBitmap(MINIMAP_LAYER, RT_LARGEMAP2, x, y, w, h, sx, -56+sy, w, h, 0, true); } int Minimap_GetCurrentLargeMap(){ for(int i=0; i<_LMD_MAXMAPS; ++i){ for(int j=0; j<_LMD_MAXMAPSECTORS; ++j){ if(LargeMapData[_LMD_MAPDEFS+_LMD_MAXMAPSECTORS*_LMD_SECTORSIZE*i+_LMD_SECTORSIZE*j+_LMD_DMAP]==Game->GetCurDMap()) return i; } } return -1; } void Minimap_Overlay(int dmap, int xoff, int yoff){ int refMap; int refMarkerMap; int refScrn; int level = Game->DMapLevel[dmap]; //Get the maps to reference for map drawing if(MINIMAP_USELEVELNUM){ refMap = MINIMAP_MAPS+Floor(level/128); refMarkerMap = MINIMAP_MARKERMAPS+Floor(level/128); refScrn = level%128; } else{ refMap = MINIMAP_MAPS+Floor(dmap/128); refMarkerMap = MINIMAP_MARKERMAPS+Floor(dmap/128); refScrn = dmap%128; } int map = Game->DMapMap[dmap]; int dmapOffset = Game->DMapOffset[dmap]; int bgCD = Game->GetComboData(refMap, refScrn, 160); int xpos; int totalX; int totalY; int roomX; int roomVisited; int markerState; int roomCD; int roomCS; int roomCF; int markerCD; int markerCS; int markerCT; for(int i=0; i<128; ++i){ xpos = i%16+dmapOffset; roomCD = Game->GetComboData(refMap, refScrn, i); if(roomCD&&xpos>=0&&xpos<=15){ totalX = (i%16)+xoff; totalY = Floor(i/16)+yoff; roomX = (i%16)+dmapOffset; if(totalX>=0&&totalX<=47&&totalY>=0&&totalY<=47&&roomX>=0&&roomX<=15){ roomCS = Game->GetComboCSet(refMap, refScrn, i); roomCF = Game->GetComboFlag(refMap, refScrn, i); markerCD = Game->GetComboData(refMarkerMap, refScrn, i); markerCS = Game->GetComboCSet(refMarkerMap, refScrn, i); markerCT = Game->GetComboType(refMarkerMap, refScrn, i); roomVisited = 0; markerState = 0; //Check if Link has visited or is in this screen if(dmap==Game->GetCurDMap()&&i==Game->GetCurDMapScreen()) LargeMapData[_LMD_LINKPOS] = ((i%16)+xoff)+48*(Floor(i/16)+yoff); if(Game->GetScreenState(map, i+dmapOffset, ST_VISITED)&&i+dmapOffset>-1) roomVisited = 1; //Hidden rooms are marked with a flag so they're visible in the editor but not in normal play until visited if(roomCF==CF_HIDDENROOM&&roomVisited==0) roomCD = 0; //Prevent showing unvisited rooms without the map if(!(Game->LItems[level]&LI_MAP)&&MINIMAP_REQUIREDUNGEONMAP&&roomVisited==0) roomCD = 0; if(roomCD){ //If the background combo was set, draw that under the screen first if(bgCD){ LargeMapLayout[_LML_BGCMB+totalX+48*totalY] = bgCD-1+roomVisited; LargeMapLayout[_LML_LAYOUTCMB+totalX+48*totalY] = roomCD; LargeMapLayout[_LML_LAYOUTCS+totalX+48*totalY] = roomCS; } else{ LargeMapLayout[_LML_LAYOUTCMB+totalX+48*totalY] = roomCD+roomVisited; LargeMapLayout[_LML_LAYOUTCS+totalX+48*totalY] = roomCS; } //Check for markers on the layer screen if(markerCD&&(roomVisited||!MINIMAP_MARKERSREQUIREVISITED)&&(Game->LItems[level]&LI_COMPASS||!MINIMAP_REQUIRECOMPASS)){ //Item or Special Item if(markerCT==CT_CHEST){ if(Game->GetScreenState(map, i+dmapOffset, ST_ITEM)||Game->GetScreenState(map, i+dmapOffset, ST_SPECIALITEM)) markerState = 1; } //Item and Special Item (4 states) else if(markerCT==CT_BOSSCHEST){ if(Game->GetScreenState(map, i+dmapOffset, ST_SPECIALITEM)) ++markerState; if(Game->GetScreenState(map, i+dmapOffset, ST_ITEM)) markerState += 2; } //Boss level state else if(markerCT==CT_DAMAGE1){ if(Game->LItems[Game->DMapLevel[dmap]]&LI_BOSS) markerState = 1; } //Lock block else if(markerCT==CT_LOCKBLOCK){ if(Game->GetScreenState(map, i+dmapOffset, ST_LOCKBLOCK)) markerState = 1; } //Boss lock else if(markerCT==CT_BOSSLOCKBLOCK){ if(Game->GetScreenState(map, i+dmapOffset, ST_BOSSLOCKBLOCK)) markerState = 1; } //Secret combo else if(markerCT==CT_STEP){ if(Game->GetScreenState(map, i+dmapOffset, ST_SECRET)) markerState = 1; } LargeMapLayout[_LML_MARKERCMB+totalX+48*totalY] = markerCD+markerState; LargeMapLayout[_LML_MARKERCS+totalX+48*totalY] = markerCS; } } } } } } void Minimap_LoadLargeMapData(){ //No need to keep drawing if everything has already been drawn if(LargeMapData[_LMD_CURDRAWINDEX]==4608) return; int i; int x; int y; //Start with the layout layer Screen->SetRenderTarget(RT_LARGEMAP1); for(i=LargeMapData[_LMD_CURDRAWINDEX]; i<2304&&LargeMapData[_LMD_DRAWCOUNT]<=MINIMAP_LARGEMAP_FRAMEDRAWCAP; ++i){ if(LargeMapLayout[_LML_LAYOUTCMB+i]){ x = i%48; y = Floor(i/48); //If this is the first room discovered, set the edges up //This should prevent it from reading the top left corner as the edge when there's nothing there if(LargeMapData[_LMD_MINX]==-1){ LargeMapData[_LMD_MINX] = x; LargeMapData[_LMD_MAXX] = x; LargeMapData[_LMD_MINY] = y; LargeMapData[_LMD_MAXY] = y; } //Record edges of the map space if(x<LargeMapData[_LMD_MINX]) LargeMapData[_LMD_MINX] = x; if(x>LargeMapData[_LMD_MAXX]) LargeMapData[_LMD_MAXX] = x; if(y<LargeMapData[_LMD_MINY]) LargeMapData[_LMD_MINY] = y; if(y>LargeMapData[_LMD_MAXY]) LargeMapData[_LMD_MAXY] = y; x = i%48*MINIMAP_SQUARESIZE; y = Floor(i/48)*MINIMAP_SQUARESIZE; if(LargeMapLayout[_LML_BGCMB+i]){ Screen->FastCombo(0, x, y, LargeMapLayout[_LML_BGCMB+i], LargeMapLayout[_LML_LAYOUTCS+i], 128); ++LargeMapData[_LMD_DRAWCOUNT]; } Screen->FastCombo(0, x, y, LargeMapLayout[_LML_LAYOUTCMB+i], LargeMapLayout[_LML_LAYOUTCS+i], 128); ++LargeMapData[_LMD_DRAWCOUNT]; } else if(MINIMAP_LARGEMAP_DEBUG){ x = i%48; y = Floor(i/48); //If this is the first room discovered, set the edges up //This should prevent it from reading the top left corner as the edge when there's nothing there if(LargeMapData[_LMD_MINX]==-1){ LargeMapData[_LMD_MINX] = x; LargeMapData[_LMD_MAXX] = x; LargeMapData[_LMD_MINY] = y; LargeMapData[_LMD_MAXY] = y; } //Record edges of the map space if(x<LargeMapData[_LMD_MINX]) LargeMapData[_LMD_MINX] = x; if(x>LargeMapData[_LMD_MAXX]) LargeMapData[_LMD_MAXX] = x; if(y<LargeMapData[_LMD_MINY]) LargeMapData[_LMD_MINY] = y; if(y>LargeMapData[_LMD_MAXY]) LargeMapData[_LMD_MAXY] = y; x *= MINIMAP_SQUARESIZE; y *= MINIMAP_SQUARESIZE; Screen->Rectangle(0, x+2, y+2, x+MINIMAP_SQUARESIZE-2, y+MINIMAP_SQUARESIZE-2, C_MINIMAP_DEBUG, 1, 0, 0, 0, false, 128); ++LargeMapData[_LMD_DRAWCOUNT]; } } LargeMapData[_LMD_CURDRAWINDEX] = i; if(LargeMapData[_LMD_DRAWCOUNT]>MINIMAP_LARGEMAP_FRAMEDRAWCAP){ Screen->SetRenderTarget(RT_SCREEN); LargeMapData[_LMD_DRAWCOUNT] = 0; return; } //Next draw the marker layer Screen->SetRenderTarget(RT_LARGEMAP2); for(i=LargeMapData[_LMD_CURDRAWINDEX]-2304; i<2304&&LargeMapData[_LMD_DRAWCOUNT]<=MINIMAP_LARGEMAP_FRAMEDRAWCAP; ++i){ if(LargeMapLayout[_LML_MARKERCMB+i]){ x = i%48*MINIMAP_SQUARESIZE; y = Floor(i/48)*MINIMAP_SQUARESIZE; Screen->FastCombo(0, x, y, LargeMapLayout[_LML_MARKERCMB+i], LargeMapLayout[_LML_MARKERCS+i], 128); ++LargeMapData[_LMD_DRAWCOUNT]; } } LargeMapData[_LMD_CURDRAWINDEX] = 2304+i; Screen->SetRenderTarget(RT_SCREEN); LargeMapData[_LMD_DRAWCOUNT] = 0; } global script MetroidvaniaMinimap_Example{ void run(){ MiniMap_Init(); while(true){ Minimap_Update(); Waitdraw(); Waitframe(); } } }