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 m_pTypeName
= "(invalid)";
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;}
159 const char *m_pTypeName
;
171 class CEditorMap
*m_pMap
;
173 array
<CLayer
*> m_lLayers
;
195 void Convert(CUIRect
*pRect
);
198 void Mapping(float *pPoints
);
200 void GetSize(float *w
, float *h
);
202 void DeleteLayer(int Index
);
203 int SwapLayers(int Index0
, int Index1
);
207 return m_lLayers
.size() == 0;
212 m_lLayers
.delete_all();
215 void AddLayer(CLayer
*l
);
217 void ModifyImageIndex(INDEX_MODIFY_FUNC Func
)
219 for(int i
= 0; i
< m_lLayers
.size(); i
++)
220 m_lLayers
[i
]->ModifyImageIndex(Func
);
223 void ModifyEnvelopeIndex(INDEX_MODIFY_FUNC Func
)
225 for(int i
= 0; i
< m_lLayers
.size(); i
++)
226 m_lLayers
[i
]->ModifyEnvelopeIndex(Func
);
230 class CEditorImage
: public CImageInfo
235 CEditorImage(CEditor
*pEditor
)
236 : m_AutoMapper(pEditor
)
250 void AnalyseTileFlags();
255 unsigned char m_aTileFlags
[256];
256 class CAutoMapper m_AutoMapper
;
261 void MakeGameGroup(CLayerGroup
*pGroup
);
262 void MakeGameLayer(CLayer
*pLayer
);
272 array
<CLayerGroup
*> m_lGroups
;
273 array
<CEditorImage
*> m_lImages
;
274 array
<CEnvelope
*> m_lEnvelopes
;
276 class CLayerGame
*m_pGameLayer
;
277 CLayerGroup
*m_pGameGroup
;
279 CEnvelope
*NewEnvelope(int Channels
)
282 CEnvelope
*e
= new CEnvelope(Channels
);
287 void DeleteEnvelope(int Index
);
289 CLayerGroup
*NewGroup()
292 CLayerGroup
*g
= new CLayerGroup
;
298 int SwapGroups(int Index0
, int Index1
)
300 if(Index0
< 0 || Index0
>= m_lGroups
.size()) return Index0
;
301 if(Index1
< 0 || Index1
>= m_lGroups
.size()) return Index0
;
302 if(Index0
== Index1
) return Index0
;
304 swap(m_lGroups
[Index0
], m_lGroups
[Index1
]);
308 void DeleteGroup(int Index
)
310 if(Index
< 0 || Index
>= m_lGroups
.size()) return;
312 delete m_lGroups
[Index
];
313 m_lGroups
.remove_index(Index
);
316 void ModifyImageIndex(INDEX_MODIFY_FUNC pfnFunc
)
319 for(int i
= 0; i
< m_lGroups
.size(); i
++)
320 m_lGroups
[i
]->ModifyImageIndex(pfnFunc
);
323 void ModifyEnvelopeIndex(INDEX_MODIFY_FUNC pfnFunc
)
326 for(int i
= 0; i
< m_lGroups
.size(); i
++)
327 m_lGroups
[i
]->ModifyEnvelopeIndex(pfnFunc
);
331 void CreateDefault(int EntitiesTexture
);
334 int Save(class IStorage
*pStorage
, const char *pFilename
);
335 int Load(class IStorage
*pStorage
, const char *pFilename
, int StorageType
);
366 class CLayerTiles
: public CLayer
369 CLayerTiles(int w
, int h
);
372 void Resize(int NewW
, int NewH
);
373 void Shift(int Direction
);
376 virtual void Render();
378 int ConvertX(float x
) const;
379 int ConvertY(float y
) const;
380 void Convert(CUIRect Rect
, RECTi
*pOut
);
381 void Snap(CUIRect
*pRect
);
382 void Clamp(RECTi
*pRect
);
384 virtual void BrushSelecting(CUIRect Rect
);
385 virtual int BrushGrab(CLayerGroup
*pBrush
, CUIRect Rect
);
386 virtual void FillSelection(bool Empty
, CLayer
*pBrush
, CUIRect Rect
);
387 virtual void BrushDraw(CLayer
*pBrush
, float wx
, float wy
);
388 virtual void BrushFlipX();
389 virtual void BrushFlipY();
390 virtual void BrushRotate(float Amount
);
392 virtual void ShowInfo();
393 virtual int RenderProperties(CUIRect
*pToolbox
);
395 virtual void ModifyImageIndex(INDEX_MODIFY_FUNC pfnFunc
);
396 virtual void ModifyEnvelopeIndex(INDEX_MODIFY_FUNC pfnFunc
);
398 void PrepareForSave();
400 void GetSize(float *w
, float *h
) { *w
= m_Width
*32.0f
; *h
= m_Height
*32.0f
; }
411 class CLayerQuads
: public CLayer
417 virtual void Render();
420 virtual void BrushSelecting(CUIRect Rect
);
421 virtual int BrushGrab(CLayerGroup
*pBrush
, CUIRect Rect
);
422 virtual void BrushPlace(CLayer
*pBrush
, float wx
, float wy
);
423 virtual void BrushFlipX();
424 virtual void BrushFlipY();
425 virtual void BrushRotate(float Amount
);
427 virtual int RenderProperties(CUIRect
*pToolbox
);
429 virtual void ModifyImageIndex(INDEX_MODIFY_FUNC pfnFunc
);
430 virtual void ModifyEnvelopeIndex(INDEX_MODIFY_FUNC pfnFunc
);
432 void GetSize(float *w
, float *h
);
435 array
<CQuad
> m_lQuads
;
438 class CLayerGame
: public CLayerTiles
441 CLayerGame(int w
, int h
);
444 virtual int RenderProperties(CUIRect
*pToolbox
);
447 class CEditor
: public IEditor
449 class IInput
*m_pInput
;
450 class IClient
*m_pClient
;
451 class IConsole
*m_pConsole
;
452 class IGraphics
*m_pGraphics
;
453 class ITextRender
*m_pTextRender
;
454 class IStorage
*m_pStorage
;
455 CRenderTools m_RenderTools
;
458 class IInput
*Input() { return m_pInput
; };
459 class IClient
*Client() { return m_pClient
; };
460 class IConsole
*Console() { return m_pConsole
; };
461 class IGraphics
*Graphics() { return m_pGraphics
; };
462 class ITextRender
*TextRender() { return m_pTextRender
; };
463 class IStorage
*Storage() { return m_pStorage
; };
464 CUI
*UI() { return &m_UI
; }
465 CRenderTools
*RenderTools() { return &m_RenderTools
; }
467 CEditor() : m_TilesetPicker(16, 16)
474 m_Mode
= MODE_LAYERS
;
479 m_aFileSaveName
[0] = 0;
480 m_ValidSaveFilename
= false;
482 m_PopupEventActivated
= false;
484 m_FileDialogStorageType
= 0;
485 m_pFileDialogTitle
= 0;
486 m_pFileDialogButtonText
= 0;
487 m_pFileDialogUser
= 0;
488 m_aFileDialogFileName
[0] = 0;
489 m_aFileDialogCurrentFolder
[0] = 0;
490 m_aFileDialogCurrentLink
[0] = 0;
491 m_pFileDialogPath
= m_aFileDialogCurrentFolder
;
492 m_aFileDialogActivate
= false;
493 m_FileDialogScrollValue
= 0.0f
;
494 m_FilesSelectedIndex
= -1;
501 m_EditorOffsetX
= 0.0f
;
502 m_EditorOffsetY
= 0.0f
;
507 m_ShowMousePointer
= true;
514 m_ProofBorders
= false;
516 m_ShowTileInfo
= false;
523 m_ShowEnvelopeEditor
= 0;
525 ms_CheckerTexture
= 0;
526 ms_BackgroundTexture
= 0;
527 ms_CursorTexture
= 0;
528 ms_EntitiesTexture
= 0;
530 ms_pUiGotContext
= 0;
534 virtual void UpdateAndRender();
535 virtual bool HasUnsavedData() { return m_Map
.m_Modified
; }
537 void FilelistPopulate(int StorageType
);
538 void InvokeFileDialog(int StorageType
, int FileType
, const char *pTitle
, const char *pButtonText
,
539 const char *pBasepath
, const char *pDefaultName
,
540 void (*pfnFunc
)(const char *pFilename
, int StorageType
, void *pUser
), void *pUser
);
542 void Reset(bool CreateDefault
=true);
543 int Save(const char *pFilename
);
544 int Load(const char *pFilename
, int StorageType
);
545 int Append(const char *pFilename
, int StorageType
);
548 CQuad
*GetSelectedQuad();
549 CLayer
*GetSelectedLayerType(int Index
, int Type
);
550 CLayer
*GetSelectedLayer(int Index
);
551 CLayerGroup
*GetSelectedGroup();
553 int DoProperties(CUIRect
*pToolbox
, CProperty
*pProps
, int *pIDs
, int *pNewVal
);
557 const char *m_pTooltip
;
559 char m_aFileName
[512];
560 char m_aFileSaveName
[512];
561 bool m_ValidSaveFilename
;
571 int m_PopupEventType
;
572 int m_PopupEventActivated
;
579 MAX_PATH_LENGTH
= 512
582 int m_FileDialogStorageType
;
583 const char *m_pFileDialogTitle
;
584 const char *m_pFileDialogButtonText
;
585 void (*m_pfnFileDialogFunc
)(const char *pFileName
, int StorageType
, void *pUser
);
586 void *m_pFileDialogUser
;
587 char m_aFileDialogFileName
[MAX_PATH_LENGTH
];
588 char m_aFileDialogCurrentFolder
[MAX_PATH_LENGTH
];
589 char m_aFileDialogCurrentLink
[MAX_PATH_LENGTH
];
590 char *m_pFileDialogPath
;
591 bool m_aFileDialogActivate
;
592 int m_FileDialogFileType
;
593 float m_FileDialogScrollValue
;
594 int m_FilesSelectedIndex
;
595 char m_FileDialogNewFolderName
[64];
596 char m_FileDialogErrString
[64];
600 char m_aFilename
[128];
606 bool operator<(const CFilelistItem
&Other
) { return !str_comp(m_aFilename
, "..") ? true : !str_comp(Other
.m_aFilename
, "..") ? false :
607 m_IsDir
&& !Other
.m_IsDir
? true : !m_IsDir
&& Other
.m_IsDir
? false :
608 str_comp_filenames(m_aFilename
, Other
.m_aFilename
) < 0; }
610 sorted_array
<CFilelistItem
> m_FileList
;
615 float m_WorldOffsetX
;
616 float m_WorldOffsetY
;
617 float m_EditorOffsetX
;
618 float m_EditorOffsetY
;
622 bool m_ShowMousePointer
;
627 float m_MouseDeltaWx
;
628 float m_MouseDeltaWy
;
633 int64 m_AnimateStart
;
635 float m_AnimateSpeed
;
637 int m_ShowEnvelopeEditor
;
643 int m_SelectedPoints
;
644 int m_SelectedEnvelope
;
647 static int ms_CheckerTexture
;
648 static int ms_BackgroundTexture
;
649 static int ms_CursorTexture
;
650 static int ms_EntitiesTexture
;
653 CLayerTiles m_TilesetPicker
;
655 static const void *ms_pUiGotContext
;
660 int DoButton_Editor_Common(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
661 int DoButton_Editor(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
663 int DoButton_Tab(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
664 int DoButton_Ex(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
, int Corners
);
665 int DoButton_ButtonDec(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
666 int DoButton_ButtonInc(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
668 int DoButton_File(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
670 int DoButton_Menu(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
, const char *pToolTip
);
671 int DoButton_MenuItem(const void *pID
, const char *pText
, int Checked
, const CUIRect
*pRect
, int Flags
=0, const char *pToolTip
=0);
673 int DoEditBox(void *pID
, const CUIRect
*pRect
, char *pStr
, unsigned StrSize
, float FontSize
, bool Hidden
=false);
675 void RenderBackground(CUIRect View
, int Texture
, float Size
, float Brightness
);
677 void UiInvokePopupMenu(void *pID
, int Flags
, float X
, float Y
, float W
, float H
, int (*pfnFunc
)(CEditor
*pEditor
, CUIRect Rect
), void *pExtra
=0);
678 void UiDoPopupMenu();
680 int UiDoValueSelector(void *pID
, CUIRect
*pRect
, const char *pLabel
, int Current
, int Min
, int Max
, int Step
, float Scale
, const char *pToolTip
);
682 static int PopupGroup(CEditor
*pEditor
, CUIRect View
);
683 static int PopupLayer(CEditor
*pEditor
, CUIRect View
);
684 static int PopupQuad(CEditor
*pEditor
, CUIRect View
);
685 static int PopupPoint(CEditor
*pEditor
, CUIRect View
);
686 static int PopupNewFolder(CEditor
*pEditor
, CUIRect View
);
687 static int PopupEvent(CEditor
*pEditor
, CUIRect View
);
688 static int PopupSelectImage(CEditor
*pEditor
, CUIRect View
);
689 static int PopupSelectGametileOp(CEditor
*pEditor
, CUIRect View
);
690 static int PopupImage(CEditor
*pEditor
, CUIRect View
);
691 static int PopupMenuFile(CEditor
*pEditor
, CUIRect View
);
692 static int PopupSelectConfigAutoMap(CEditor
*pEditor
, CUIRect View
);
694 static void CallbackOpenMap(const char *pFileName
, int StorageType
, void *pUser
);
695 static void CallbackAppendMap(const char *pFileName
, int StorageType
, void *pUser
);
696 static void CallbackSaveMap(const char *pFileName
, int StorageType
, void *pUser
);
698 void PopupSelectImageInvoke(int Current
, float x
, float y
);
699 int PopupSelectImageResult();
701 void PopupSelectGametileOpInvoke(float x
, float y
);
702 int PopupSelectGameTileOpResult();
704 void PopupSelectConfigAutoMapInvoke(float x
, float y
);
705 int PopupSelectConfigAutoMapResult();
707 vec4
ButtonColorMul(const void *pID
);
709 void DoQuadPoint(CQuad
*pQuad
, int QuadIndex
, int v
);
710 void DoMapEditor(CUIRect View
, CUIRect Toolbar
);
711 void DoToolbar(CUIRect Toolbar
);
712 void DoQuad(CQuad
*pQuad
, int Index
);
713 float UiDoScrollbarV(const void *pID
, const CUIRect
*pRect
, float Current
);
714 vec4
GetButtonColor(const void *pID
, int Checked
);
716 static void ReplaceImage(const char *pFilename
, int StorageType
, void *pUser
);
717 static void AddImage(const char *pFilename
, int StorageType
, void *pUser
);
719 void RenderImages(CUIRect Toolbox
, CUIRect Toolbar
, CUIRect View
);
720 void RenderLayers(CUIRect Toolbox
, CUIRect Toolbar
, CUIRect View
);
721 void RenderModebar(CUIRect View
);
722 void RenderStatusbar(CUIRect View
);
723 void RenderEnvelopeEditor(CUIRect View
);
725 void RenderMenubar(CUIRect Menubar
);
726 void RenderFileDialog();
728 void AddFileDialogEntry(int Index
, CUIRect
*pView
);
730 static void ExtractName(const char *pFileName
, char *pName
, int BufferSize
)
732 const char *pExtractedName
= pFileName
;
733 const char *pEnd
= 0;
734 for(; *pFileName
; ++pFileName
)
736 if(*pFileName
== '/' || *pFileName
== '\\')
737 pExtractedName
= pFileName
+1;
738 else if(*pFileName
== '.')
742 int Length
= pEnd
> pExtractedName
? min(BufferSize
, (int)(pEnd
-pExtractedName
+1)) : BufferSize
;
743 str_copy(pName
, pExtractedName
, Length
);
747 // make sure to inline this function
748 inline class IGraphics
*CLayer::Graphics() { return m_pEditor
->Graphics(); }
749 inline class ITextRender
*CLayer::TextRender() { return m_pEditor
->TextRender(); }