1 /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2 /* If you are missing that file, acquire a complete release at teeworlds.com. */
3 #ifndef GAME_EDITOR_EDITOR_H
4 #define GAME_EDITOR_EDITOR_H
9 #include <base/system.h>
11 #include <base/tl/algorithm.h>
12 #include <base/tl/array.h>
13 #include <base/tl/sorted_array.h>
14 #include <base/tl/string.h>
16 #include <game/client/ui.h>
17 #include <game/mapitems.h>
18 #include <game/client/render.h>
20 #include <engine/shared/config.h>
21 #include <engine/shared/datafile.h>
22 #include <engine/editor.h>
23 #include <engine/graphics.h>
27 typedef void (*INDEX_MODIFY_FUNC
)(int *pIndex
);
29 //CRenderTools m_RenderTools;
51 array
<CEnvPoint
> m_lPoints
;
53 float m_Bottom
, m_Top
;
65 sort(m_lPoints
.all());
69 void FindTopBottom(int ChannelMask
)
71 m_Top
= -1000000000.0f
;
72 m_Bottom
= 1000000000.0f
;
73 for(int i
= 0; i
< m_lPoints
.size(); i
++)
75 for(int c
= 0; c
< m_Channels
; c
++)
77 if(ChannelMask
&(1<<c
))
79 float v
= fx2f(m_lPoints
[i
].m_aValues
[c
]);
80 if(v
> m_Top
) m_Top
= v
;
81 if(v
< m_Bottom
) m_Bottom
= v
;
87 int Eval(float Time
, float *pResult
)
89 CRenderTools::RenderEvalEnvelope(m_lPoints
.base_ptr(), m_lPoints
.size(), m_Channels
, Time
, pResult
);
93 void AddPoint(int Time
, int v0
, int v1
=0, int v2
=0, int v3
=0)
101 p
.m_Curvetype
= CURVETYPE_LINEAR
;
109 return m_lPoints
[m_lPoints
.size()-1].m_Time
*(1.0f
/1000.0f
);
122 class CEditor
*m_pEditor
;
123 class IGraphics
*Graphics();
124 class ITextRender
*TextRender();
128 m_Type
= LAYERTYPE_INVALID
;
129 str_copy(m_aName
, "(invalid)", sizeof(m_aName
));
142 virtual void BrushSelecting(CUIRect Rect
) {}
143 virtual int BrushGrab(CLayerGroup
*pBrush
, CUIRect Rect
) { return 0; }
144 virtual void FillSelection(bool Empty
, CLayer
*pBrush
, CUIRect Rect
) {}
145 virtual void BrushDraw(CLayer
*pBrush
, float x
, float y
) {}
146 virtual void BrushPlace(CLayer
*pBrush
, float x
, float y
) {}
147 virtual void BrushFlipX() {}
148 virtual void BrushFlipY() {}
149 virtual void BrushRotate(float Amount
) {}
151 virtual void Render() {}
152 virtual int RenderProperties(CUIRect
*pToolbox
) { return 0; }
154 virtual void ModifyImageIndex(INDEX_MODIFY_FUNC pfnFunc
) {}
155 virtual void ModifyEnvelopeIndex(INDEX_MODIFY_FUNC pfnFunc
) {}
157 virtual void GetSize(float *w
, float *h
) { *w
= 0; *h
= 0;}
171 class CEditorMap
*m_pMap
;
173 array
<CLayer
*> m_lLayers
;
196 void Convert(CUIRect
*pRect
);
199 void Mapping(float *pPoints
);
201 void GetSize(float *w
, float *h
);
203 void DeleteLayer(int Index
);
204 int SwapLayers(int Index0
, int Index1
);
208 return m_lLayers
.size() == 0;
213 m_lLayers
.delete_all();
216 void AddLayer(CLayer
*l
);
218 void ModifyImageIndex(INDEX_MODIFY_FUNC Func
)
220 for(int i
= 0; i
< m_lLayers
.size(); i
++)
221 m_lLayers
[i
]->ModifyImageIndex(Func
);
224 void ModifyEnvelopeIndex(INDEX_MODIFY_FUNC Func
)
226 for(int i
= 0; i
< m_lLayers
.size(); i
++)
227 m_lLayers
[i
]->ModifyEnvelopeIndex(Func
);
231 class CEditorImage
: public CImageInfo
236 CEditorImage(CEditor
*pEditor
)
237 : m_AutoMapper(pEditor
)
251 void AnalyseTileFlags();
256 unsigned char m_aTileFlags
[256];
257 class CAutoMapper m_AutoMapper
;
262 void MakeGameGroup(CLayerGroup
*pGroup
);
263 void MakeGameLayer(CLayer
*pLayer
);
273 array
<CLayerGroup
*> m_lGroups
;
274 array
<CEditorImage
*> m_lImages
;
275 array
<CEnvelope
*> m_lEnvelopes
;
277 class CLayerGame
*m_pGameLayer
;
278 CLayerGroup
*m_pGameGroup
;
280 CEnvelope
*NewEnvelope(int Channels
)
283 CEnvelope
*e
= new CEnvelope(Channels
);
288 void DeleteEnvelope(int Index
);
290 CLayerGroup
*NewGroup()
293 CLayerGroup
*g
= new CLayerGroup
;
299 int SwapGroups(int Index0
, int Index1
)
301 if(Index0
< 0 || Index0
>= m_lGroups
.size()) return Index0
;
302 if(Index1
< 0 || Index1
>= m_lGroups
.size()) return Index0
;
303 if(Index0
== Index1
) return Index0
;
305 swap(m_lGroups
[Index0
], m_lGroups
[Index1
]);
309 void DeleteGroup(int Index
)
311 if(Index
< 0 || Index
>= m_lGroups
.size()) return;
313 delete m_lGroups
[Index
];
314 m_lGroups
.remove_index(Index
);
317 void ModifyImageIndex(INDEX_MODIFY_FUNC pfnFunc
)
320 for(int i
= 0; i
< m_lGroups
.size(); i
++)
321 m_lGroups
[i
]->ModifyImageIndex(pfnFunc
);
324 void ModifyEnvelopeIndex(INDEX_MODIFY_FUNC pfnFunc
)
327 for(int i
= 0; i
< m_lGroups
.size(); i
++)
328 m_lGroups
[i
]->ModifyEnvelopeIndex(pfnFunc
);
332 void CreateDefault(int EntitiesTexture
);
335 int Save(class IStorage
*pStorage
, const char *pFilename
);
336 int Load(class IStorage
*pStorage
, const char *pFilename
, int StorageType
);
367 class CLayerTiles
: public CLayer
370 CLayerTiles(int w
, int h
);
373 void Resize(int NewW
, int NewH
);
374 void Shift(int Direction
);
377 virtual void Render();
379 int ConvertX(float x
) const;
380 int ConvertY(float y
) const;
381 void Convert(CUIRect Rect
, RECTi
*pOut
);
382 void Snap(CUIRect
*pRect
);
383 void Clamp(RECTi
*pRect
);
385 virtual void BrushSelecting(CUIRect Rect
);
386 virtual int BrushGrab(CLayerGroup
*pBrush
, CUIRect Rect
);
387 virtual void FillSelection(bool Empty
, CLayer
*pBrush
, CUIRect Rect
);
388 virtual void BrushDraw(CLayer
*pBrush
, float wx
, float wy
);
389 virtual void BrushFlipX();
390 virtual void BrushFlipY();
391 virtual void BrushRotate(float Amount
);
393 virtual void ShowInfo();
394 virtual int RenderProperties(CUIRect
*pToolbox
);
396 virtual void ModifyImageIndex(INDEX_MODIFY_FUNC pfnFunc
);
397 virtual void ModifyEnvelopeIndex(INDEX_MODIFY_FUNC pfnFunc
);
399 void PrepareForSave();
401 void GetSize(float *w
, float *h
) { *w
= m_Width
*32.0f
; *h
= m_Height
*32.0f
; }
410 int m_ColorEnvOffset
;
414 class CLayerQuads
: public CLayer
420 virtual void Render();
423 virtual void BrushSelecting(CUIRect Rect
);
424 virtual int BrushGrab(CLayerGroup
*pBrush
, CUIRect Rect
);
425 virtual void BrushPlace(CLayer
*pBrush
, float wx
, float wy
);
426 virtual void BrushFlipX();
427 virtual void BrushFlipY();
428 virtual void BrushRotate(float Amount
);
430 virtual int RenderProperties(CUIRect
*pToolbox
);
432 virtual void ModifyImageIndex(INDEX_MODIFY_FUNC pfnFunc
);
433 virtual void ModifyEnvelopeIndex(INDEX_MODIFY_FUNC pfnFunc
);
435 void GetSize(float *w
, float *h
);
438 array
<CQuad
> m_lQuads
;
441 class CLayerGame
: public CLayerTiles
444 CLayerGame(int w
, int h
);
447 virtual int RenderProperties(CUIRect
*pToolbox
);
450 class CEditor
: public IEditor
452 class IInput
*m_pInput
;
453 class IClient
*m_pClient
;
454 class IConsole
*m_pConsole
;
455 class IGraphics
*m_pGraphics
;
456 class ITextRender
*m_pTextRender
;
457 class IStorage
*m_pStorage
;
458 CRenderTools m_RenderTools
;
461 class IInput
*Input() { return m_pInput
; };
462 class IClient
*Client() { return m_pClient
; };
463 class IConsole
*Console() { return m_pConsole
; };
464 class IGraphics
*Graphics() { return m_pGraphics
; };
465 class ITextRender
*TextRender() { return m_pTextRender
; };
466 class IStorage
*Storage() { return m_pStorage
; };
467 CUI
*UI() { return &m_UI
; }
468 CRenderTools
*RenderTools() { return &m_RenderTools
; }
470 CEditor() : m_TilesetPicker(16, 16)
477 m_Mode
= MODE_LAYERS
;
481 m_GridActive
= false;
485 m_aFileSaveName
[0] = 0;
486 m_ValidSaveFilename
= false;
488 m_PopupEventActivated
= false;
489 m_PopupEventWasActivated
= false;
491 m_FileDialogStorageType
= 0;
492 m_pFileDialogTitle
= 0;
493 m_pFileDialogButtonText
= 0;
494 m_pFileDialogUser
= 0;
495 m_aFileDialogFileName
[0] = 0;
496 m_aFileDialogCurrentFolder
[0] = 0;
497 m_aFileDialogCurrentLink
[0] = 0;
498 m_pFileDialogPath
= m_aFileDialogCurrentFolder
;
499 m_aFileDialogActivate
= false;
500 m_FileDialogScrollValue
= 0.0f
;
501 m_FilesSelectedIndex
= -1;
508 m_EditorOffsetX
= 0.0f
;
509 m_EditorOffsetY
= 0.0f
;
514 m_ShowMousePointer
= true;
521 m_ProofBorders
= false;
523 m_ShowTileInfo
= false;
530 m_ShowEnvelopeEditor
= 0;
532 m_ShowEnvelopePreview
= 0;
533 m_SelectedQuadEnvelope
= -1;
534 m_SelectedEnvelopeChannel
= -1;
536 ms_CheckerTexture
= 0;
537 ms_BackgroundTexture
= 0;
538 ms_CursorTexture
= 0;
539 ms_EntitiesTexture
= 0;
541 ms_pUiGotContext
= 0;
545 virtual void UpdateAndRender();
546 virtual bool HasUnsavedData() { return m_Map
.m_Modified
; }
548 void FilelistPopulate(int StorageType
);
549 void InvokeFileDialog(int StorageType
, int FileType
, const char *pTitle
, const char *pButtonText
,
550 const char *pBasepath
, const char *pDefaultName
,
551 void (*pfnFunc
)(const char *pFilename
, int StorageType
, void *pUser
), void *pUser
);
553 void Reset(bool CreateDefault
=true);
554 int Save(const char *pFilename
);
555 int Load(const char *pFilename
, int StorageType
);
556 int Append(const char *pFilename
, int StorageType
);
559 CQuad
*GetSelectedQuad();
560 CLayer
*GetSelectedLayerType(int Index
, int Type
);
561 CLayer
*GetSelectedLayer(int Index
);
562 CLayerGroup
*GetSelectedGroup();
564 int DoProperties(CUIRect
*pToolbox
, CProperty
*pProps
, int *pIDs
, int *pNewVal
);
568 const char *m_pTooltip
;
573 char m_aFileName
[512];
574 char m_aFileSaveName
[512];
575 bool m_ValidSaveFilename
;
585 int m_PopupEventType
;
586 int m_PopupEventActivated
;
587 int m_PopupEventWasActivated
;
594 MAX_PATH_LENGTH
= 512
597 int m_FileDialogStorageType
;
598 const char *m_pFileDialogTitle
;
599 const char *m_pFileDialogButtonText
;
600 void (*m_pfnFileDialogFunc
)(const char *pFileName
, int StorageType
, void *pUser
);
601 void *m_pFileDialogUser
;
602 char m_aFileDialogFileName
[MAX_PATH_LENGTH
];
603 char m_aFileDialogCurrentFolder
[MAX_PATH_LENGTH
];
604 char m_aFileDialogCurrentLink
[MAX_PATH_LENGTH
];
605 char *m_pFileDialogPath
;
606 bool m_aFileDialogActivate
;
607 int m_FileDialogFileType
;
608 float m_FileDialogScrollValue
;
609 int m_FilesSelectedIndex
;
610 char m_FileDialogNewFolderName
[64];
611 char m_FileDialogErrString
[64];
615 char m_aFilename
[128];
621 bool operator<(const CFilelistItem
&Other
) { return !str_comp(m_aFilename
, "..") ? true : !str_comp(Other
.m_aFilename
, "..") ? false :
622 m_IsDir
&& !Other
.m_IsDir
? true : !m_IsDir
&& Other
.m_IsDir
? false :
623 str_comp_filenames(m_aFilename
, Other
.m_aFilename
) < 0; }
625 sorted_array
<CFilelistItem
> m_FileList
;
630 float m_WorldOffsetX
;
631 float m_WorldOffsetY
;
632 float m_EditorOffsetX
;
633 float m_EditorOffsetY
;
637 bool m_ShowMousePointer
;
642 float m_MouseDeltaWx
;
643 float m_MouseDeltaWy
;
648 int64 m_AnimateStart
;
650 float m_AnimateSpeed
;
652 int m_ShowEnvelopeEditor
;
653 int m_ShowEnvelopePreview
; //Values: 0-Off|1-Selected Envelope|2-All
659 int m_SelectedPoints
;
660 int m_SelectedEnvelope
;
661 int m_SelectedEnvelopeChannel
;
662 int m_SelectedQuadEnvelope
;
665 static int ms_CheckerTexture
;
666 static int ms_BackgroundTexture
;
667 static int ms_CursorTexture
;
668 static int ms_EntitiesTexture
;
671 CLayerTiles m_TilesetPicker
;
673 static const void *ms_pUiGotContext
;
677 static void EnvelopeEval(float TimeOffset
, int Env
, float *pChannels
, void *pUser
);
680 int DoButton_Editor_Common(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
681 int DoButton_Editor(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
683 int DoButton_Tab(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
684 int DoButton_Ex(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
, int Corners
, float FontSize
=10.0f
);
685 int DoButton_ButtonDec(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
686 int DoButton_ButtonInc(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
688 int DoButton_File(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
690 int DoButton_Menu(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
691 int DoButton_MenuItem(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
=0, const char *pToolTip
=0);
693 int DoEditBox(void *pID
, const CUIRect
*pRect
, char *pStr
, unsigned StrSize
, float FontSize
, float *Offset
, bool Hidden
=false, int Corners
=CUI::CORNER_ALL
);
695 void RenderBackground(CUIRect View
, int Texture
, float Size
, float Brightness
);
697 void RenderGrid(CLayerGroup
*pGroup
);
699 void UiInvokePopupMenu(void *pID
, int Flags
, float X
, float Y
, float W
, float H
, int (*pfnFunc
)(CEditor
*pEditor
, CUIRect Rect
), void *pExtra
=0);
700 void UiDoPopupMenu();
702 int UiDoValueSelector(void *pID
, CUIRect
*pRect
, const char *pLabel
, int Current
, int Min
, int Max
, int Step
, float Scale
, const char *pToolTip
);
704 static int PopupGroup(CEditor
*pEditor
, CUIRect View
);
705 static int PopupLayer(CEditor
*pEditor
, CUIRect View
);
706 static int PopupQuad(CEditor
*pEditor
, CUIRect View
);
707 static int PopupPoint(CEditor
*pEditor
, CUIRect View
);
708 static int PopupNewFolder(CEditor
*pEditor
, CUIRect View
);
709 static int PopupEvent(CEditor
*pEditor
, CUIRect View
);
710 static int PopupSelectImage(CEditor
*pEditor
, CUIRect View
);
711 static int PopupSelectGametileOp(CEditor
*pEditor
, CUIRect View
);
712 static int PopupImage(CEditor
*pEditor
, CUIRect View
);
713 static int PopupMenuFile(CEditor
*pEditor
, CUIRect View
);
714 static int PopupSelectConfigAutoMap(CEditor
*pEditor
, CUIRect View
);
716 static void CallbackOpenMap(const char *pFileName
, int StorageType
, void *pUser
);
717 static void CallbackAppendMap(const char *pFileName
, int StorageType
, void *pUser
);
718 static void CallbackSaveMap(const char *pFileName
, int StorageType
, void *pUser
);
720 void PopupSelectImageInvoke(int Current
, float x
, float y
);
721 int PopupSelectImageResult();
723 void PopupSelectGametileOpInvoke(float x
, float y
);
724 int PopupSelectGameTileOpResult();
726 void PopupSelectConfigAutoMapInvoke(float x
, float y
);
727 int PopupSelectConfigAutoMapResult();
729 vec4
ButtonColorMul(const void *pID
);
731 void DoQuadEnvelopes(CQuad
*q
, int Index
, int texID
= -1);
732 void DoQuadEnvPoint(CQuad
*pQuad
, int Index
, int V
);
733 void DoQuadPoint(CQuad
*pQuad
, int QuadIndex
, int v
);
735 void DoMapEditor(CUIRect View
, CUIRect Toolbar
);
736 void DoToolbar(CUIRect Toolbar
);
737 void DoQuad(CQuad
*pQuad
, int Index
);
738 float UiDoScrollbarV(const void *pID
, const CUIRect
*pRect
, float Current
);
739 vec4
GetButtonColor(const void *pID
, int Checked
);
741 static void ReplaceImage(const char *pFilename
, int StorageType
, void *pUser
);
742 static void AddImage(const char *pFilename
, int StorageType
, void *pUser
);
744 void RenderImages(CUIRect Toolbox
, CUIRect Toolbar
, CUIRect View
);
745 void RenderLayers(CUIRect Toolbox
, CUIRect Toolbar
, CUIRect View
);
746 void RenderModebar(CUIRect View
);
747 void RenderStatusbar(CUIRect View
);
748 void RenderEnvelopeEditor(CUIRect View
);
750 void RenderMenubar(CUIRect Menubar
);
751 void RenderFileDialog();
753 void AddFileDialogEntry(int Index
, CUIRect
*pView
);
755 static void ExtractName(const char *pFileName
, char *pName
, int BufferSize
)
757 const char *pExtractedName
= pFileName
;
758 const char *pEnd
= 0;
759 for(; *pFileName
; ++pFileName
)
761 if(*pFileName
== '/' || *pFileName
== '\\')
762 pExtractedName
= pFileName
+1;
763 else if(*pFileName
== '.')
767 int Length
= pEnd
> pExtractedName
? min(BufferSize
, (int)(pEnd
-pExtractedName
+1)) : BufferSize
;
768 str_copy(pName
, pExtractedName
, Length
);
771 int GetLineDistance();
774 // make sure to inline this function
775 inline class IGraphics
*CLayer::Graphics() { return m_pEditor
->Graphics(); }
776 inline class ITextRender
*CLayer::TextRender() { return m_pEditor
->TextRender(); }