mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Merge branch 'master' of http://github.com/oy/teeworlds into master
Conflicts: src/engine/client/input.h src/engine/server/server.cpp src/engine/shared/config_variables.h src/engine/shared/network_server.cpp src/engine/storage.h src/game/client/components/chat.cpp src/game/client/gameclient.cpp src/game/client/gameclient.h src/game/collision.cpp src/game/editor/ed_editor.cpp src/game/editor/ed_editor.h src/game/server/gamecontext.cpp src/game/server/gamecontroller.cpp src/game/server/gamemodes/ctf.cpp src/game/server/player.cpp Signed-off-by: GreYFoXGTi <GreYFoXGTi@GMaiL.CoM>
This commit is contained in:
commit
616498e7b1
Binary file not shown.
Before Width: | Height: | Size: 599 B After Width: | Height: | Size: 616 B |
|
@ -385,7 +385,7 @@ container.sprites.Add(Sprite("speedup_arrow", set_speedup_arrow, 0,0,1,1))
|
|||
|
||||
container.sprites.Add(Sprite("demobutton_play", set_demobuttons, 0,0,1,1))
|
||||
container.sprites.Add(Sprite("demobutton_pause", set_demobuttons, 1,0,1,1))
|
||||
container.sprites.Add(Sprite("demobutton_reset", set_demobuttons, 2,0,1,1))
|
||||
container.sprites.Add(Sprite("demobutton_stop", set_demobuttons, 2,0,1,1))
|
||||
container.sprites.Add(Sprite("demobutton_slower", set_demobuttons, 3,0,1,1))
|
||||
container.sprites.Add(Sprite("demobutton_faster", set_demobuttons, 4,0,1,1))
|
||||
|
||||
|
|
|
@ -291,7 +291,7 @@ unsigned io_read(IOHANDLE io, void *buffer, unsigned size)
|
|||
return fread(buffer, 1, size, (FILE*)io);
|
||||
}
|
||||
|
||||
unsigned io_skip(IOHANDLE io, unsigned size)
|
||||
unsigned io_skip(IOHANDLE io, int size)
|
||||
{
|
||||
fseek((FILE*)io, size, SEEK_CUR);
|
||||
return size;
|
||||
|
|
|
@ -242,7 +242,7 @@ unsigned io_read(IOHANDLE io, void *buffer, unsigned size);
|
|||
Returns:
|
||||
Number of bytes skipped.
|
||||
*/
|
||||
unsigned io_skip(IOHANDLE io, unsigned size);
|
||||
unsigned io_skip(IOHANDLE io, int size);
|
||||
|
||||
/*
|
||||
Function: io_write
|
||||
|
|
|
@ -387,13 +387,21 @@ int CGraphics_OpenGL::LoadPNG(CImageInfo *pImg, const char *pFilename)
|
|||
IOHANDLE File = m_pStorage->OpenFile(pFilename, IOFLAG_READ, aCompleteFilename, sizeof(aCompleteFilename));
|
||||
if(File)
|
||||
io_close(File);
|
||||
|
||||
if(png_open_file(&Png, aCompleteFilename) != PNG_NO_ERROR) // ignore_convention
|
||||
else
|
||||
{
|
||||
dbg_msg("game/png", "failed to open file. filename='%s'", aCompleteFilename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Error = png_open_file(&Png, aCompleteFilename); // ignore_convention
|
||||
if(Error != PNG_NO_ERROR)
|
||||
{
|
||||
dbg_msg("game/png", "failed to open file. filename='%s'", aCompleteFilename);
|
||||
if(Error != PNG_FILE_ERROR)
|
||||
png_close_file(&Png); // ignore_convention
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(Png.depth != 8 || (Png.color_type != PNG_TRUECOLOR && Png.color_type != PNG_TRUECOLOR_ALPHA)) // ignore_convention
|
||||
{
|
||||
dbg_msg("game/png", "invalid format. filename='%s'", aCompleteFilename);
|
||||
|
|
|
@ -87,7 +87,13 @@ void CInput::MouseModeRelative()
|
|||
|
||||
int CInput::MouseDoubleClick()
|
||||
{
|
||||
return m_ReleaseDelta < (time_freq() >> 2);
|
||||
if(m_ReleaseDelta >= 0 && m_ReleaseDelta < (time_freq() >> 2))
|
||||
{
|
||||
m_LastRelease = 0;
|
||||
m_ReleaseDelta = -1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CInput::ClearKeyStates()
|
||||
|
|
|
@ -185,6 +185,7 @@ public:
|
|||
|
||||
void PumpNetwork();
|
||||
|
||||
char *GetMapName();
|
||||
int LoadMap(const char *pMapName);
|
||||
|
||||
void InitEngine(const char *pAppname);
|
||||
|
|
|
@ -511,7 +511,7 @@ int CDataFileWriter::Finish()
|
|||
// calculate the complete size
|
||||
TypesSize = m_NumItemTypes*sizeof(CDatafileItemType);
|
||||
HeaderSize = sizeof(CDatafileHeader);
|
||||
OffsetSize = m_NumItems*sizeof(int) + m_NumDatas*sizeof(int);
|
||||
OffsetSize = (m_NumItems + m_NumDatas + m_NumDatas) * sizeof(int); //ItemOffsets, DataOffsets, DataSizes
|
||||
FileSize = HeaderSize + TypesSize + OffsetSize + ItemSize + DataSize;
|
||||
SwapSize = FileSize - DataSize;
|
||||
|
||||
|
|
|
@ -9,7 +9,10 @@
|
|||
#include "network.h"
|
||||
#include "engine.h"
|
||||
|
||||
static const unsigned char gs_aHeaderMarker[8] = {'T', 'W', 'D', 'E', 'M', 'O', 0, 1};
|
||||
static const unsigned char gs_aHeaderMarker[8] = {'T', 'W', 'D', 'E', 'M', 'O', '1', 0};
|
||||
static const unsigned char gs_aHeaderMarkerOld[8] = {'T', 'W', 'D', 'E', 'M', 'O', 0, 1}; // TODO: remove this later on
|
||||
static const unsigned char gs_aMapMarker[8] = {'M', 'A', 'P', 'D', 'A', 'T', 'A', 0,};
|
||||
|
||||
|
||||
CDemoRecorder::CDemoRecorder(class CSnapshotDelta *pSnapshotDelta)
|
||||
{
|
||||
|
@ -50,6 +53,45 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con
|
|||
Header.m_aCrc[3] = (Crc)&0xff;
|
||||
io_write(m_File, &Header, sizeof(Header));
|
||||
|
||||
|
||||
// write map
|
||||
char aMapFilename[128];
|
||||
// try the normal maps folder
|
||||
str_format(aMapFilename, sizeof(aMapFilename), "maps/%s.map", pMap);
|
||||
IOHANDLE MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_READ);
|
||||
if(!MapFile)
|
||||
{
|
||||
// try the downloaded maps
|
||||
str_format(aMapFilename, sizeof(aMapFilename), "downloadedmaps/%s_%08x.map", pMap, Crc);
|
||||
MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_READ);
|
||||
}
|
||||
if(MapFile)
|
||||
{
|
||||
// write map marker
|
||||
io_write(m_File, &gs_aMapMarker, sizeof(gs_aMapMarker));
|
||||
|
||||
// write map size
|
||||
int MapSize = io_length(MapFile);
|
||||
unsigned char aBufMapSize[4];
|
||||
aBufMapSize[0] = (MapSize>>24)&0xff;
|
||||
aBufMapSize[1] = (MapSize>>16)&0xff;
|
||||
aBufMapSize[2] = (MapSize>>8)&0xff;
|
||||
aBufMapSize[3] = (MapSize)&0xff;
|
||||
io_write(m_File, &aBufMapSize, sizeof(aBufMapSize));
|
||||
|
||||
// write map data
|
||||
while(1)
|
||||
{
|
||||
unsigned char aChunk[1024*64];
|
||||
int Bytes = io_read(MapFile, &aChunk, sizeof(aChunk));
|
||||
if(Bytes <= 0)
|
||||
break;
|
||||
io_write(m_File, &aChunk, Bytes);
|
||||
}
|
||||
io_close(MapFile);
|
||||
}
|
||||
|
||||
|
||||
m_LastKeyFrame = -1;
|
||||
m_LastTickMarker = -1;
|
||||
|
||||
|
@ -488,7 +530,8 @@ int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const
|
|||
|
||||
// read the header
|
||||
io_read(m_File, &m_Info.m_Header, sizeof(m_Info.m_Header));
|
||||
if(mem_comp(m_Info.m_Header.m_aMarker, gs_aHeaderMarker, sizeof(gs_aHeaderMarker)) != 0)
|
||||
if(mem_comp(m_Info.m_Header.m_aMarker, gs_aHeaderMarker, sizeof(gs_aHeaderMarker)) != 0 &&
|
||||
mem_comp(m_Info.m_Header.m_aMarker, gs_aHeaderMarkerOld, sizeof(gs_aHeaderMarkerOld)) != 0)
|
||||
{
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "'%s' is not a demo file", pFilename);
|
||||
|
@ -498,6 +541,51 @@ int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// check if the demo includes a map
|
||||
unsigned char aMapMarker[8];
|
||||
io_read(m_File, &aMapMarker, sizeof(aMapMarker));
|
||||
|
||||
if(mem_comp(aMapMarker, gs_aMapMarker, sizeof(gs_aMapMarker)) == 0)
|
||||
{
|
||||
// get map size
|
||||
unsigned char aBufMapSize[4];
|
||||
io_read(m_File, &aBufMapSize, sizeof(aBufMapSize));
|
||||
int MapSize = (aBufMapSize[0]<<24) | (aBufMapSize[1]<<16) | (aBufMapSize[2]<<8) | (aBufMapSize[3]);
|
||||
|
||||
// check if we already have the map
|
||||
// TODO: improve map checking
|
||||
int Crc = (m_Info.m_Header.m_aCrc[0]<<24) | (m_Info.m_Header.m_aCrc[1]<<16) | (m_Info.m_Header.m_aCrc[2]<<8) | (m_Info.m_Header.m_aCrc[3]);
|
||||
char aMapFilename[128];
|
||||
str_format(aMapFilename, sizeof(aMapFilename), "downloadedmaps/%s_%08x.map", m_Info.m_Header.m_aMap, Crc);
|
||||
IOHANDLE MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_READ);
|
||||
|
||||
if(MapFile)
|
||||
{
|
||||
io_skip(m_File, MapSize);
|
||||
io_close(MapFile);
|
||||
}
|
||||
else if(MapSize > 0)
|
||||
{
|
||||
// get map data
|
||||
unsigned char *pMapData = (unsigned char *)mem_alloc(MapSize, 1);
|
||||
io_read(m_File, pMapData, MapSize);
|
||||
|
||||
// save map
|
||||
MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_WRITE);
|
||||
io_write(MapFile, pMapData, MapSize);
|
||||
io_close(MapFile);
|
||||
|
||||
// free data
|
||||
mem_free(pMapData);
|
||||
}
|
||||
}
|
||||
else // no map in the demo
|
||||
{
|
||||
io_skip(m_File, -sizeof(aMapMarker));
|
||||
}
|
||||
|
||||
|
||||
// scan the file for interessting points
|
||||
ScanFile();
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// copyright (c) 2007 magnus auvinen, see licence.txt for more info
|
||||
#include <stdio.h> //remove()
|
||||
#include <base/system.h>
|
||||
#include <engine/storage.h>
|
||||
#include "engine.h"
|
||||
|
@ -194,6 +195,18 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
virtual bool RemoveFile(const char *pFilename)
|
||||
{
|
||||
char aBuffer[1024];
|
||||
str_format(aBuffer, sizeof(aBuffer), "%s/%s", m_aApplicationSavePath, pFilename);
|
||||
bool Fail = remove(aBuffer);
|
||||
|
||||
if(Fail)
|
||||
Fail = remove(pFilename);
|
||||
|
||||
return !Fail;
|
||||
}
|
||||
|
||||
virtual const char* SavePath(const char *pFilename, char *pBuffer, int Max)
|
||||
{
|
||||
str_format(pBuffer, Max, "%s/%s", m_aApplicationSavePath, pFilename);
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include <stdio.h>
|
||||
#include <engine/graphics.h>
|
||||
#include <engine/keys.h> //temp
|
||||
#include <engine/keys.h>
|
||||
#include <engine/serverbrowser.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <engine/storage.h>
|
||||
|
||||
#include <game/layers.h>
|
||||
#include <game/client/gameclient.h>
|
||||
|
@ -126,20 +127,30 @@ void CMapLayers::OnRender()
|
|||
Render = true;
|
||||
}
|
||||
|
||||
if(pLayer->m_Type == LAYERTYPE_TILES && Input()->KeyPressed(KEY_KP0))
|
||||
if(Render && pLayer->m_Type == LAYERTYPE_TILES && Input()->KeyPressed(KEY_LCTRL) && Input()->KeyPressed(KEY_LSHIFT) && Input()->KeyDown(KEY_KP0))
|
||||
{
|
||||
CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
|
||||
CTile *pTiles = (CTile *)m_pLayers->Map()->GetData(pTMap->m_Data);
|
||||
char buf[256];
|
||||
str_format(buf, sizeof(buf), "%d%d_%dx%d", g, l, pTMap->m_Width, pTMap->m_Height);
|
||||
FILE *f = fopen(buf, "w");
|
||||
CServerInfo CurrentServerInfo;
|
||||
Client()->GetServerInfo(&CurrentServerInfo);
|
||||
char aFilename[256];
|
||||
str_format(aFilename, sizeof(aFilename), "dumps/tilelayer_dump_%s-%d-%d-%dx%d.txt", CurrentServerInfo.m_aMap, g, l, pTMap->m_Width, pTMap->m_Height);
|
||||
IOHANDLE File = Storage()->OpenFile(aFilename, IOFLAG_WRITE);
|
||||
if(File)
|
||||
{
|
||||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
static const char Newline[] = "\r\n";
|
||||
#else
|
||||
static const char Newline[] = "\n";
|
||||
#endif
|
||||
for(int y = 0; y < pTMap->m_Height; y++)
|
||||
{
|
||||
for(int x = 0; x < pTMap->m_Width; x++)
|
||||
fprintf(f, "%d,", pTiles[y*pTMap->m_Width + x].m_Index);
|
||||
fprintf(f, "\n");
|
||||
io_write(File, &(pTiles[y*pTMap->m_Width + x].m_Index), sizeof(pTiles[y*pTMap->m_Width + x].m_Index));
|
||||
io_write(File, Newline, sizeof(Newline)-1);
|
||||
}
|
||||
io_close(File);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
if(Render && !IsGameLayer && !g_Config.m_GfxClearFull || (g_Config.m_GfxClearFull && IsGameLayer))
|
||||
|
|
|
@ -90,9 +90,11 @@ CMenus::CMenus()
|
|||
m_NeedSendinfo = false;
|
||||
m_MenuActive = true;
|
||||
m_UseMouseButtons = true;
|
||||
m_DemolistDelEntry = false;
|
||||
|
||||
m_EscapePressed = false;
|
||||
m_EnterPressed = false;
|
||||
m_DeletePressed = false;
|
||||
m_NumInputEvents = 0;
|
||||
|
||||
m_LastInput = time_get();
|
||||
|
@ -993,6 +995,12 @@ int CMenus::Render()
|
|||
pButtonText = Localize("Ok");
|
||||
ExtraAlign = -1;
|
||||
}
|
||||
else if(m_Popup == POPUP_DELETE_DEMO)
|
||||
{
|
||||
pTitle = Localize("Delete demo");
|
||||
pExtraText = Localize("Are you sure that you want to delete the demo?");
|
||||
ExtraAlign = -1;
|
||||
}
|
||||
else if(m_Popup == POPUP_PASSWORD)
|
||||
{
|
||||
pTitle = Localize("Password incorrect");
|
||||
|
@ -1086,6 +1094,29 @@ int CMenus::Render()
|
|||
static float Offset = 0.0f;
|
||||
DoEditBox(&g_Config.m_Password, &TextBox, g_Config.m_Password, sizeof(g_Config.m_Password), 12.0f, &Offset, true);
|
||||
}
|
||||
else if(m_Popup == POPUP_DELETE_DEMO)
|
||||
{
|
||||
CUIRect Yes, No;
|
||||
Box.HSplitBottom(20.f, &Box, &Part);
|
||||
Box.HSplitBottom(24.f, &Box, &Part);
|
||||
Part.VMargin(80.0f, &Part);
|
||||
|
||||
Part.VSplitMid(&No, &Yes);
|
||||
|
||||
Yes.VMargin(20.0f, &Yes);
|
||||
No.VMargin(20.0f, &No);
|
||||
|
||||
static int s_ButtonAbort = 0;
|
||||
if(DoButton_Menu(&s_ButtonAbort, Localize("No"), 0, &No) || m_EscapePressed)
|
||||
m_Popup = POPUP_NONE;
|
||||
|
||||
static int s_ButtonTryAgain = 0;
|
||||
if(DoButton_Menu(&s_ButtonTryAgain, Localize("Yes"), 0, &Yes) || m_EnterPressed)
|
||||
{
|
||||
m_Popup = POPUP_NONE;
|
||||
m_DemolistDelEntry = true;
|
||||
}
|
||||
}
|
||||
else if(m_Popup == POPUP_FIRST_LAUNCH)
|
||||
{
|
||||
CUIRect Label, TextBox;
|
||||
|
@ -1177,10 +1208,15 @@ bool CMenus::OnInput(IInput::CEvent e)
|
|||
}
|
||||
|
||||
if(IsActive())
|
||||
{
|
||||
if(e.m_Flags&IInput::FLAG_PRESS)
|
||||
{
|
||||
// special for popups
|
||||
if(e.m_Flags&IInput::FLAG_PRESS && e.m_Key == KEY_RETURN)
|
||||
if(e.m_Key == KEY_RETURN)
|
||||
m_EnterPressed = true;
|
||||
else if(e.m_Key == KEY_DELETE)
|
||||
m_DeletePressed = true;
|
||||
}
|
||||
|
||||
if(m_NumInputEvents < MAX_INPUTEVENTS)
|
||||
m_aInputEvents[m_NumInputEvents++] = e;
|
||||
|
@ -1265,6 +1301,7 @@ void CMenus::OnRender()
|
|||
{
|
||||
m_EscapePressed = false;
|
||||
m_EnterPressed = false;
|
||||
m_DeletePressed = false;
|
||||
m_NumInputEvents = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -1332,6 +1369,7 @@ void CMenus::OnRender()
|
|||
|
||||
m_EscapePressed = false;
|
||||
m_EnterPressed = false;
|
||||
m_DeletePressed = false;
|
||||
m_NumInputEvents = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ class CMenus : public CComponent
|
|||
POPUP_MESSAGE,
|
||||
POPUP_DISCONNECTED,
|
||||
POPUP_PURE,
|
||||
POPUP_DELETE_DEMO,
|
||||
POPUP_PASSWORD,
|
||||
POPUP_QUIT,
|
||||
};
|
||||
|
@ -147,6 +148,7 @@ class CMenus : public CComponent
|
|||
//
|
||||
bool m_EscapePressed;
|
||||
bool m_EnterPressed;
|
||||
bool m_DeletePressed;
|
||||
|
||||
// for call vote
|
||||
int m_CallvoteSelectedOption;
|
||||
|
@ -162,6 +164,7 @@ class CMenus : public CComponent
|
|||
};
|
||||
|
||||
char m_aCurrentDemoFolder[256];
|
||||
bool m_DemolistDelEntry;
|
||||
|
||||
static void DemolistCountCallback(const char *pName, int IsDir, void *pUser);
|
||||
static void DemolistFetchCallback(const char *pName, int IsDir, void *pUser);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <engine/demo.h>
|
||||
#include <engine/keys.h>
|
||||
#include <engine/graphics.h>
|
||||
#include <engine/storage.h>
|
||||
|
||||
#include <game/client/render.h>
|
||||
#include <game/client/gameclient.h>
|
||||
|
@ -59,6 +60,9 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
|
|||
|
||||
CUIRect SeekBar, ButtonBar;
|
||||
|
||||
int CurrentTick = pInfo->m_CurrentTick - pInfo->m_FirstTick;
|
||||
int TotalTicks = pInfo->m_LastTick - pInfo->m_FirstTick;
|
||||
|
||||
if(m_MenuActive)
|
||||
{
|
||||
MainView.HSplitTop(SeekBarHeight, &SeekBar, &ButtonBar);
|
||||
|
@ -75,9 +79,6 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
|
|||
|
||||
RenderTools()->DrawUIRect(&SeekBar, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 5.0f);
|
||||
|
||||
int CurrentTick = pInfo->m_CurrentTick - pInfo->m_FirstTick;
|
||||
int TotalTicks = pInfo->m_LastTick - pInfo->m_FirstTick;
|
||||
|
||||
float Amount = CurrentTick/(float)TotalTicks;
|
||||
|
||||
CUIRect FilledBar = SeekBar;
|
||||
|
@ -121,6 +122,11 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
|
|||
UI()->SetHotItem(id);
|
||||
}
|
||||
|
||||
if(CurrentTick == TotalTicks)
|
||||
{
|
||||
DemoPlayer()->Pause();
|
||||
DemoPlayer()->SetPos(0);
|
||||
}
|
||||
|
||||
if(m_MenuActive)
|
||||
{
|
||||
|
@ -141,11 +147,14 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
|
|||
DemoPlayer()->Unpause();
|
||||
}
|
||||
|
||||
// stop button
|
||||
|
||||
ButtonBar.VSplitLeft(Margins, 0, &ButtonBar);
|
||||
ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar);
|
||||
static int s_ResetButton = 0;
|
||||
if(DoButton_DemoPlayer_Sprite(&s_ResetButton, SPRITE_DEMOBUTTON_RESET, false, &Button))
|
||||
if(DoButton_DemoPlayer_Sprite(&s_ResetButton, SPRITE_DEMOBUTTON_STOP, false, &Button))
|
||||
{
|
||||
DemoPlayer()->Pause();
|
||||
DemoPlayer()->SetPos(0);
|
||||
}
|
||||
|
||||
|
@ -334,6 +343,7 @@ CMenus::CListboxItem CMenus::UiDoListboxNextItem(void *pId, bool Selected)
|
|||
if(m_EnterPressed || (Input()->MouseDoubleClick() && UI()->ActiveItem() == pId))
|
||||
{
|
||||
gs_ListBoxItemActivated = true;
|
||||
UI()->SetActiveItem(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -390,7 +400,6 @@ struct FETCH_CALLBACKINFO
|
|||
{
|
||||
CMenus *m_pSelf;
|
||||
const char *m_pPrefix;
|
||||
int m_Count;
|
||||
};
|
||||
|
||||
void CMenus::DemolistFetchCallback(const char *pName, int IsDir, void *pUser)
|
||||
|
@ -411,7 +420,7 @@ void CMenus::DemolistPopulate()
|
|||
m_lDemos.clear();
|
||||
|
||||
|
||||
if(str_comp_num(m_aCurrentDemoFolder, "demos", 256)) //add parent folder
|
||||
if(str_comp(m_aCurrentDemoFolder, "demos") != 0) //add parent folder
|
||||
{
|
||||
CDemoItem Item;
|
||||
str_copy(Item.m_aName, "..", sizeof(Item.m_aName));
|
||||
|
@ -423,7 +432,7 @@ void CMenus::DemolistPopulate()
|
|||
char aBuf[512];
|
||||
str_format(aBuf, sizeof(aBuf), "%s/%s", Client()->UserDirectory(), m_aCurrentDemoFolder);
|
||||
|
||||
FETCH_CALLBACKINFO Info = {this, aBuf, m_aCurrentDemoFolder[6]}; //skip "demos/"
|
||||
FETCH_CALLBACKINFO Info = {this, aBuf};
|
||||
fs_listdir(aBuf, DemolistFetchCallback, &Info);
|
||||
Info.m_pPrefix = m_aCurrentDemoFolder;
|
||||
fs_listdir(m_aCurrentDemoFolder, DemolistFetchCallback, &Info);
|
||||
|
@ -432,10 +441,34 @@ void CMenus::DemolistPopulate()
|
|||
|
||||
void CMenus::RenderDemoList(CUIRect MainView)
|
||||
{
|
||||
static int s_SelectedItem = -1;
|
||||
static int s_Inited = 0;
|
||||
if(!s_Inited)
|
||||
{
|
||||
DemolistPopulate();
|
||||
s_Inited = 1;
|
||||
if(m_lDemos.size() > 0)
|
||||
s_SelectedItem = 0;
|
||||
}
|
||||
|
||||
bool IsDir = false;
|
||||
if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size())
|
||||
{
|
||||
if(str_comp(m_lDemos[s_SelectedItem].m_aName, "..") == 0 || fs_is_dir(m_lDemos[s_SelectedItem].m_aFilename))
|
||||
IsDir = true;
|
||||
}
|
||||
|
||||
// delete demo
|
||||
if(m_DemolistDelEntry)
|
||||
{
|
||||
if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size() && !IsDir)
|
||||
{
|
||||
Storage()->RemoveFile(m_lDemos[s_SelectedItem].m_aFilename);
|
||||
DemolistPopulate();
|
||||
s_SelectedItem = s_SelectedItem-1 < 0 ? m_lDemos.size() > 0 ? 0 : -1 : s_SelectedItem-1;
|
||||
}
|
||||
m_DemolistDelEntry = false;
|
||||
}
|
||||
|
||||
// render background
|
||||
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
|
||||
|
@ -445,7 +478,6 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
|||
MainView.HSplitBottom(ms_ButtonHeight+5.0f, &MainView, &ButtonBar);
|
||||
ButtonBar.HSplitTop(5.0f, 0, &ButtonBar);
|
||||
|
||||
static int s_SelectedItem = -1;
|
||||
static int s_DemoListId = 0;
|
||||
static float s_ScrollValue = 0;
|
||||
|
||||
|
@ -460,18 +492,11 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
|||
bool Activated = false;
|
||||
s_SelectedItem = UiDoListboxEnd(&s_ScrollValue, &Activated);
|
||||
|
||||
CUIRect RefreshRect, PlayRect;
|
||||
ButtonBar.VSplitRight(250.0f, &ButtonBar, &RefreshRect);
|
||||
RefreshRect.VSplitRight(130.0f, &RefreshRect, &PlayRect);
|
||||
PlayRect.VSplitRight(120.0f, 0x0, &PlayRect);
|
||||
|
||||
|
||||
bool IsDir = false;
|
||||
if(!str_comp_num(m_lDemos[s_SelectedItem].m_aName, "..", 256)) //parent folder
|
||||
IsDir = true;
|
||||
else if(fs_is_dir(m_lDemos[s_SelectedItem].m_aFilename))
|
||||
IsDir = true;
|
||||
|
||||
CUIRect RefreshRect, PlayRect, DeleteRect;
|
||||
ButtonBar.VSplitRight(130.0f, &ButtonBar, &PlayRect);
|
||||
ButtonBar.VSplitLeft(130.0f, &RefreshRect, &ButtonBar);
|
||||
ButtonBar.VSplitLeft(10.0f, &DeleteRect, &ButtonBar);
|
||||
ButtonBar.VSplitLeft(120.0f, &DeleteRect, &ButtonBar);
|
||||
|
||||
static int s_RefreshButton = 0;
|
||||
if(DoButton_Menu(&s_RefreshButton, Localize("Refresh"), 0, &RefreshRect))
|
||||
|
@ -490,19 +515,21 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
|||
{
|
||||
if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size())
|
||||
{
|
||||
if(!str_comp_num(m_lDemos[s_SelectedItem].m_aName, "..", 256))
|
||||
if(str_comp(m_lDemos[s_SelectedItem].m_aName, "..") == 0) //parent folder
|
||||
{
|
||||
DemoSetParentDirectory();
|
||||
DemolistPopulate();
|
||||
s_SelectedItem = 0;
|
||||
s_SelectedItem = m_lDemos.size() > 0 ? 0 : -1;
|
||||
}
|
||||
else if(IsDir)
|
||||
else if(IsDir) //folder
|
||||
{
|
||||
str_format(m_aCurrentDemoFolder, sizeof(m_aCurrentDemoFolder), "%s/%s", m_aCurrentDemoFolder, m_lDemos[s_SelectedItem].m_aName);
|
||||
char aTemp[256];
|
||||
str_copy(aTemp, m_aCurrentDemoFolder, sizeof(aTemp));
|
||||
str_format(m_aCurrentDemoFolder, sizeof(m_aCurrentDemoFolder), "%s/%s", aTemp, m_lDemos[s_SelectedItem].m_aName);
|
||||
DemolistPopulate();
|
||||
s_SelectedItem = 0;
|
||||
s_SelectedItem = m_lDemos.size() > 0 ? 0 : -1;
|
||||
}
|
||||
else
|
||||
else //file
|
||||
{
|
||||
const char *pError = Client()->DemoPlayer_Play(m_lDemos[s_SelectedItem].m_aFilename);
|
||||
if(pError)
|
||||
|
@ -511,24 +538,30 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
|||
}
|
||||
}
|
||||
|
||||
if(!IsDir)
|
||||
{
|
||||
static int s_DeleteButton = 0;
|
||||
if(DoButton_Menu(&s_DeleteButton, Localize("Delete"), 0, &DeleteRect) || m_DeletePressed)
|
||||
{
|
||||
if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size())
|
||||
m_Popup = POPUP_DELETE_DEMO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CMenus::DemoSetParentDirectory()
|
||||
{
|
||||
int Stop = 0;
|
||||
int i;
|
||||
for(i = 0; i < 256; i++)
|
||||
for(int i = 0; i < 256; i++)
|
||||
{
|
||||
if(m_aCurrentDemoFolder[i] == '/')
|
||||
Stop = i;
|
||||
}
|
||||
|
||||
//keeps chars which are before the last '/' and remove chars which are after
|
||||
for(i = 0; i < 256; i++)
|
||||
for(int i = 0; i < 256; i++)
|
||||
{
|
||||
if(i >= Stop)
|
||||
m_aCurrentDemoFolder[i] = 0;
|
||||
m_aCurrentDemoFolder[i] = '\0';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -250,26 +250,46 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, vec4
|
|||
int Px1 = Px0+(1024/16)-1;
|
||||
int Py1 = Py0+(1024/16)-1;
|
||||
|
||||
float u0 = Nudge + Px0/TexSize+Frac;
|
||||
float v0 = Nudge + Py0/TexSize+Frac;
|
||||
float u1 = Nudge + Px1/TexSize-Frac;
|
||||
float v1 = Nudge + Py1/TexSize-Frac;
|
||||
float x0 = Nudge + Px0/TexSize+Frac;
|
||||
float y0 = Nudge + Py0/TexSize+Frac;
|
||||
float x1 = Nudge + Px1/TexSize-Frac;
|
||||
float y1 = Nudge + Py0/TexSize+Frac;
|
||||
float x2 = Nudge + Px1/TexSize-Frac;
|
||||
float y2 = Nudge + Py1/TexSize-Frac;
|
||||
float x3 = Nudge + Px0/TexSize+Frac;
|
||||
float y3 = Nudge + Py1/TexSize-Frac;
|
||||
|
||||
if(Flags&TILEFLAG_VFLIP)
|
||||
{
|
||||
float Tmp = u0;
|
||||
u0 = u1;
|
||||
u1 = Tmp;
|
||||
x0 = x2;
|
||||
x1 = x3;
|
||||
x2 = x3;
|
||||
x3 = x0;
|
||||
}
|
||||
|
||||
if(Flags&TILEFLAG_HFLIP)
|
||||
{
|
||||
float Tmp = v0;
|
||||
v0 = v1;
|
||||
v1 = Tmp;
|
||||
y0 = y3;
|
||||
y2 = y1;
|
||||
y3 = y1;
|
||||
y1 = y0;
|
||||
}
|
||||
|
||||
Graphics()->QuadsSetSubset(u0,v0,u1,v1);
|
||||
if(Flags&TILEFLAG_ROTATE)
|
||||
{
|
||||
float Tmp = x0;
|
||||
x0 = x3;
|
||||
x3 = x2;
|
||||
x2 = x1;
|
||||
x1 = Tmp;
|
||||
Tmp = y0;
|
||||
y0 = y3;
|
||||
y3 = y2;
|
||||
y2 = y1;
|
||||
y1 = Tmp;
|
||||
}
|
||||
|
||||
Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3);
|
||||
IGraphics::CQuadItem QuadItem(x*Scale, y*Scale, Scale, Scale);
|
||||
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||
}
|
||||
|
|
|
@ -377,6 +377,7 @@ public:
|
|||
virtual void BrushDraw(CLayer *pBrush, float wx, float wy);
|
||||
virtual void BrushFlipX();
|
||||
virtual void BrushFlipY();
|
||||
virtual void BrushRotate(float Amount);
|
||||
|
||||
virtual int RenderProperties(CUIRect *pToolbox);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ void CLayerTiles::PrepareForSave()
|
|||
{
|
||||
for(int y = 0; y < m_Height; y++)
|
||||
for(int x = 0; x < m_Width; x++)
|
||||
m_pTiles[y*m_Width+x].m_Flags &= TILEFLAG_VFLIP|TILEFLAG_HFLIP;
|
||||
m_pTiles[y*m_Width+x].m_Flags &= TILEFLAG_VFLIP|TILEFLAG_HFLIP|TILEFLAG_ROTATE;
|
||||
|
||||
if(m_Image != -1)
|
||||
{
|
||||
|
@ -296,7 +296,7 @@ void CLayerTiles::BrushFlipX()
|
|||
|
||||
for(int y = 0; y < m_Height; y++)
|
||||
for(int x = 0; x < m_Width; x++)
|
||||
m_pTiles[y*m_Width+x].m_Flags ^= TILEFLAG_VFLIP;
|
||||
m_pTiles[y*m_Width+x].m_Flags ^= m_pTiles[y*m_Width+x].m_Flags&TILEFLAG_ROTATE ? TILEFLAG_HFLIP : TILEFLAG_VFLIP;
|
||||
}
|
||||
|
||||
void CLayerTiles::BrushFlipY()
|
||||
|
@ -311,7 +311,41 @@ void CLayerTiles::BrushFlipY()
|
|||
|
||||
for(int y = 0; y < m_Height; y++)
|
||||
for(int x = 0; x < m_Width; x++)
|
||||
m_pTiles[y*m_Width+x].m_Flags ^= TILEFLAG_HFLIP;
|
||||
m_pTiles[y*m_Width+x].m_Flags ^= m_pTiles[y*m_Width+x].m_Flags&TILEFLAG_ROTATE ? TILEFLAG_VFLIP : TILEFLAG_HFLIP;
|
||||
}
|
||||
|
||||
void CLayerTiles::BrushRotate(float Amount)
|
||||
{
|
||||
int Rotation = (round(360.0f*Amount/(pi*2))/90)%4; // 0=0°, 1=90°, 2=180°, 3=270°
|
||||
if(Rotation < 0)
|
||||
Rotation +=4;
|
||||
|
||||
if(Rotation == 1 || Rotation == 3)
|
||||
{
|
||||
// 90° rotation
|
||||
CTile *pTempData = new CTile[m_Width*m_Height];
|
||||
mem_copy(pTempData, m_pTiles, m_Width*m_Height*sizeof(CTile));
|
||||
CTile *pDst = m_pTiles;
|
||||
for(int x = 0; x < m_Width; ++x)
|
||||
for(int y = m_Height-1; y >= 0; --y, ++pDst)
|
||||
{
|
||||
*pDst = pTempData[y*m_Width+x];
|
||||
if(pDst->m_Flags&TILEFLAG_ROTATE)
|
||||
pDst->m_Flags ^= (TILEFLAG_HFLIP|TILEFLAG_VFLIP);
|
||||
pDst->m_Flags ^= TILEFLAG_ROTATE;
|
||||
}
|
||||
|
||||
int Temp = m_Width;
|
||||
m_Width = m_Height;
|
||||
m_Height = Temp;
|
||||
delete[] pTempData;
|
||||
}
|
||||
|
||||
if(Rotation == 2 || Rotation == 3)
|
||||
{
|
||||
BrushFlipX();
|
||||
BrushFlipY();
|
||||
}
|
||||
}
|
||||
|
||||
void CLayerTiles::Resize(int NewW, int NewH)
|
||||
|
|
|
@ -137,6 +137,7 @@ enum
|
|||
TILEFLAG_VFLIP=1,
|
||||
TILEFLAG_HFLIP=2,
|
||||
TILEFLAG_OPAQUE=4,
|
||||
TILEFLAG_ROTATE=8,
|
||||
|
||||
LAYERFLAG_DETAIL=1,
|
||||
|
||||
|
|
Loading…
Reference in a new issue