mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 14:38:18 +00:00
Merge branch 'master' into pr_cmake
This commit is contained in:
commit
02e716f509
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -16,6 +16,8 @@ scripts/work/
|
|||
/SDL.dll
|
||||
/freetype.dll
|
||||
/autoexec.cfg
|
||||
other/freetype
|
||||
other/sdl
|
||||
_test.exe
|
||||
Info.plist
|
||||
|
||||
|
|
15
bam.lua
15
bam.lua
|
@ -268,6 +268,12 @@ function GenerateWindowsSettings(settings, conf, target_arch, compiler)
|
|||
|
||||
-- Content
|
||||
BuildContent(settings)
|
||||
|
||||
-- dependencies
|
||||
AddJob("other/sdl/include/SDL.h", "Downloading SDL2 headers and DLL...", dl .. " sdl SDL2.dll") -- TODO: split up dll and headers!
|
||||
AddJob("other/freetype/include/ft2build.h", "Downloading freetype headers and DLL...", dl .. " freetype freetype.dll")
|
||||
AddDependency(cur_builddir .. "/objs/engine/client/backend_sdl" .. settings.cc.extension, "other/sdl/include/SDL.h")
|
||||
AddDependency(cur_builddir .. "/objs/engine/client/text" .. settings.cc.extension, "other/freetype/include/ft2build.h")
|
||||
end
|
||||
|
||||
function SharedCommonFiles()
|
||||
|
@ -433,7 +439,7 @@ function GenerateSettings(conf, arch, builddir, compiler)
|
|||
return settings
|
||||
end
|
||||
|
||||
-- String formatting wth named parameters, by RiciLake http://lua-users.org/wiki/StringInterpolation
|
||||
-- String formatting with named parameters, by RiciLake http://lua-users.org/wiki/StringInterpolation
|
||||
function interp(s, tab)
|
||||
return (s:gsub('%%%((%a%w*)%)([-0-9%.]*[cdeEfgGiouxXsq])',
|
||||
function(k, fmt)
|
||||
|
@ -495,12 +501,19 @@ end
|
|||
for a, cur_arch in ipairs(archs) do
|
||||
for c, cur_conf in ipairs(confs) do
|
||||
cur_builddir = interp(builddir, {platform=family, arch=cur_arch, target=cur_target, conf=cur_conf, compiler=compiler})
|
||||
if family == "windows" then
|
||||
dl = Python("scripts/download.py")
|
||||
dl = dl .. " --arch " .. cur_arch .. " --conf " .. cur_conf
|
||||
AddJob(cur_builddir .. "/SDL2.dll", "Downloading SDL.dll for " .. cur_arch .. "/" .. cur_conf, dl .. " SDL2.dll") -- TODO: Make me working!
|
||||
AddJob(cur_builddir .. "/freetype.dll", "Downloading freetype.dll for " .. cur_arch .. "/" .. cur_conf, dl .. " freetype.dll")
|
||||
end
|
||||
local settings = GenerateSettings(cur_conf, cur_arch, cur_builddir, compiler)
|
||||
for t, cur_target in pairs(targets) do
|
||||
table.insert(subtargets[cur_target], PathJoin(cur_builddir, cur_target .. settings.link.extension))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for cur_name, cur_target in pairs(targets) do
|
||||
-- Supertarget for all configurations and architectures of that target
|
||||
PseudoTarget(cur_name, subtargets[cur_target])
|
||||
|
|
61
scripts/download.py
Normal file
61
scripts/download.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
import shutil, os, re, sys, zipfile
|
||||
from distutils.dir_util import copy_tree
|
||||
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])) + "/..")
|
||||
import twlib
|
||||
|
||||
def unzip(filename, where):
|
||||
try:
|
||||
z = zipfile.ZipFile(filename, "r")
|
||||
except:
|
||||
return False
|
||||
for name in z.namelist():
|
||||
z.extract(name, where)
|
||||
z.close()
|
||||
return z.namelist()[0]
|
||||
|
||||
def downloadAll(arch, conf, targets):
|
||||
url = "https://github.com/teeworlds/teeworlds-libs/archive/master.zip"
|
||||
if arch == "x86_64":
|
||||
_arch = "x64"
|
||||
else:
|
||||
_arch = arch
|
||||
builddir = "build/" + arch + "/" + conf + "/"
|
||||
|
||||
# download and unzip
|
||||
src_package_libs = twlib.fetch_file(url)
|
||||
if not src_package_libs:
|
||||
print("couldn't download libs")
|
||||
sys.exit(-1)
|
||||
libs_dir = unzip(src_package_libs, ".")
|
||||
if not libs_dir:
|
||||
print("couldn't unzip libs")
|
||||
sys.exit(-1)
|
||||
libs_dir = "teeworlds-libs-master"
|
||||
|
||||
if "SDL2.dll" in targets:
|
||||
shutil.copy(libs_dir + "/sdl/windows/lib/" + _arch + "/SDL2.dll", builddir)
|
||||
if "freetype.dll" in targets:
|
||||
shutil.copy(libs_dir + "/freetype/windows/lib/" + _arch + "/freetype.dll", builddir)
|
||||
if "sdl" in targets:
|
||||
copy_tree(libs_dir + "/sdl/windows/", "other/sdl/")
|
||||
if "freetype" in targets:
|
||||
copy_tree(libs_dir + "/freetype/windows/", "other/freetype/")
|
||||
|
||||
# cleanup
|
||||
try:
|
||||
shutil.rmtree(libs_dir)
|
||||
os.remove(src_package_libs)
|
||||
except: pass
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
p = argparse.ArgumentParser(description="Download freetype and SDL library and header files for Windows.")
|
||||
p.add_argument("--arch", default="x86", choices=["x86", "x86_64"], help="Architecture for the downloaded libraries (Default: x86)")
|
||||
p.add_argument("--conf", default="debug", choices=["debug", "release"], help="Build type (Default: debug)")
|
||||
p.add_argument("targets", metavar="TARGET", nargs='+', choices=["SDL2.dll", "freetype.dll", "sdl", "freetype"], help='Target to download. Valid choices are "SDL.dll", "freetype.dll", "sdl" and "freetype"')
|
||||
args = p.parse_args()
|
||||
|
||||
downloadAll(args.arch, args.conf, args.targets)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1798,6 +1798,22 @@ void str_sanitize(char *str_in)
|
|||
}
|
||||
}
|
||||
|
||||
/* removes all forbidden windows/unix characters in filenames*/
|
||||
char* str_sanitize_filename(char* aName)
|
||||
{
|
||||
char *str = (char *)aName;
|
||||
while(*str)
|
||||
{
|
||||
// replace forbidden characters with a whispace
|
||||
if(*str == '/' || *str == '<' || *str == '>' || *str == ':' || *str == '"'
|
||||
|| *str == '/' || *str == '\\' || *str == '|' || *str == '?' || *str == '*')
|
||||
*str = ' ';
|
||||
str++;
|
||||
}
|
||||
str_clean_whitespaces(aName);
|
||||
return aName;
|
||||
}
|
||||
|
||||
/* removes leading and trailing spaces and limits the use of multiple spaces */
|
||||
void str_clean_whitespaces(char *str_in)
|
||||
{
|
||||
|
|
|
@ -841,6 +841,19 @@ void str_sanitize_cc(char *str);
|
|||
*/
|
||||
void str_sanitize(char *str);
|
||||
|
||||
/*
|
||||
Function: str_sanitize_filename
|
||||
Replaces all forbidden Windows/Unix characters with whitespace
|
||||
or nothing if leading or trailing.
|
||||
|
||||
Parameters:
|
||||
str - String to sanitize.
|
||||
|
||||
Remarks:
|
||||
- The strings are treated as zero-terminated strings.
|
||||
*/
|
||||
char* str_sanitize_filename(char* aName);
|
||||
|
||||
/*
|
||||
Function: str_check_pathname
|
||||
Check if the string contains '..' (parent directory) paths.
|
||||
|
|
|
@ -12,11 +12,10 @@
|
|||
#include "graphics_threaded.h"
|
||||
#include "backend_sdl.h"
|
||||
|
||||
|
||||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
PFNGLTEXIMAGE3DPROC glTexImage3DInternal;
|
||||
|
||||
void GLAPIENTRY glTexImage3D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
|
||||
GLAPI void APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
|
||||
{
|
||||
glTexImage3DInternal(target, level, internalFormat, width, height, depth, border, format, type, pixels);
|
||||
}
|
||||
|
|
|
@ -125,21 +125,23 @@ static void Mix(short *pFinalOut, unsigned Frames)
|
|||
float Dist = sqrtf((float)dx*dx+dy*dy);
|
||||
if(Dist >= 0.0f && Dist < m_MaxDistance)
|
||||
{
|
||||
// constant panning (-3dB center)
|
||||
float a = 0.5f;
|
||||
if(dx < 0)
|
||||
a -= (Dist/m_MaxDistance)/2.0f;
|
||||
else
|
||||
a += (Dist/m_MaxDistance)/2.0f;
|
||||
|
||||
float Lgain = sinf((1-a)*pi/2.0f);
|
||||
float Rgain = sinf(a*pi/2.0f);
|
||||
|
||||
// linear falloff
|
||||
float Falloff = 1.0f - Dist/m_MaxDistance;
|
||||
|
||||
Lvol = Lvol*Lgain*Falloff;
|
||||
Rvol = Rvol*Rgain*Falloff;
|
||||
// amplitude after falloff
|
||||
float FalloffAmp = v->m_pChannel->m_Vol * Falloff;
|
||||
|
||||
// distribute volume to the channels depending on x difference
|
||||
float Lpan = 0.5f - dx/m_MaxDistance/2.0f;
|
||||
float Rpan = 1.0f - Lpan;
|
||||
|
||||
// apply square root to preserve sound power after panning
|
||||
float LampFactor = sqrt(Lpan);
|
||||
float RampFactor = sqrt(Rpan);
|
||||
|
||||
// volume of the channels
|
||||
Lvol = FalloffAmp*LampFactor;
|
||||
Rvol = FalloffAmp*RampFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -760,8 +760,8 @@ void CServer::SendRconCmdRem(const IConsole::CCommandInfo *pCommandInfo, int Cli
|
|||
|
||||
void CServer::UpdateClientRconCommands()
|
||||
{
|
||||
int ClientID = Tick() % MAX_CLIENTS;
|
||||
|
||||
for(int ClientID = Tick() % MAX_RCONCMD_RATIO; ClientID < MaxClients(); ClientID += MAX_RCONCMD_RATIO)
|
||||
{
|
||||
if(m_aClients[ClientID].m_State != CClient::STATE_EMPTY && m_aClients[ClientID].m_Authed)
|
||||
{
|
||||
int ConsoleAccessLevel = m_aClients[ClientID].m_Authed == AUTHED_ADMIN ? IConsole::ACCESS_LEVEL_ADMIN : IConsole::ACCESS_LEVEL_MOD;
|
||||
|
@ -771,6 +771,7 @@ void CServer::UpdateClientRconCommands()
|
|||
m_aClients[ClientID].m_pRconCmdToSend = m_aClients[ClientID].m_pRconCmdToSend->NextCommandInfo(ConsoleAccessLevel, CFGFLAG_SERVER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
||||
|
|
|
@ -76,6 +76,7 @@ public:
|
|||
AUTHED_ADMIN,
|
||||
|
||||
MAX_RCONCMD_SEND=16,
|
||||
MAX_RCONCMD_RATIO=8,
|
||||
};
|
||||
|
||||
class CClient
|
||||
|
|
|
@ -139,6 +139,11 @@ void CChat::ConShowChat(IConsole::IResult *pResult, void *pUserData)
|
|||
((CChat *)pUserData)->m_Show = pResult->GetInteger(0) != 0;
|
||||
}
|
||||
|
||||
void CChat::OnInit()
|
||||
{
|
||||
m_Input.Init(Input());
|
||||
}
|
||||
|
||||
void CChat::OnConsoleInit()
|
||||
{
|
||||
Console()->Register("say", "r", CFGFLAG_CLIENT, ConSay, this, "Say in chat");
|
||||
|
|
|
@ -81,6 +81,7 @@ public:
|
|||
|
||||
void Say(int Team, const char *pLine);
|
||||
|
||||
virtual void OnInit();
|
||||
virtual void OnReset();
|
||||
virtual void OnConsoleInit();
|
||||
virtual void OnStateChange(int NewState, int OldState);
|
||||
|
|
|
@ -57,6 +57,7 @@ CGameConsole::CInstance::CInstance(int Type)
|
|||
void CGameConsole::CInstance::Init(CGameConsole *pGameConsole)
|
||||
{
|
||||
m_pGameConsole = pGameConsole;
|
||||
m_Input.Init(m_pGameConsole->Input());
|
||||
};
|
||||
|
||||
void CGameConsole::CInstance::ClearBacklog()
|
||||
|
|
|
@ -448,11 +448,10 @@ int CMenus::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrS
|
|||
s_DoScroll = true;
|
||||
s_ScrollStart = UI()->MouseX();
|
||||
int MxRel = (int)(UI()->MouseX() - pRect->x);
|
||||
float Offset = pRect->w/2.0f-TextRender()->TextWidth(0, FontSize, pStr, -1)/2.0f;
|
||||
|
||||
for(int i = 1; i <= Len; i++)
|
||||
{
|
||||
if(Offset + TextRender()->TextWidth(0, FontSize, pStr, i) - *pOffset > MxRel)
|
||||
if(TextRender()->TextWidth(0, FontSize, pStr, i) - *pOffset > MxRel)
|
||||
{
|
||||
s_AtIndex = i - 1;
|
||||
break;
|
||||
|
@ -487,7 +486,7 @@ int CMenus::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrS
|
|||
{
|
||||
Len = str_length(pStr);
|
||||
int NumChars = Len;
|
||||
ReturnValue |= CLineInput::Manipulate(Input()->GetEvent(i), pStr, StrSize, StrSize, &Len, &s_AtIndex, &NumChars);
|
||||
ReturnValue |= CLineInput::Manipulate(Input()->GetEvent(i), pStr, StrSize, StrSize, &Len, &s_AtIndex, &NumChars, Input());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -562,15 +561,14 @@ int CMenus::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrS
|
|||
UI()->ClipEnable(pRect);
|
||||
Textbox.x -= *pOffset;
|
||||
|
||||
UI()->DoLabel(&Textbox, pDisplayStr, FontSize, CUI::ALIGN_CENTER);
|
||||
UI()->DoLabel(&Textbox, pDisplayStr, FontSize, CUI::ALIGN_LEFT);
|
||||
|
||||
// render the cursor
|
||||
if(UI()->LastActiveItem() == pID && !JustGotActive)
|
||||
{
|
||||
float w = TextRender()->TextWidth(0, FontSize, pDisplayStr, -1);
|
||||
float w = TextRender()->TextWidth(0, FontSize, pDisplayStr, s_AtIndex);
|
||||
Textbox = *pRect;
|
||||
Textbox.x += Textbox.w/2.0f-w/2.0f;
|
||||
w = TextRender()->TextWidth(0, FontSize, pDisplayStr, s_AtIndex);
|
||||
Textbox.VSplitLeft(2.0f, 0, &Textbox);
|
||||
Textbox.x += (w-*pOffset-TextRender()->TextWidth(0, FontSize, "|", -1)/2);
|
||||
|
||||
if((2*time_get()/time_freq()) % 2) // make it blink
|
||||
|
|
|
@ -531,7 +531,7 @@ private:
|
|||
void HandleCallvote(int Page, bool Force);
|
||||
void RenderServerControl(CUIRect MainView);
|
||||
void RenderServerControlKick(CUIRect MainView, bool FilterSpectators);
|
||||
void RenderServerControlServer(CUIRect MainView);
|
||||
bool RenderServerControlServer(CUIRect MainView);
|
||||
|
||||
// found in menus_browser.cpp
|
||||
// int m_ScrollOffset;
|
||||
|
|
|
@ -2132,11 +2132,15 @@ void CMenus::RenderServerbrowserBottomBox(CUIRect MainView)
|
|||
}
|
||||
void CMenus::DoGameIcon(const char *pName, const CUIRect *pRect, int Type)
|
||||
{
|
||||
char aNameBuf[128];
|
||||
str_copy(aNameBuf, pName, sizeof(aNameBuf));
|
||||
str_sanitize_filename(aNameBuf);
|
||||
|
||||
// get texture
|
||||
IGraphics::CTextureHandle Tex = m_GameIconDefault;
|
||||
for(int i = 0; i < m_lGameIcons.size(); ++i)
|
||||
{
|
||||
if(!str_comp_nocase(pName, m_lGameIcons[i].m_Name))
|
||||
if(!str_comp_nocase(aNameBuf, m_lGameIcons[i].m_Name))
|
||||
{
|
||||
Tex = m_lGameIcons[i].m_IconTexture;
|
||||
break;
|
||||
|
|
|
@ -469,8 +469,9 @@ void CMenus::RenderServerInfo(CUIRect MainView)
|
|||
TextRender()->Text(0, Motd.x, Motd.y, ButtonHeight*ms_FontmodHeight*0.8f, m_pClient->m_pMotd->GetMotd(), (int)Motd.w);
|
||||
}
|
||||
|
||||
void CMenus::RenderServerControlServer(CUIRect MainView)
|
||||
bool CMenus::RenderServerControlServer(CUIRect MainView)
|
||||
{
|
||||
bool doCallVote = false;
|
||||
static int s_VoteList = 0;
|
||||
static CListBoxState s_ListBoxState;
|
||||
CUIRect List = MainView;
|
||||
|
@ -489,7 +490,8 @@ void CMenus::RenderServerControlServer(CUIRect MainView)
|
|||
}
|
||||
}
|
||||
|
||||
m_CallvoteSelectedOption = UiDoListboxEnd(&s_ListBoxState, 0);
|
||||
m_CallvoteSelectedOption = UiDoListboxEnd(&s_ListBoxState, &doCallVote);
|
||||
return doCallVote;
|
||||
}
|
||||
|
||||
void CMenus::RenderServerControlKick(CUIRect MainView, bool FilterSpectators)
|
||||
|
@ -676,9 +678,10 @@ void CMenus::RenderServerControl(CUIRect MainView)
|
|||
MainView.HSplitBottom(90.0f+2*20.0f, &MainView, &Extended);
|
||||
RenderTools()->DrawUIRect(&Extended, vec4(0.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_ALL, 5.0f);
|
||||
|
||||
bool doCallVote = false;
|
||||
// render page
|
||||
if(s_ControlPage == 0)
|
||||
RenderServerControlServer(MainView);
|
||||
doCallVote = RenderServerControlServer(MainView); // double click triggers vote
|
||||
else if(s_ControlPage == 1)
|
||||
RenderServerControlKick(MainView, false);
|
||||
else if(s_ControlPage == 2)
|
||||
|
@ -720,7 +723,7 @@ void CMenus::RenderServerControl(CUIRect MainView)
|
|||
{
|
||||
// call vote
|
||||
static CButtonContainer s_CallVoteButton;
|
||||
if(DoButton_Menu(&s_CallVoteButton, Localize("Call vote"), 0, &Button))
|
||||
if(DoButton_Menu(&s_CallVoteButton, Localize("Call vote"), 0, &Button) || doCallVote)
|
||||
HandleCallvote(s_ControlPage, false);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
||||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||
#include <engine/keys.h>
|
||||
#include <engine/input.h>
|
||||
#include "lineinput.h"
|
||||
|
||||
CLineInput::CLineInput()
|
||||
{
|
||||
Clear();
|
||||
m_pInput = 0;
|
||||
}
|
||||
|
||||
void CLineInput::Clear()
|
||||
|
@ -16,6 +18,11 @@ void CLineInput::Clear()
|
|||
m_NumChars = 0;
|
||||
}
|
||||
|
||||
void CLineInput::Init(IInput *pInput)
|
||||
{
|
||||
m_pInput = pInput;
|
||||
}
|
||||
|
||||
void CLineInput::Set(const char *pString)
|
||||
{
|
||||
str_copy(m_Str, pString, sizeof(m_Str));
|
||||
|
@ -30,7 +37,15 @@ void CLineInput::Set(const char *pString)
|
|||
}
|
||||
}
|
||||
|
||||
bool CLineInput::Manipulate(IInput::CEvent Event, char *pStr, int StrMaxSize, int StrMaxChars, int *pStrLenPtr, int *pCursorPosPtr, int *pNumCharsPtr)
|
||||
bool CLineInput::CtrlStop(char c)
|
||||
{
|
||||
// jump to spaces and special ASCII characters
|
||||
return ((32 <= c && c <= 47) || // !"#$%&'()*+,-./
|
||||
(58 <= c && c <= 64) || // :;<=>?@
|
||||
(91 <= c && c <= 96)); // [\]^_`
|
||||
}
|
||||
|
||||
bool CLineInput::Manipulate(IInput::CEvent Event, char *pStr, int StrMaxSize, int StrMaxChars, int *pStrLenPtr, int *pCursorPosPtr, int *pNumCharsPtr, IInput *pInput)
|
||||
{
|
||||
int NumChars = *pNumCharsPtr;
|
||||
int CursorPos = *pCursorPosPtr;
|
||||
|
@ -74,31 +89,54 @@ bool CLineInput::Manipulate(IInput::CEvent Event, char *pStr, int StrMaxSize, in
|
|||
if(Event.m_Flags&IInput::FLAG_PRESS)
|
||||
{
|
||||
int Key = Event.m_Key;
|
||||
bool Ctrl = false;
|
||||
#ifdef CONF_PLATFORM_MACOSX
|
||||
if(pInput && (pInput->KeyIsPressed(KEY_LALT) || pInput->KeyIsPressed(KEY_RALT)))
|
||||
#else
|
||||
if(pInput && (pInput->KeyIsPressed(KEY_LCTRL) || pInput->KeyIsPressed(KEY_RCTRL)))
|
||||
#endif
|
||||
Ctrl = true;
|
||||
if(Key == KEY_BACKSPACE && CursorPos > 0)
|
||||
{
|
||||
int NewCursorPos = str_utf8_rewind(pStr, CursorPos);
|
||||
int NewCursorPos = CursorPos;
|
||||
do
|
||||
{
|
||||
NewCursorPos = str_utf8_rewind(pStr, NewCursorPos);
|
||||
NumChars -= 1;
|
||||
} while(Ctrl && NewCursorPos > 0 && !CtrlStop(pStr[NewCursorPos - 1]));
|
||||
int CharSize = CursorPos-NewCursorPos;
|
||||
mem_move(pStr+NewCursorPos, pStr+CursorPos, Len - NewCursorPos - CharSize + 1); // +1 == null term
|
||||
CursorPos = NewCursorPos;
|
||||
Len -= CharSize;
|
||||
if(CharSize > 0)
|
||||
--NumChars;
|
||||
Changes = true;
|
||||
}
|
||||
else if(Key == KEY_DELETE && CursorPos < Len)
|
||||
{
|
||||
int p = str_utf8_forward(pStr, CursorPos);
|
||||
int CharSize = p-CursorPos;
|
||||
int EndCursorPos = CursorPos;
|
||||
do
|
||||
{
|
||||
EndCursorPos = str_utf8_forward(pStr, EndCursorPos);
|
||||
NumChars -= 1;
|
||||
} while(Ctrl && EndCursorPos < Len && !CtrlStop(pStr[EndCursorPos - 1]));
|
||||
int CharSize = EndCursorPos - CursorPos;
|
||||
mem_move(pStr + CursorPos, pStr + CursorPos + CharSize, Len - CursorPos - CharSize + 1); // +1 == null term
|
||||
Len -= CharSize;
|
||||
if(CharSize > 0)
|
||||
--NumChars;
|
||||
Changes = true;
|
||||
}
|
||||
else if(Key == KEY_LEFT && CursorPos > 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
CursorPos = str_utf8_rewind(pStr, CursorPos);
|
||||
} while(Ctrl && CursorPos > 0 && !CtrlStop(pStr[CursorPos - 1]));
|
||||
}
|
||||
else if(Key == KEY_RIGHT && CursorPos < Len)
|
||||
{
|
||||
do
|
||||
{
|
||||
CursorPos = str_utf8_forward(pStr, CursorPos);
|
||||
} while(Ctrl && CursorPos < Len && !CtrlStop(pStr[CursorPos - 1]));
|
||||
}
|
||||
else if(Key == KEY_HOME)
|
||||
CursorPos = 0;
|
||||
else if(Key == KEY_END)
|
||||
|
@ -114,5 +152,5 @@ bool CLineInput::Manipulate(IInput::CEvent Event, char *pStr, int StrMaxSize, in
|
|||
|
||||
bool CLineInput::ProcessInput(IInput::CEvent e)
|
||||
{
|
||||
return Manipulate(e, m_Str, MAX_SIZE, MAX_CHARS, &m_Len, &m_CursorPos, &m_NumChars);
|
||||
return Manipulate(e, m_Str, MAX_SIZE, MAX_CHARS, &m_Len, &m_CursorPos, &m_NumChars, m_pInput);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,10 @@ class CLineInput
|
|||
int m_Len;
|
||||
int m_CursorPos;
|
||||
int m_NumChars;
|
||||
IInput *m_pInput;
|
||||
public:
|
||||
static bool Manipulate(IInput::CEvent e, char *pStr, int StrMaxSize, int StrMaxChars, int *pStrLenPtr, int *pCursorPosPtr, int *pNumCharsPtr);
|
||||
static bool CtrlStop(char c);
|
||||
static bool Manipulate(IInput::CEvent e, char *pStr, int StrMaxSize, int StrMaxChars, int *pStrLenPtr, int *pCursorPosPtr, int *pNumCharsPtr, IInput *pInput);
|
||||
|
||||
class CCallback
|
||||
{
|
||||
|
@ -28,6 +30,7 @@ public:
|
|||
};
|
||||
|
||||
CLineInput();
|
||||
void Init(IInput *pInput);
|
||||
void Clear();
|
||||
bool ProcessInput(IInput::CEvent e);
|
||||
void Set(const char *pString);
|
||||
|
|
|
@ -340,7 +340,7 @@ int CEditor::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned Str
|
|||
{
|
||||
Len = str_length(pStr);
|
||||
int NumChars = Len;
|
||||
ReturnValue |= CLineInput::Manipulate(Input()->GetEvent(i), pStr, StrSize, StrSize, &Len, &s_AtIndex, &NumChars);
|
||||
ReturnValue |= CLineInput::Manipulate(Input()->GetEvent(i), pStr, StrSize, StrSize, &Len, &s_AtIndex, &NumChars, Input());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue