2014-10-09 10:44:17 +00:00
|
|
|
|
2014-10-21 10:07:09 +00:00
|
|
|
#include <game/generated/client_data.h>
|
|
|
|
|
2014-10-09 10:44:17 +00:00
|
|
|
#include "editor.h"
|
|
|
|
|
2014-10-21 10:07:09 +00:00
|
|
|
static const float s_SourceVisualSize = 32.0f;
|
2014-10-09 10:44:17 +00:00
|
|
|
|
|
|
|
CLayerSounds::CLayerSounds()
|
|
|
|
{
|
|
|
|
m_Type = LAYERTYPE_SOUNDS;
|
2019-03-24 01:44:33 +00:00
|
|
|
m_aName[0] = '\0';
|
2014-10-09 10:44:17 +00:00
|
|
|
m_Sound = -1;
|
|
|
|
}
|
|
|
|
|
2022-08-17 23:07:16 +00:00
|
|
|
CLayerSounds::CLayerSounds(const CLayerSounds &Other) :
|
|
|
|
CLayer(Other)
|
|
|
|
{
|
|
|
|
m_Sound = Other.m_Sound;
|
|
|
|
m_vSources = Other.m_vSources;
|
|
|
|
}
|
|
|
|
|
2022-02-14 23:32:04 +00:00
|
|
|
CLayerSounds::~CLayerSounds() = default;
|
2014-10-09 10:44:17 +00:00
|
|
|
|
2018-08-19 17:05:42 +00:00
|
|
|
void CLayerSounds::Render(bool Tileset)
|
2014-10-09 10:44:17 +00:00
|
|
|
{
|
|
|
|
// TODO: nice texture
|
2012-08-12 10:41:50 +00:00
|
|
|
Graphics()->TextureClear();
|
2014-10-09 10:44:17 +00:00
|
|
|
Graphics()->BlendNormal();
|
|
|
|
Graphics()->QuadsBegin();
|
|
|
|
|
2014-10-11 18:05:48 +00:00
|
|
|
// draw falloff distance
|
|
|
|
Graphics()->SetColor(0.6f, 0.8f, 1.0f, 0.4f);
|
2022-06-11 19:38:18 +00:00
|
|
|
for(const auto &Source : m_vSources)
|
2014-10-11 18:05:48 +00:00
|
|
|
{
|
2014-10-12 13:10:33 +00:00
|
|
|
float OffsetX = 0;
|
|
|
|
float OffsetY = 0;
|
|
|
|
|
2022-05-24 09:24:33 +00:00
|
|
|
if(Source.m_PosEnv >= 0)
|
2014-10-12 13:10:33 +00:00
|
|
|
{
|
2022-07-01 04:42:36 +00:00
|
|
|
ColorRGBA Channels;
|
|
|
|
m_pEditor->EnvelopeEval(Source.m_PosEnvOffset, Source.m_PosEnv, Channels, m_pEditor);
|
|
|
|
OffsetX = Channels.r;
|
|
|
|
OffsetY = Channels.g;
|
2014-10-12 13:10:33 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 09:24:33 +00:00
|
|
|
switch(Source.m_Shape.m_Type)
|
2014-11-28 19:01:25 +00:00
|
|
|
{
|
|
|
|
case CSoundShape::SHAPE_CIRCLE:
|
2020-09-26 19:41:58 +00:00
|
|
|
{
|
2022-07-09 11:16:12 +00:00
|
|
|
m_pEditor->Graphics()->DrawCircle(fx2f(Source.m_Position.x) + OffsetX, fx2f(Source.m_Position.y) + OffsetY,
|
2022-05-24 09:24:33 +00:00
|
|
|
Source.m_Shape.m_Circle.m_Radius, 32);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
2022-05-24 09:24:33 +00:00
|
|
|
float Falloff = ((float)Source.m_Falloff / 255.0f);
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Falloff > 0.0f)
|
2022-07-09 11:16:12 +00:00
|
|
|
m_pEditor->Graphics()->DrawCircle(fx2f(Source.m_Position.x) + OffsetX, fx2f(Source.m_Position.y) + OffsetY,
|
2022-05-24 09:24:33 +00:00
|
|
|
Source.m_Shape.m_Circle.m_Radius * Falloff, 32);
|
2020-09-26 19:41:58 +00:00
|
|
|
break;
|
|
|
|
}
|
2014-11-28 19:01:25 +00:00
|
|
|
case CSoundShape::SHAPE_RECTANGLE:
|
2020-09-26 19:41:58 +00:00
|
|
|
{
|
2022-05-24 09:24:33 +00:00
|
|
|
float Width = fx2f(Source.m_Shape.m_Rectangle.m_Width);
|
|
|
|
float Height = fx2f(Source.m_Shape.m_Rectangle.m_Height);
|
2022-07-09 20:27:35 +00:00
|
|
|
m_pEditor->Graphics()->DrawRectExt(fx2f(Source.m_Position.x) + OffsetX - Width / 2, fx2f(Source.m_Position.y) + OffsetY - Height / 2,
|
2022-07-26 19:17:29 +00:00
|
|
|
Width, Height, 0.0f, IGraphics::CORNER_NONE);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
2022-05-24 09:24:33 +00:00
|
|
|
float Falloff = ((float)Source.m_Falloff / 255.0f);
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Falloff > 0.0f)
|
2022-07-09 20:27:35 +00:00
|
|
|
m_pEditor->Graphics()->DrawRectExt(fx2f(Source.m_Position.x) + OffsetX - Falloff * Width / 2, fx2f(Source.m_Position.y) + OffsetY - Falloff * Height / 2,
|
2022-07-26 19:17:29 +00:00
|
|
|
Width * Falloff, Height * Falloff, 0.0f, IGraphics::CORNER_NONE);
|
2020-09-26 19:41:58 +00:00
|
|
|
break;
|
|
|
|
}
|
2014-11-28 19:01:25 +00:00
|
|
|
}
|
2014-10-11 18:05:48 +00:00
|
|
|
}
|
|
|
|
|
2014-10-21 10:07:09 +00:00
|
|
|
Graphics()->QuadsEnd();
|
|
|
|
|
2014-10-11 18:05:48 +00:00
|
|
|
// draw handles
|
2014-10-21 10:07:09 +00:00
|
|
|
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_AUDIO_SOURCE].m_Id);
|
|
|
|
Graphics()->QuadsBegin();
|
|
|
|
|
|
|
|
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
m_pEditor->RenderTools()->SelectSprite(SPRITE_AUDIO_SOURCE);
|
2022-06-11 19:38:18 +00:00
|
|
|
for(const auto &Source : m_vSources)
|
2014-10-09 10:44:17 +00:00
|
|
|
{
|
2014-10-12 13:10:33 +00:00
|
|
|
float OffsetX = 0;
|
|
|
|
float OffsetY = 0;
|
|
|
|
|
2022-05-24 09:24:33 +00:00
|
|
|
if(Source.m_PosEnv >= 0)
|
2014-10-12 13:10:33 +00:00
|
|
|
{
|
2022-07-01 04:42:36 +00:00
|
|
|
ColorRGBA Channels;
|
|
|
|
m_pEditor->EnvelopeEval(Source.m_PosEnvOffset, Source.m_PosEnv, Channels, m_pEditor);
|
|
|
|
OffsetX = Channels.r;
|
|
|
|
OffsetY = Channels.g;
|
2014-10-12 13:10:33 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 09:24:33 +00:00
|
|
|
m_pEditor->RenderTools()->DrawSprite(fx2f(Source.m_Position.x) + OffsetX, fx2f(Source.m_Position.y) + OffsetY, s_SourceVisualSize * m_pEditor->m_WorldZoom);
|
2014-10-09 10:44:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Graphics()->QuadsEnd();
|
|
|
|
}
|
|
|
|
|
2019-03-28 12:41:07 +00:00
|
|
|
CSoundSource *CLayerSounds::NewSource(int x, int y)
|
2014-10-09 10:44:17 +00:00
|
|
|
{
|
|
|
|
m_pEditor->m_Map.m_Modified = true;
|
|
|
|
|
2022-06-11 19:38:18 +00:00
|
|
|
m_vSources.emplace_back();
|
|
|
|
CSoundSource *pSource = &m_vSources[m_vSources.size() - 1];
|
2014-10-09 10:44:17 +00:00
|
|
|
|
2019-03-28 12:41:07 +00:00
|
|
|
pSource->m_Position.x = f2fx(x);
|
|
|
|
pSource->m_Position.y = f2fx(y);
|
2014-10-09 10:44:17 +00:00
|
|
|
|
|
|
|
pSource->m_Loop = 1;
|
2014-11-30 11:23:05 +00:00
|
|
|
pSource->m_Pan = 1;
|
2014-10-10 17:10:57 +00:00
|
|
|
pSource->m_TimeDelay = 0;
|
2014-10-09 10:44:17 +00:00
|
|
|
|
2014-10-12 13:10:33 +00:00
|
|
|
pSource->m_PosEnv = -1;
|
|
|
|
pSource->m_PosEnvOffset = 0;
|
2014-10-11 14:05:36 +00:00
|
|
|
pSource->m_SoundEnv = -1;
|
2014-10-12 13:10:33 +00:00
|
|
|
pSource->m_SoundEnvOffset = 0;
|
2014-10-11 14:05:36 +00:00
|
|
|
|
2014-11-30 11:23:05 +00:00
|
|
|
pSource->m_Falloff = 80;
|
|
|
|
|
2014-11-28 19:01:25 +00:00
|
|
|
pSource->m_Shape.m_Type = CSoundShape::SHAPE_CIRCLE;
|
|
|
|
pSource->m_Shape.m_Circle.m_Radius = 1500;
|
|
|
|
|
2014-10-09 10:44:17 +00:00
|
|
|
return pSource;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CLayerSounds::BrushSelecting(CUIRect Rect)
|
|
|
|
{
|
|
|
|
// draw selection rectangle
|
|
|
|
IGraphics::CLineItem Array[4] = {
|
2020-09-26 19:41:58 +00:00
|
|
|
IGraphics::CLineItem(Rect.x, Rect.y, Rect.x + Rect.w, Rect.y),
|
|
|
|
IGraphics::CLineItem(Rect.x + Rect.w, Rect.y, Rect.x + Rect.w, Rect.y + Rect.h),
|
|
|
|
IGraphics::CLineItem(Rect.x + Rect.w, Rect.y + Rect.h, Rect.x, Rect.y + Rect.h),
|
|
|
|
IGraphics::CLineItem(Rect.x, Rect.y + Rect.h, Rect.x, Rect.y)};
|
2012-08-12 10:41:50 +00:00
|
|
|
Graphics()->TextureClear();
|
2014-10-09 10:44:17 +00:00
|
|
|
Graphics()->LinesBegin();
|
|
|
|
Graphics()->LinesDraw(Array, 4);
|
|
|
|
Graphics()->LinesEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
int CLayerSounds::BrushGrab(CLayerGroup *pBrush, CUIRect Rect)
|
|
|
|
{
|
|
|
|
// create new layer
|
|
|
|
CLayerSounds *pGrabbed = new CLayerSounds();
|
|
|
|
pGrabbed->m_pEditor = m_pEditor;
|
|
|
|
pGrabbed->m_Sound = m_Sound;
|
|
|
|
pBrush->AddLayer(pGrabbed);
|
|
|
|
|
2022-06-11 19:38:18 +00:00
|
|
|
for(const auto &Source : m_vSources)
|
2014-10-09 10:44:17 +00:00
|
|
|
{
|
2022-05-24 09:24:33 +00:00
|
|
|
float px = fx2f(Source.m_Position.x);
|
|
|
|
float py = fx2f(Source.m_Position.y);
|
2014-10-09 10:44:17 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(px > Rect.x && px < Rect.x + Rect.w && py > Rect.y && py < Rect.y + Rect.h)
|
2014-10-09 10:44:17 +00:00
|
|
|
{
|
2022-05-24 09:24:33 +00:00
|
|
|
CSoundSource n = Source;
|
2014-10-09 10:44:17 +00:00
|
|
|
|
|
|
|
n.m_Position.x -= f2fx(Rect.x);
|
|
|
|
n.m_Position.y -= f2fx(Rect.y);
|
|
|
|
|
2022-06-11 19:38:18 +00:00
|
|
|
pGrabbed->m_vSources.push_back(n);
|
2014-10-09 10:44:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-11 19:38:18 +00:00
|
|
|
return pGrabbed->m_vSources.empty() ? 0 : 1;
|
2014-10-09 10:44:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CLayerSounds::BrushPlace(CLayer *pBrush, float wx, float wy)
|
|
|
|
{
|
2022-06-30 22:36:32 +00:00
|
|
|
CLayerSounds *pSoundLayer = (CLayerSounds *)pBrush;
|
|
|
|
for(const auto &Source : pSoundLayer->m_vSources)
|
2014-10-09 10:44:17 +00:00
|
|
|
{
|
2022-05-24 09:24:33 +00:00
|
|
|
CSoundSource n = Source;
|
2014-10-09 10:44:17 +00:00
|
|
|
|
|
|
|
n.m_Position.x += f2fx(wx);
|
|
|
|
n.m_Position.y += f2fx(wy);
|
|
|
|
|
2022-06-11 19:38:18 +00:00
|
|
|
m_vSources.push_back(n);
|
2014-10-09 10:44:17 +00:00
|
|
|
}
|
|
|
|
m_pEditor->m_Map.m_Modified = true;
|
|
|
|
}
|
|
|
|
|
2023-03-27 15:22:17 +00:00
|
|
|
CUI::EPopupMenuFunctionResult CLayerSounds::RenderProperties(CUIRect *pToolBox)
|
2014-10-09 10:44:17 +00:00
|
|
|
{
|
|
|
|
enum
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
PROP_SOUND = 0,
|
2014-10-09 10:44:17 +00:00
|
|
|
NUM_PROPS,
|
|
|
|
};
|
|
|
|
|
|
|
|
CProperty aProps[] = {
|
2020-05-30 07:08:59 +00:00
|
|
|
{"Sound", m_Sound, PROPTYPE_SOUND, -1, 0},
|
2022-06-13 16:28:13 +00:00
|
|
|
{nullptr},
|
2014-10-09 10:44:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static int s_aIds[NUM_PROPS] = {0};
|
|
|
|
int NewVal = 0;
|
|
|
|
int Prop = m_pEditor->DoProperties(pToolBox, aProps, s_aIds, &NewVal);
|
|
|
|
if(Prop != -1)
|
2023-03-27 15:22:17 +00:00
|
|
|
{
|
2014-10-09 10:44:17 +00:00
|
|
|
m_pEditor->m_Map.m_Modified = true;
|
2023-03-27 15:22:17 +00:00
|
|
|
}
|
2014-10-09 10:44:17 +00:00
|
|
|
|
|
|
|
if(Prop == PROP_SOUND)
|
|
|
|
{
|
2020-05-30 07:08:59 +00:00
|
|
|
if(NewVal >= 0)
|
2022-06-11 19:38:18 +00:00
|
|
|
m_Sound = NewVal % m_pEditor->m_Map.m_vpSounds.size();
|
2020-05-30 07:08:59 +00:00
|
|
|
else
|
|
|
|
m_Sound = -1;
|
2014-10-09 10:44:17 +00:00
|
|
|
}
|
|
|
|
|
2023-03-27 15:22:17 +00:00
|
|
|
return CUI::POPUP_KEEP_OPEN;
|
2014-10-09 10:44:17 +00:00
|
|
|
}
|
|
|
|
|
2014-10-11 14:05:36 +00:00
|
|
|
void CLayerSounds::ModifySoundIndex(INDEX_MODIFY_FUNC Func)
|
2014-10-09 10:44:17 +00:00
|
|
|
{
|
2014-10-11 14:05:36 +00:00
|
|
|
Func(&m_Sound);
|
2014-10-09 10:44:17 +00:00
|
|
|
}
|
2014-10-11 14:05:36 +00:00
|
|
|
|
|
|
|
void CLayerSounds::ModifyEnvelopeIndex(INDEX_MODIFY_FUNC Func)
|
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
for(auto &Source : m_vSources)
|
2020-11-01 22:04:33 +00:00
|
|
|
{
|
2022-05-24 09:24:33 +00:00
|
|
|
Func(&Source.m_SoundEnv);
|
|
|
|
Func(&Source.m_PosEnv);
|
2020-11-01 22:04:33 +00:00
|
|
|
}
|
2015-08-22 13:27:41 +00:00
|
|
|
}
|
2022-08-17 23:07:16 +00:00
|
|
|
|
|
|
|
CLayer *CLayerSounds::Duplicate() const
|
|
|
|
{
|
|
|
|
return new CLayerSounds(*this);
|
|
|
|
}
|