added functions for editing Tunelayer (mostly copied from other layers); put Snap(&Rect) into all Fillselection-functions (fix) and made if(Empty) more precise (fix); merged tunelayer into other functions

This commit is contained in:
HMH 2014-03-12 23:34:30 +01:00 committed by def
parent c84eaea33d
commit 12ac06f1f2

View file

@ -35,6 +35,7 @@ CLayerTiles::CLayerTiles(int w, int h)
m_Speedup = 0;
m_Front = 0;
m_Switch = 0;
m_Tune = 0;
m_pTiles = new CTile[m_Width*m_Height];
mem_zero(m_pTiles, m_Width*m_Height*sizeof(CTile));
@ -86,6 +87,8 @@ void CLayerTiles::Render()
m_pEditor->RenderTools()->RenderSpeedupOverlay(((CLayerSpeedup*)this)->m_pSpeedupTile, m_Width, m_Height, 32.0f);
if(m_Switch)
m_pEditor->RenderTools()->RenderSwitchOverlay(((CLayerSwitch*)this)->m_pSwitchTile, m_Width, m_Height, 32.0f);
if(m_Tune)
m_pEditor->RenderTools()->RenderTuneOverlay(((CLayerTune*)this)->m_pTuneTile, m_Width, m_Height, 32.0f);
}
int CLayerTiles::ConvertX(float x) const { return (int)(x/32.0f); }
@ -250,6 +253,35 @@ int CLayerTiles::BrushGrab(CLayerGroup *pBrush, CUIRect Rect)
pGrabbed->m_SwitchDelay = m_pEditor->m_SwitchDelay;
str_copy(pGrabbed->m_aFileName, m_pEditor->m_aFileName, sizeof(pGrabbed->m_aFileName));
}
else if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pTuneLayer)
{
CLayerTune *pGrabbed = new CLayerTune(r.w, r.h);
pGrabbed->m_pEditor = m_pEditor;
pGrabbed->m_TexID = m_TexID;
pGrabbed->m_Image = m_Image;
pGrabbed->m_Game = m_Game;
pBrush->AddLayer(pGrabbed);
// copy the tiles
for(int y = 0; y < r.h; y++)
for(int x = 0; x < r.w; x++)
pGrabbed->m_pTiles[y*pGrabbed->m_Width+x] = m_pTiles[(r.y+y)*m_Width+(r.x+x)];
// copy the tiles
if(!m_pEditor->Input()->KeyPressed(KEY_SPACE))
for(int y = 0; y < r.h; y++)
for(int x = 0; x < r.w; x++)
{
pGrabbed->m_pTuneTile[y*pGrabbed->m_Width+x] = ((CLayerTune*)this)->m_pTuneTile[(r.y+y)*m_Width+(r.x+x)];
if(pGrabbed->m_pTuneTile[y*pGrabbed->m_Width+x].m_Type == TILE_TUNE1)
{
m_pEditor->m_TuningNum = pGrabbed->m_pTuneTile[y*pGrabbed->m_Width+x].m_Number;
}
}
pGrabbed->m_TuningNumber = m_pEditor->m_TuningNum;
str_copy(pGrabbed->m_aFileName, m_pEditor->m_aFileName, sizeof(pGrabbed->m_aFileName));
}
else if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pFrontLayer)
{
CLayerFront *pGrabbed = new CLayerFront(r.w, r.h);
@ -350,7 +382,7 @@ void CLayerTiles::BrushFlipX()
m_pTiles[y*m_Width+m_Width-1-x] = Tmp;
}
if(!m_Game && !m_Tele && !m_Speedup)
if(!m_Game && !m_Tele && !m_Speedup && !m_Tune)
for(int y = 0; y < m_Height; y++)
for(int x = 0; x < m_Width; x++)
m_pTiles[y*m_Width+x].m_Flags ^= m_pTiles[y*m_Width+x].m_Flags&TILEFLAG_ROTATE ? TILEFLAG_HFLIP : TILEFLAG_VFLIP;
@ -366,7 +398,7 @@ void CLayerTiles::BrushFlipY()
m_pTiles[(m_Height-1-y)*m_Width+x] = Tmp;
}
if(!m_Game && !m_Tele && !m_Speedup)
if(!m_Game && !m_Tele && !m_Speedup && !m_Tune)
for(int y = 0; y < m_Height; y++)
for(int x = 0; x < m_Width; x++)
m_pTiles[y*m_Width+x].m_Flags ^= m_pTiles[y*m_Width+x].m_Flags&TILEFLAG_ROTATE ? TILEFLAG_VFLIP : TILEFLAG_HFLIP;
@ -374,13 +406,13 @@ void CLayerTiles::BrushFlipY()
void CLayerTiles::BrushRotate(float Amount)
{
int Rotation = (round(360.0f*Amount/(pi*2))/90)%4; // 0=0°, 1=90°, 2=180°, 3=270°
int Rotation = (round(360.0f*Amount/(pi*2))/90)%4; // 0=0<EFBFBD>, 1=90<39>, 2=180<38>, 3=270<37>
if(Rotation < 0)
Rotation +=4;
if(Rotation == 1 || Rotation == 3)
{
// 90° rotation
// 90<EFBFBD> rotation
CTile *pTempData = new CTile[m_Width*m_Height];
mem_copy(pTempData, m_pTiles, m_Width*m_Height*sizeof(CTile));
CTile *pDst = m_pTiles;
@ -388,7 +420,7 @@ void CLayerTiles::BrushRotate(float Amount)
for(int y = m_Height-1; y >= 0; --y, ++pDst)
{
*pDst = pTempData[y*m_Width+x];
if(!m_Game && !m_Tele && !m_Speedup)
if(!m_Game && !m_Tele && !m_Speedup && !m_Tune)
{
if(pDst->m_Flags&TILEFLAG_ROTATE)
pDst->m_Flags ^= (TILEFLAG_HFLIP|TILEFLAG_VFLIP);
@ -439,6 +471,10 @@ void CLayerTiles::Resize(int NewW, int NewH)
// resize switch layer if available
if(m_Game && m_pEditor->m_Map.m_pSwitchLayer && (m_pEditor->m_Map.m_pSwitchLayer->m_Width != NewW || m_pEditor->m_Map.m_pSwitchLayer->m_Height != NewH))
m_pEditor->m_Map.m_pSwitchLayer->Resize(NewW, NewH);
// resize tune layer if available
if(m_Game && m_pEditor->m_Map.m_pTuneLayer && (m_pEditor->m_Map.m_pTuneLayer->m_Width != NewW || m_pEditor->m_Map.m_pTuneLayer->m_Height != NewH))
m_pEditor->m_Map.m_pTuneLayer->Resize(NewW, NewH);
}
void CLayerTiles::Shift(int Direction)
@ -532,7 +568,7 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox)
}
}
}
else if(m_pEditor->m_Map.m_pGameLayer == this || m_pEditor->m_Map.m_pTeleLayer == this || m_pEditor->m_Map.m_pSpeedupLayer == this || m_pEditor->m_Map.m_pFrontLayer == this || m_pEditor->m_Map.m_pSwitchLayer == this)
else if(m_pEditor->m_Map.m_pGameLayer == this || m_pEditor->m_Map.m_pTeleLayer == this || m_pEditor->m_Map.m_pSpeedupLayer == this || m_pEditor->m_Map.m_pFrontLayer == this || m_pEditor->m_Map.m_pSwitchLayer == this || m_pEditor->m_Map.m_pTuneLayer == this)
InGameGroup = false;
if(InGameGroup)
@ -629,7 +665,7 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox)
{0},
};
if(m_pEditor->m_Map.m_pGameLayer == this || m_pEditor->m_Map.m_pTeleLayer == this || m_pEditor->m_Map.m_pSpeedupLayer == this || m_pEditor->m_Map.m_pFrontLayer == this || m_pEditor->m_Map.m_pSwitchLayer == this) // remove the image and color properties if this is the game/tele/speedup/front/switch layer
if(m_pEditor->m_Map.m_pGameLayer == this || m_pEditor->m_Map.m_pTeleLayer == this || m_pEditor->m_Map.m_pSpeedupLayer == this || m_pEditor->m_Map.m_pFrontLayer == this || m_pEditor->m_Map.m_pSwitchLayer == this || m_pEditor->m_Map.m_pTuneLayer == this) // remove the image and color properties if this is the game/tele/speedup/front/switch layer
{
aProps[3].m_pName = 0;
aProps[4].m_pName = 0;
@ -849,13 +885,13 @@ void CLayerTele::BrushFlipY()
void CLayerTele::BrushRotate(float Amount)
{
int Rotation = (round(360.0f*Amount/(pi*2))/90)%4; // 0=0°, 1=90°, 2=180°, 3=270°
int Rotation = (round(360.0f*Amount/(pi*2))/90)%4; // 0=0<EFBFBD>, 1=90<39>, 2=180<38>, 3=270<37>
if(Rotation < 0)
Rotation +=4;
if(Rotation == 1 || Rotation == 3)
{
// 90° rotation
// 90<EFBFBD> rotation
CTeleTile *pTempData1 = new CTeleTile[m_Width*m_Height];
CTile *pTempData2 = new CTile[m_Width*m_Height];
mem_copy(pTempData1, m_pTeleTile, m_Width*m_Height*sizeof(CTeleTile));
@ -887,6 +923,8 @@ void CLayerTele::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
{
if(m_Readonly)
return;
Snap(&Rect); // corrects Rect; no need of <=
int sx = ConvertX(Rect.x);
int sy = ConvertY(Rect.y);
@ -895,9 +933,9 @@ void CLayerTele::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
CLayerTele *pLt = static_cast<CLayerTele*>(pBrush);
for(int y = 0; y <= h; y++)
for(int y = 0; y < h; y++)
{
for(int x = 0; x <= w; x++)
for(int x = 0; x < w; x++)
{
int fx = x+sx;
int fy = y+sy;
@ -1097,13 +1135,13 @@ void CLayerSpeedup::BrushFlipY()
void CLayerSpeedup::BrushRotate(float Amount)
{
int Rotation = (round(360.0f*Amount/(pi*2))/90)%4; // 0=0°, 1=90°, 2=180°, 3=270°
int Rotation = (round(360.0f*Amount/(pi*2))/90)%4; // 0=0<EFBFBD>, 1=90<39>, 2=180<38>, 3=270<37>
if(Rotation < 0)
Rotation +=4;
if(Rotation == 1 || Rotation == 3)
{
// 90° rotation
// 90<EFBFBD> rotation
CSpeedupTile *pTempData1 = new CSpeedupTile[m_Width*m_Height];
CTile *pTempData2 = new CTile[m_Width*m_Height];
mem_copy(pTempData1, m_pSpeedupTile, m_Width*m_Height*sizeof(CSpeedupTile));
@ -1135,6 +1173,8 @@ void CLayerSpeedup::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
{
if(m_Readonly)
return;
Snap(&Rect); // corrects Rect; no need of <=
int sx = ConvertX(Rect.x);
int sy = ConvertY(Rect.y);
@ -1143,9 +1183,9 @@ void CLayerSpeedup::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
CLayerSpeedup *pLt = static_cast<CLayerSpeedup*>(pBrush);
for(int y = 0; y <= h; y++)
for(int y = 0; y < h; y++)
{
for(int x = 0; x <= w; x++)
for(int x = 0; x < w; x++)
{
int fx = x+sx;
int fy = y+sy;
@ -1153,7 +1193,7 @@ void CLayerSpeedup::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
if(fx < 0 || fx >= m_Width || fy < 0 || fy >= m_Height)
continue;
if(Empty)
if(Empty || (pLt->m_pTiles[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)]).m_Index != TILE_BOOST) // maybe add a function to check this cause adding new tiles manually always requires to add them here
{
m_pTiles[fy*m_Width+fx].m_Index = 0;
m_pSpeedupTile[fy*m_Width+fx].m_Force = 0;
@ -1417,6 +1457,8 @@ void CLayerSwitch::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
{
if(m_Readonly)
return;
Snap(&Rect); // corrects Rect; no need of <=
int sx = ConvertX(Rect.x);
int sy = ConvertY(Rect.y);
@ -1425,9 +1467,9 @@ void CLayerSwitch::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
CLayerSwitch *pLt = static_cast<CLayerSwitch*>(pBrush);
for(int y = 0; y <= h; y++)
for(int y = 0; y < h; y++)
{
for(int x = 0; x <= w; x++)
for(int x = 0; x < w; x++)
{
int fx = x+sx;
int fy = y+sy;
@ -1435,11 +1477,12 @@ void CLayerSwitch::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
if(fx < 0 || fx >= m_Width || fy < 0 || fy >= m_Height)
continue;
if(Empty)
if(Empty || !(pLt->m_pTiles[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)]).m_Index)
{
m_pTiles[fy*m_Width+fx].m_Index = 0;
m_pSwitchTile[fy*m_Width+fx].m_Type = 0;
m_pSwitchTile[fy*m_Width+fx].m_Number = 0;
m_pSwitchTile[fy*m_Width+fx].m_Delay = 0; // dont forget this lol
}
else
{
@ -1461,3 +1504,244 @@ void CLayerSwitch::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
}
}
}
//------------------------------------------------------
CLayerTune::CLayerTune(int w, int h)
: CLayerTiles(w, h)
{
//m_Type = LAYERTYPE_SWITCH;
str_copy(m_aName, "Tune", sizeof(m_aName));
m_Tune = 1;
m_pTuneTile = new CTuneTile[w*h];
mem_zero(m_pTuneTile, w*h*sizeof(CTuneTile));
}
CLayerTune::~CLayerTune()
{
delete[] m_pTuneTile;
}
void CLayerTune::Resize(int NewW, int NewH)
{
// resize Tune data
CTuneTile *pNewTuneData = new CTuneTile[NewW*NewH];
mem_zero(pNewTuneData, NewW*NewH*sizeof(CTuneTile));
// copy old data
for(int y = 0; y < min(NewH, m_Height); y++)
mem_copy(&pNewTuneData[y*NewW], &m_pTuneTile[y*m_Width], min(m_Width, NewW)*sizeof(CTuneTile));
// replace old
delete [] m_pTuneTile;
m_pTuneTile = pNewTuneData;
// resize tile data
CLayerTiles::Resize(NewW, NewH);
// resize gamelayer too
if(m_pEditor->m_Map.m_pGameLayer->m_Width != NewW || m_pEditor->m_Map.m_pGameLayer->m_Height != NewH)
m_pEditor->m_Map.m_pGameLayer->Resize(NewW, NewH);
}
void CLayerTune::Shift(int Direction)
{
CLayerTiles::Shift(Direction);
switch(Direction)
{
case 1:
{
// left
for(int y = 0; y < m_Height; ++y)
mem_move(&m_pTuneTile[y*m_Width], &m_pTuneTile[y*m_Width+1], (m_Width-1)*sizeof(CTuneTile));
}
break;
case 2:
{
// right
for(int y = 0; y < m_Height; ++y)
mem_move(&m_pTuneTile[y*m_Width+1], &m_pTuneTile[y*m_Width], (m_Width-1)*sizeof(CTuneTile));
}
break;
case 4:
{
// up
for(int y = 0; y < m_Height-1; ++y)
mem_copy(&m_pTuneTile[y*m_Width], &m_pTuneTile[(y+1)*m_Width], m_Width*sizeof(CTuneTile));
}
break;
case 8:
{
// down
for(int y = m_Height-1; y > 0; --y)
mem_copy(&m_pTuneTile[y*m_Width], &m_pTuneTile[(y-1)*m_Width], m_Width*sizeof(CTuneTile));
}
}
}
void CLayerTune::BrushDraw(CLayer *pBrush, float wx, float wy)
{
if(m_Readonly)
return;
CLayerTune *l = (CLayerTune *)pBrush;
int sx = ConvertX(wx);
int sy = ConvertY(wy);
if(str_comp(l->m_aFileName, m_pEditor->m_aFileName))
{
m_pEditor->m_TuningNum = l->m_TuningNumber;
}
for(int y = 0; y < l->m_Height; y++)
for(int x = 0; x < l->m_Width; x++)
{
int fx = x+sx;
int fy = y+sy;
if(fx<0 || fx >= m_Width || fy < 0 || fy >= m_Height)
continue;
if(l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TUNE1)
{
if(m_pEditor->m_TuningNum != l->m_TuningNumber)
{
m_pTuneTile[fy*m_Width+fx].m_Number = m_pEditor->m_TuningNum;
}
else if(l->m_pTuneTile[y*l->m_Width+x].m_Number)
m_pTuneTile[fy*m_Width+fx].m_Number = l->m_pTuneTile[y*l->m_Width+x].m_Number;
else
{
if(!m_pEditor->m_TuningNum)
{
m_pTuneTile[fy*m_Width+fx].m_Number = 0;
m_pTuneTile[fy*m_Width+fx].m_Type = 0;
m_pTiles[fy*m_Width+fx].m_Index = 0;
continue;
}
else
m_pTuneTile[fy*m_Width+fx].m_Number = m_pEditor->m_TuningNum;
}
m_pTuneTile[fy*m_Width+fx].m_Type = l->m_pTiles[y*l->m_Width+x].m_Index;
m_pTiles[fy*m_Width+fx].m_Index = l->m_pTiles[y*l->m_Width+x].m_Index;
}
else
{
m_pTuneTile[fy*m_Width+fx].m_Number = 0;
m_pTuneTile[fy*m_Width+fx].m_Type = 0;
m_pTiles[fy*m_Width+fx].m_Index = 0;
}
}
m_pEditor->m_Map.m_Modified = true;
}
void CLayerTune::BrushFlipX()
{
CLayerTiles::BrushFlipX();
for(int y = 0; y < m_Height; y++)
for(int x = 0; x < m_Width/2; x++)
{
CTuneTile Tmp = m_pTuneTile[y*m_Width+x];
m_pTuneTile[y*m_Width+x] = m_pTuneTile[y*m_Width+m_Width-1-x];
m_pTuneTile[y*m_Width+m_Width-1-x] = Tmp;
}
}
void CLayerTune::BrushFlipY()
{
CLayerTiles::BrushFlipY();
for(int y = 0; y < m_Height/2; y++)
for(int x = 0; x < m_Width; x++)
{
CTuneTile Tmp = m_pTuneTile[y*m_Width+x];
m_pTuneTile[y*m_Width+x] = m_pTuneTile[(m_Height-1-y)*m_Width+x];
m_pTuneTile[(m_Height-1-y)*m_Width+x] = Tmp;
}
}
void CLayerTune::BrushRotate(float Amount)
{
int Rotation = (round(360.0f*Amount/(pi*2))/90)%4; // 0=0<>, 1=90<39>, 2=180<38>, 3=270<37>
if(Rotation < 0)
Rotation +=4;
if(Rotation == 1 || Rotation == 3)
{
// 90<39> rotation
CTuneTile *pTempData1 = new CTuneTile[m_Width*m_Height];
CTile *pTempData2 = new CTile[m_Width*m_Height];
mem_copy(pTempData1, m_pTuneTile, m_Width*m_Height*sizeof(CTuneTile));
mem_copy(pTempData2, m_pTiles, m_Width*m_Height*sizeof(CTile));
CTuneTile *pDst1 = m_pTuneTile;
CTile *pDst2 = m_pTiles;
for(int x = 0; x < m_Width; ++x)
for(int y = m_Height-1; y >= 0; --y, ++pDst1, ++pDst2)
{
*pDst1 = pTempData1[y*m_Width+x];
*pDst2 = pTempData2[y*m_Width+x];
}
int Temp = m_Width;
m_Width = m_Height;
m_Height = Temp;
delete[] pTempData1;
delete[] pTempData2;
}
if(Rotation == 2 || Rotation == 3)
{
BrushFlipX();
BrushFlipY();
}
}
void CLayerTune::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect)
{
if(m_Readonly)
return;
Snap(&Rect); // corrects Rect; no need of <=
int sx = ConvertX(Rect.x);
int sy = ConvertY(Rect.y);
int w = ConvertX(Rect.w);
int h = ConvertY(Rect.h);
CLayerTune *pLt = static_cast<CLayerTune*>(pBrush);
for(int y = 0; y < h; y++)
{
for(int x = 0; x < w; x++)
{
int fx = x+sx;
int fy = y+sy;
if(fx < 0 || fx >= m_Width || fy < 0 || fy >= m_Height)
continue;
if(Empty || (pLt->m_pTiles[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)]).m_Index != TILE_TUNE1) // \o/ this fixes editor bug; TODO: use IsUsedInThisLayer here
{
m_pTiles[fy*m_Width+fx].m_Index = 0;
m_pTuneTile[fy*m_Width+fx].m_Type = 0;
m_pTuneTile[fy*m_Width+fx].m_Number = 0;
}
else
{
m_pTiles[fy*m_Width+fx] = pLt->m_pTiles[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)];
m_pTuneTile[fy*m_Width+fx].m_Type = m_pTiles[fy*m_Width+fx].m_Index;
if(m_pTiles[fy*m_Width+fx].m_Index > 0)
{
if((!pLt->m_pTuneTile[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)].m_Number && m_pEditor->m_TuningNum) || m_pEditor->m_TuningNum != pLt->m_TuningNumber)
m_pTuneTile[fy*m_Width+fx].m_Number = m_pEditor->m_TuningNum;
else
m_pTuneTile[fy*m_Width+fx].m_Number = pLt->m_pTuneTile[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)].m_Number;
}
}
}
}
}