mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Working on installer, fixing more Win32 issues
Throwing error on member references with ".." cascade token outside invocations (ie: "ts..mA = 123") Fixed 'Thread.ModuleTLSIndex' error - which caused us TLS lookup failures in Beef DLLs Fixed some hotswap errors Made BeefPerf shut down properly Fixed an 'int literal' FixIntUnknown issue where rhs was System.Object which caused an illegal boxing Fixed COFF::LocateSymbol issues with Win32 and also with linking to static libraries - showed up with hot-linking in fmod when hot-adding a floating point mod Fixed a couple memory leaks Fixed alignment issue in COFF::ParseCompileUnit
This commit is contained in:
parent
aad0a640c5
commit
b63a243fd7
73 changed files with 2474 additions and 293 deletions
|
@ -11,6 +11,7 @@ using Beefy.utils;
|
||||||
using Beefy.res;
|
using Beefy.res;
|
||||||
using Beefy.geom;
|
using Beefy.geom;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Beefy.sound;
|
||||||
#if MONOTOUCH
|
#if MONOTOUCH
|
||||||
using MonoTouch;
|
using MonoTouch;
|
||||||
#endif
|
#endif
|
||||||
|
@ -61,6 +62,7 @@ namespace Beefy
|
||||||
public bool mStarted;
|
public bool mStarted;
|
||||||
|
|
||||||
public ResourceManager mResourceManager ~ delete _;
|
public ResourceManager mResourceManager ~ delete _;
|
||||||
|
public SoundManager mSoundManager = new SoundManager() ~ delete _;
|
||||||
|
|
||||||
public int32 mFPSDrawCount;
|
public int32 mFPSDrawCount;
|
||||||
public int32 mFPSUpdateCount;
|
public int32 mFPSUpdateCount;
|
||||||
|
@ -124,6 +126,9 @@ namespace Beefy
|
||||||
[StdCall, CLink]
|
[StdCall, CLink]
|
||||||
public static extern void BFApp_RehupMouse();
|
public static extern void BFApp_RehupMouse();
|
||||||
|
|
||||||
|
[StdCall, CLink]
|
||||||
|
public static extern void* BFApp_GetSoundManager();
|
||||||
|
|
||||||
UpdateDelegate mUpdateDelegate ~ delete _;
|
UpdateDelegate mUpdateDelegate ~ delete _;
|
||||||
DrawDelegate mDrawDelegate ~ delete _;
|
DrawDelegate mDrawDelegate ~ delete _;
|
||||||
|
|
||||||
|
@ -467,6 +472,8 @@ namespace Beefy
|
||||||
#endif
|
#endif
|
||||||
BFApp_Init();
|
BFApp_Init();
|
||||||
|
|
||||||
|
mSoundManager.[Friend]mNativeSoundManager = BFApp_GetSoundManager();
|
||||||
|
|
||||||
Interlocked.Fence();
|
Interlocked.Fence();
|
||||||
|
|
||||||
mInstallDir = new String(BFApp_GetInstallDir());
|
mInstallDir = new String(BFApp_GetInstallDir());
|
||||||
|
|
|
@ -107,9 +107,7 @@ namespace Beefy.gfx
|
||||||
mClipDisposeProxy.mDisposeProxyDelegate = new => PopClip;
|
mClipDisposeProxy.mDisposeProxyDelegate = new => PopClip;
|
||||||
mRenderStateDisposeProxy = new DisposeProxy();
|
mRenderStateDisposeProxy = new DisposeProxy();
|
||||||
|
|
||||||
String filePath = scope String();
|
mWhiteDot = Image.LoadFromFile("!white");
|
||||||
filePath.Append(BFApp.sApp.mInstallDir, "images/whiteDot.tga");
|
|
||||||
mWhiteDot = Image.LoadFromFile(filePath);
|
|
||||||
|
|
||||||
for (int32 i = 0; i < MATIX_STACK_SIZE; i++)
|
for (int32 i = 0; i < MATIX_STACK_SIZE; i++)
|
||||||
mMatrixStack[i] = Matrix.IdentityMatrix;
|
mMatrixStack[i] = Matrix.IdentityMatrix;
|
||||||
|
|
|
@ -4,8 +4,8 @@ using System.Text;
|
||||||
|
|
||||||
namespace Beefy.res
|
namespace Beefy.res
|
||||||
{
|
{
|
||||||
public class SoundGameObject
|
/*public class SoundGameObject
|
||||||
{
|
{
|
||||||
public void* mWwiseObject;
|
public void* mWwiseObject;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
43
BeefLibs/Beefy2D/src/sound/SoundInstance.bf
Normal file
43
BeefLibs/Beefy2D/src/sound/SoundInstance.bf
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Beefy.sound
|
||||||
|
{
|
||||||
|
struct SoundInstance
|
||||||
|
{
|
||||||
|
[StdCall, CLink]
|
||||||
|
public static extern void* BFSoundInstance_Play(void* nativeSoundInstance, bool looping, bool autoRelease);
|
||||||
|
|
||||||
|
[StdCall, CLink]
|
||||||
|
public static extern void BFSoundInstance_Release(void* nativeSoundInstance);
|
||||||
|
|
||||||
|
[StdCall, CLink]
|
||||||
|
public static extern bool BFSoundInstance_IsPlaying(void* nativeSoundInstance);
|
||||||
|
|
||||||
|
void* mNativeSoundInstance;
|
||||||
|
|
||||||
|
public this(void* nativeSoundInstance)
|
||||||
|
{
|
||||||
|
mNativeSoundInstance = nativeSoundInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() mut
|
||||||
|
{
|
||||||
|
BFSoundInstance_Release(mNativeSoundInstance);
|
||||||
|
mNativeSoundInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Play(bool looping = false, bool autoRelease = false)
|
||||||
|
{
|
||||||
|
if (mNativeSoundInstance == null)
|
||||||
|
return;
|
||||||
|
BFSoundInstance_Play(mNativeSoundInstance, looping, autoRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsPlaying()
|
||||||
|
{
|
||||||
|
if (mNativeSoundInstance == null)
|
||||||
|
return false;
|
||||||
|
return BFSoundInstance_IsPlaying(mNativeSoundInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
BeefLibs/Beefy2D/src/sound/SoundManager.bf
Normal file
43
BeefLibs/Beefy2D/src/sound/SoundManager.bf
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Beefy.sound
|
||||||
|
{
|
||||||
|
struct SoundSource : int32
|
||||||
|
{
|
||||||
|
public bool IsInvalid
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this == (.)-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SoundManager
|
||||||
|
{
|
||||||
|
void* mNativeSoundManager;
|
||||||
|
|
||||||
|
[StdCall, CLink]
|
||||||
|
public static extern int32 BFSoundManager_LoadSound(void* nativeSoundManager, char8* fileName);
|
||||||
|
|
||||||
|
[StdCall, CLink]
|
||||||
|
public static extern void* BFSoundManager_GetSoundInstance(void* nativeSoundManager, int32 sfxId);
|
||||||
|
|
||||||
|
public SoundSource LoadSound(StringView fileName)
|
||||||
|
{
|
||||||
|
return (.)BFSoundManager_LoadSound(mNativeSoundManager, fileName.ToScopeCStr!());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoundInstance GetSoundInstance(SoundSource soundSource)
|
||||||
|
{
|
||||||
|
void* nativeSoundInstance = BFSoundManager_GetSoundInstance(mNativeSoundManager, (.)soundSource);
|
||||||
|
return .(nativeSoundInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PlaySound(SoundSource soundSource)
|
||||||
|
{
|
||||||
|
let soundInstance = GetSoundInstance(soundSource);
|
||||||
|
soundInstance.Play(false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ namespace Beefy.widgets
|
||||||
{
|
{
|
||||||
if ((mMouseOver && mMouseDown) && (mDownImage != null))
|
if ((mMouseOver && mMouseDown) && (mDownImage != null))
|
||||||
g.Draw(mDownImage);
|
g.Draw(mDownImage);
|
||||||
if ((mMouseOver) && (mOverImage != null))
|
else if ((mMouseOver) && (mOverImage != null))
|
||||||
g.Draw(mOverImage);
|
g.Draw(mOverImage);
|
||||||
else
|
else
|
||||||
g.Draw(mImage);
|
g.Draw(mImage);
|
||||||
|
|
|
@ -9,8 +9,9 @@ namespace Beefy.widgets
|
||||||
public class LabelWidget : Widget
|
public class LabelWidget : Widget
|
||||||
{
|
{
|
||||||
public Font mFont;
|
public Font mFont;
|
||||||
public String mLabel;
|
public String mLabel ~ delete _;
|
||||||
public uint32 mColor = Color.White;
|
public uint32 mColor = Color.White;
|
||||||
|
public FontAlign mAlign = .Left;
|
||||||
|
|
||||||
public override void Draw(Graphics g)
|
public override void Draw(Graphics g)
|
||||||
{
|
{
|
||||||
|
@ -18,7 +19,12 @@ namespace Beefy.widgets
|
||||||
|
|
||||||
g.SetFont(mFont);
|
g.SetFont(mFont);
|
||||||
using (g.PushColor(mColor))
|
using (g.PushColor(mColor))
|
||||||
g.DrawString(mLabel, 0, 0);
|
g.DrawString(mLabel, 0, 0, mAlign, mWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float CalcWidth()
|
||||||
|
{
|
||||||
|
return mFont.GetWidth(mLabel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ namespace Beefy.widgets
|
||||||
{
|
{
|
||||||
if ((value.a == 1) && (value.b == 0) && (value.c == 0) && (value.d == 1))
|
if ((value.a == 1) && (value.b == 0) && (value.c == 0) && (value.d == 1))
|
||||||
{
|
{
|
||||||
mTransformData = null;
|
DeleteAndNullify!(mTransformData);
|
||||||
mX = value.tx;
|
mX = value.tx;
|
||||||
mY = value.ty;
|
mY = value.ty;
|
||||||
}
|
}
|
||||||
|
@ -142,6 +142,11 @@ namespace Beefy.widgets
|
||||||
mOnDeleted(this);
|
mOnDeleted(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearTransform()
|
||||||
|
{
|
||||||
|
DeleteAndNullify!(mTransformData);
|
||||||
|
}
|
||||||
|
|
||||||
public void MarkDirty()
|
public void MarkDirty()
|
||||||
{
|
{
|
||||||
if (mWidgetWindow != null)
|
if (mWidgetWindow != null)
|
||||||
|
|
|
@ -428,7 +428,15 @@ namespace Beefy.widgets
|
||||||
{
|
{
|
||||||
var result = mOnHitTest(x, y);
|
var result = mOnHitTest(x, y);
|
||||||
if (result != HitTestResult.NotHandled)
|
if (result != HitTestResult.NotHandled)
|
||||||
|
{
|
||||||
|
if (result != .Client)
|
||||||
|
{
|
||||||
|
if (mHasMouseInside)
|
||||||
|
MouseLeave();
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mWindowFlags.HasFlag(Flags.Resizable))
|
if (mWindowFlags.HasFlag(Flags.Resizable))
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace SDL2
|
namespace SDL2
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#region Using Statements
|
#region Using Statements
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
namespace SDL2
|
namespace SDL2
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace SDL2
|
namespace SDL2
|
||||||
{
|
{
|
||||||
|
@ -40,13 +39,13 @@ namespace SDL2
|
||||||
public const int32 SDL_TTF_PATCHLEVEL = 12;
|
public const int32 SDL_TTF_PATCHLEVEL = 12;
|
||||||
|
|
||||||
public const int32 UNICODE_BOM_NATIVE = 0xFEFF;
|
public const int32 UNICODE_BOM_NATIVE = 0xFEFF;
|
||||||
public const int32 UNICODE_BOM_SWAPPED = 0xFFFE;
|
public const int32 UNICODE_BOM_SWAPPED = 0xFFFE;
|
||||||
|
|
||||||
public const int32 TTF_STYLE_NORMAL = 0x00;
|
public const int32 TTF_STYLE_NORMAL = 0x00;
|
||||||
public const int32 TTF_STYLE_BOLD = 0x01;
|
public const int32 TTF_STYLE_BOLD = 0x01;
|
||||||
public const int32 TTF_STYLE_ITALIC = 0x02;
|
public const int32 TTF_STYLE_ITALIC = 0x02;
|
||||||
public const int32 TTF_STYLE_UNDERLINE = 0x04;
|
public const int32 TTF_STYLE_UNDERLINE = 0x04;
|
||||||
public const int32 TTF_STYLE_STRIKETHROUGH = 0x08;
|
public const int32 TTF_STYLE_STRIKETHROUGH = 0x08;
|
||||||
|
|
||||||
public const int32 TTF_HINTING_NORMAL = 0;
|
public const int32 TTF_HINTING_NORMAL = 0;
|
||||||
public const int32 TTF_HINTING_LIGHT = 1;
|
public const int32 TTF_HINTING_LIGHT = 1;
|
||||||
|
|
|
@ -181,7 +181,7 @@ namespace System.Threading
|
||||||
StartInternal();
|
StartInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if BF_PLATFORM_WINDOWS
|
||||||
[CLink]
|
[CLink]
|
||||||
static extern int32 _tls_index;
|
static extern int32 _tls_index;
|
||||||
#endif
|
#endif
|
||||||
|
@ -190,7 +190,7 @@ namespace System.Threading
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
#if PLATFORM_WINDOWS
|
#if BF_PLATFORM_WINDOWS
|
||||||
return _tls_index;
|
return _tls_index;
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -852,6 +852,12 @@ namespace System
|
||||||
public const int32 OFN_USESHELLITEM = 0x01000000;
|
public const int32 OFN_USESHELLITEM = 0x01000000;
|
||||||
|
|
||||||
public const int32 CSIDL_DESKTOP = 0x0000;
|
public const int32 CSIDL_DESKTOP = 0x0000;
|
||||||
|
public const int32 CSIDL_PROGRAMS = 0x0002; // Start Menu\Programs
|
||||||
|
public const int32 CSIDL_PERSONAL = 0x0005; // My Documents
|
||||||
|
public const int32 CSIDL_STARTUP = 0x0007; // Start Menu\Programs\Startup
|
||||||
|
public const int32 CSIDL_LOCAL_APPDATA = 0x001c;// <user name>\Local Settings\Applicaiton Data (non roaming)
|
||||||
|
public const int32 CSIDL_COMMON_APPDATA = 0x0023; // All Users\Application Data
|
||||||
|
public const int32 CSIDL_PROGRAM_FILES = 0x0026; // C:\Program Files
|
||||||
|
|
||||||
public const int32 WM_CLOSE = 0x0010;
|
public const int32 WM_CLOSE = 0x0010;
|
||||||
public const int32 WM_DESTROY = 0x0002;
|
public const int32 WM_DESTROY = 0x0002;
|
||||||
|
|
|
@ -589,6 +589,7 @@ BFGC::BFGC()
|
||||||
mForceDecommit = false;
|
mForceDecommit = false;
|
||||||
mLastCollectFrame = 0;
|
mLastCollectFrame = 0;
|
||||||
mSkipMark = false;
|
mSkipMark = false;
|
||||||
|
mGracelessShutdown = false;
|
||||||
mMainThreadTLSPtr = NULL;
|
mMainThreadTLSPtr = NULL;
|
||||||
|
|
||||||
mCollectIdx = 0;
|
mCollectIdx = 0;
|
||||||
|
@ -1933,6 +1934,14 @@ void BFGC::StopCollecting()
|
||||||
mExiting = true;
|
mExiting = true;
|
||||||
while (mRunning)
|
while (mRunning)
|
||||||
{
|
{
|
||||||
|
if (BfpThread_WaitFor(mGCThread, 0))
|
||||||
|
{
|
||||||
|
OutputDebugStr("BeefDbgRT not shut down gracefully!\n");
|
||||||
|
mGracelessShutdown = true;
|
||||||
|
mRunning = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
//BFRtLock bfLock(mEphemeronTombstone);
|
//BFRtLock bfLock(mEphemeronTombstone);
|
||||||
mWaitingForGC = true;
|
mWaitingForGC = true;
|
||||||
// Wait for current collection to finish
|
// Wait for current collection to finish
|
||||||
|
@ -1970,6 +1979,9 @@ void BFGC::Shutdown()
|
||||||
|
|
||||||
Beefy::AutoCrit autoCrit(mCritSect);
|
Beefy::AutoCrit autoCrit(mCritSect);
|
||||||
|
|
||||||
|
if (mGracelessShutdown)
|
||||||
|
return;
|
||||||
|
|
||||||
// Report any objects that aren't deleted
|
// Report any objects that aren't deleted
|
||||||
mSweepInfo.mShowAllAsLeaks = true;
|
mSweepInfo.mShowAllAsLeaks = true;
|
||||||
Sweep();
|
Sweep();
|
||||||
|
|
|
@ -267,6 +267,7 @@ public:
|
||||||
|
|
||||||
volatile bool mExiting;
|
volatile bool mExiting;
|
||||||
volatile bool mRunning;
|
volatile bool mRunning;
|
||||||
|
bool mGracelessShutdown;
|
||||||
bool mPaused;
|
bool mPaused;
|
||||||
bool mShutdown;
|
bool mShutdown;
|
||||||
bool mWaitingForGC; // GC.Collect sets this
|
bool mWaitingForGC; // GC.Collect sets this
|
||||||
|
|
|
@ -2,6 +2,7 @@ FileVersion = 1
|
||||||
|
|
||||||
[Project]
|
[Project]
|
||||||
Name = "Stub"
|
Name = "Stub"
|
||||||
|
TargetType = "BeefWindowsApplication"
|
||||||
StartupObject = "BIStub.Program"
|
StartupObject = "BIStub.Program"
|
||||||
|
|
||||||
[Configs.Debug.Win64]
|
[Configs.Debug.Win64]
|
||||||
|
|
|
@ -147,6 +147,8 @@ namespace BIStub
|
||||||
}
|
}
|
||||||
|
|
||||||
startFunc(=> UI_Install, => UI_GetProgress, => UI_Cancel);
|
startFunc(=> UI_Install, => UI_GetProgress, => UI_Cancel);
|
||||||
|
|
||||||
|
Windows.FreeLibrary(lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Run()
|
void Run()
|
||||||
|
@ -155,7 +157,7 @@ namespace BIStub
|
||||||
Directory.GetCurrentDirectory(cwd);
|
Directory.GetCurrentDirectory(cwd);
|
||||||
StartUI(cwd);
|
StartUI(cwd);
|
||||||
|
|
||||||
CheckPE();
|
/*CheckPE();
|
||||||
|
|
||||||
ZipFile zipFile = scope .();
|
ZipFile zipFile = scope .();
|
||||||
zipFile.Open(@"c:\\temp\\build_1827.zip");
|
zipFile.Open(@"c:\\temp\\build_1827.zip");
|
||||||
|
@ -163,7 +165,7 @@ namespace BIStub
|
||||||
|
|
||||||
CabFile cabFile = scope .();
|
CabFile cabFile = scope .();
|
||||||
cabFile.Init();
|
cabFile.Init();
|
||||||
cabFile.Copy();
|
cabFile.Copy();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Main(String[] args)
|
static int Main(String[] args)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Dependencies = {corlib = "*", Beefy2D = "*"}
|
Dependencies = {corlib = "*", Beefy2D = "*", SDL2 = "*"}
|
||||||
|
|
||||||
[Project]
|
[Project]
|
||||||
Name = "StubUI"
|
Name = "StubUI"
|
||||||
|
@ -11,7 +11,7 @@ DefaultNamespace = "BIStubUI"
|
||||||
TargetDirectory = "$(WorkspaceDir)/../dist"
|
TargetDirectory = "$(WorkspaceDir)/../dist"
|
||||||
TargetName = "$(ProjectName)_d"
|
TargetName = "$(ProjectName)_d"
|
||||||
OtherLinkFlags = "$(LinkFlags) BeefySysLib64_d.lib"
|
OtherLinkFlags = "$(LinkFlags) BeefySysLib64_d.lib"
|
||||||
PostBuildCmds = ["Sleep(1000)", "cmd.exe /c echo Hey!", "CopyFilesIfNewer(\"$(WorkspaceDir)/../../../IDE/dist/BeefySysLib*.*\", \"$(WorkspaceDir)/../dist\")"]
|
BeefLibType = "DynamicDebug"
|
||||||
DebugCommand = "$(WorkspaceDir)\\..\\dist\\Stub_d.exe"
|
DebugCommand = "$(WorkspaceDir)\\..\\dist\\Stub_d.exe"
|
||||||
|
|
||||||
[Configs.Release.Win64]
|
[Configs.Release.Win64]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Projects = {StubUI = {Path = "."}, Beefy2D = "*"}
|
Projects = {StubUI = {Path = "."}, Beefy2D = "*", SDL2 = "*"}
|
||||||
Unlocked = ["corlib"]
|
Unlocked = ["Beefy2D", "corlib", "SDL2"]
|
||||||
|
|
||||||
[Workspace]
|
[Workspace]
|
||||||
StartupProject = "StubUI"
|
StartupProject = "StubUI"
|
||||||
|
|
|
@ -1,36 +1,124 @@
|
||||||
using System;
|
using System;
|
||||||
using Beefy;
|
using Beefy;
|
||||||
using Beefy.widgets;
|
using Beefy.widgets;
|
||||||
|
using Beefy.geom;
|
||||||
|
using Beefy.gfx;
|
||||||
|
|
||||||
namespace BIStubUI
|
namespace BIStubUI
|
||||||
{
|
{
|
||||||
class BIApp : BFApp
|
class BIApp : BFApp
|
||||||
{
|
{
|
||||||
|
static int a = 123;
|
||||||
|
|
||||||
public function void InstallFunc(StringView dest, StringView filter);
|
public function void InstallFunc(StringView dest, StringView filter);
|
||||||
public function int ProgressFunc();
|
public function int ProgressFunc();
|
||||||
public function void CancelFunc();
|
public function void CancelFunc();
|
||||||
|
|
||||||
|
const int cWidth = 900;
|
||||||
|
const int cHeight = 620;
|
||||||
|
|
||||||
|
public Font mHeaderFont ~ delete _;
|
||||||
|
public Font mBodyFont ~ delete _;
|
||||||
|
public Font mBtnFont ~ delete _;
|
||||||
|
public Font mBoxFont ~ delete _;
|
||||||
|
|
||||||
public InstallFunc mInstallFunc;
|
public InstallFunc mInstallFunc;
|
||||||
public ProgressFunc mProgressFunc;
|
public ProgressFunc mProgressFunc;
|
||||||
public CancelFunc mCancelFunc;
|
public CancelFunc mCancelFunc;
|
||||||
|
|
||||||
Widget mRootWidget;
|
public Board mBoard;
|
||||||
WidgetWindow mMainWindow;
|
public Widget mRootWidget;
|
||||||
|
public WidgetWindow mMainWindow;
|
||||||
|
|
||||||
const int cWidth = 700;
|
public bool mCancelling;
|
||||||
const int cHeight = 700;
|
public bool mWantRehup;
|
||||||
|
public int32 mBoardDelay;
|
||||||
|
public bool mClosing;
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
Images.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
base.Init();
|
base.Init();
|
||||||
|
|
||||||
BFWindow.Flags windowFlags = BFWindow.Flags.Border | BFWindow.Flags.SysMenu | //| BFWindow.Flags.CaptureMediaKeys |
|
BFWindow.Flags windowFlags = .QuitOnClose
|
||||||
BFWindow.Flags.Caption | BFWindow.Flags.Minimize | BFWindow.Flags.QuitOnClose;
|
| .DestAlpha
|
||||||
|
;
|
||||||
|
|
||||||
|
GetWorkspaceRect(var workX, var workY, var workWidth, var workHeight);
|
||||||
|
|
||||||
mRootWidget = new Widget();
|
mRootWidget = new Widget();
|
||||||
mMainWindow = new WidgetWindow(null, "Beef Installer", 0, 0, cWidth, cHeight, windowFlags, mRootWidget);
|
mMainWindow = new WidgetWindow(null, "Beef Installer",
|
||||||
mMainWindow.SetMinimumSize(480, 360);
|
workX + (workWidth - cWidth)/2, workY + (workHeight - cHeight) / 2, cWidth, cHeight, windowFlags, mRootWidget);
|
||||||
mMainWindow.mIsMainWindow = true;
|
mMainWindow.mIsMainWindow = true;
|
||||||
|
mMainWindow.mOnHitTest.Add(new (absX, absY) =>
|
||||||
|
{
|
||||||
|
float x = absX - mMainWindow.mX;
|
||||||
|
float y = absY - mMainWindow.mY;
|
||||||
|
|
||||||
|
Widget aWidget = mRootWidget.FindWidgetByCoords(x, y);
|
||||||
|
if ((aWidget != null) && (aWidget != mBoard))
|
||||||
|
return .NotHandled;
|
||||||
|
|
||||||
|
if (Rect(60, 24, 700, 420).Contains(x, y))
|
||||||
|
return .Caption;
|
||||||
|
|
||||||
|
return .NotHandled;
|
||||||
|
});
|
||||||
|
|
||||||
|
Font CreateFont(StringView srcName, float fontSize)
|
||||||
|
{
|
||||||
|
Font font = new Font();
|
||||||
|
font.Load(srcName, fontSize);
|
||||||
|
font.AddAlternate("Segoe UI Symbol", fontSize);
|
||||||
|
font.AddAlternate("Segoe UI Historic", fontSize);
|
||||||
|
font.AddAlternate("Segoe UI Emoji", fontSize);
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
mHeaderFont = CreateFont("Segoe UI Bold", 42);
|
||||||
|
mBodyFont = CreateFont("Segoe UI", 22);
|
||||||
|
mBoxFont = CreateFont("Segoe UI", 18);
|
||||||
|
mBtnFont = CreateFont("Segoe UI", 32);
|
||||||
|
|
||||||
|
Images.Init();
|
||||||
|
Sounds.Init();
|
||||||
|
|
||||||
|
SetupBoard();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupBoard()
|
||||||
|
{
|
||||||
|
mBoard = new .();
|
||||||
|
mRootWidget.AddWidget(mBoard);
|
||||||
|
mBoard.Resize(0, 0, cWidth, cHeight);
|
||||||
|
mBoard.SetFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(bool batchStart)
|
||||||
|
{
|
||||||
|
base.Update(batchStart);
|
||||||
|
|
||||||
|
if (mCancelling)
|
||||||
|
{
|
||||||
|
mClosing = true;
|
||||||
|
if ((mBoard != null) && (mBoard.mIsClosed))
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mWantRehup)
|
||||||
|
{
|
||||||
|
mBoard.RemoveSelf();
|
||||||
|
DeleteAndNullify!(mBoard);
|
||||||
|
mBoardDelay = 30;
|
||||||
|
mWantRehup = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mBoardDelay > 0) && (--mBoardDelay == 0))
|
||||||
|
SetupBoard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
563
BeefTools/BeefInstall/StubUI/src/Board.bf
Normal file
563
BeefTools/BeefInstall/StubUI/src/Board.bf
Normal file
|
@ -0,0 +1,563 @@
|
||||||
|
using Beefy.widgets;
|
||||||
|
using Beefy.geom;
|
||||||
|
using Beefy.gfx;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace BIStubUI
|
||||||
|
{
|
||||||
|
class BiButtonWidget : ButtonWidget
|
||||||
|
{
|
||||||
|
public Image mImage;
|
||||||
|
public Image mImageHi;
|
||||||
|
|
||||||
|
public override void Draw(Graphics g)
|
||||||
|
{
|
||||||
|
if (mMouseOver && mMouseDown)
|
||||||
|
g.Draw(mImageHi);
|
||||||
|
if (mMouseOver)
|
||||||
|
g.Draw(mImageHi);
|
||||||
|
else
|
||||||
|
g.Draw(mImage);
|
||||||
|
|
||||||
|
/*using (g.PushColor(0x8000FF00))
|
||||||
|
g.FillRect(0, 0, mWidth, mHeight);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DrawAll(Graphics g)
|
||||||
|
{
|
||||||
|
using (g.PushColor(mDisabled ? 0xD0A0A0A0 : 0xFFFFFFFF))
|
||||||
|
base.DrawAll(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void MouseEnter()
|
||||||
|
{
|
||||||
|
base.MouseEnter();
|
||||||
|
if (!mDisabled)
|
||||||
|
{
|
||||||
|
gApp.SetCursor(.Hand);
|
||||||
|
gApp.mSoundManager.PlaySound(Sounds.sMouseOver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void MouseDown(float x, float y, int32 btn, int32 btnCount)
|
||||||
|
{
|
||||||
|
base.MouseDown(x, y, btn, btnCount);
|
||||||
|
if (!mDisabled)
|
||||||
|
gApp.mSoundManager.PlaySound(Sounds.sButtonPress);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void MouseLeave()
|
||||||
|
{
|
||||||
|
base.MouseLeave();
|
||||||
|
gApp.SetCursor(.Pointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BiDialogButton : BiButtonWidget
|
||||||
|
{
|
||||||
|
public String mLabel ~ delete _;
|
||||||
|
|
||||||
|
public override void Draw(Graphics g)
|
||||||
|
{
|
||||||
|
base.Draw(g);
|
||||||
|
|
||||||
|
g.SetFont(gApp.mBtnFont);
|
||||||
|
g.DrawString(mLabel, 0, 14, .Centered, mWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BiCheckbox : CheckBox
|
||||||
|
{
|
||||||
|
public State mState;
|
||||||
|
public String mLabel ~ delete _;
|
||||||
|
|
||||||
|
public override bool Checked
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mState != .Unchecked;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
gApp.mSoundManager.PlaySound(Sounds.sChecked);
|
||||||
|
mState = value ? .Checked : .Unchecked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override State State
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mState;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
mState = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(Graphics g)
|
||||||
|
{
|
||||||
|
if (mState == .Checked)
|
||||||
|
g.Draw(Images.sChecked);
|
||||||
|
else
|
||||||
|
g.Draw(Images.sUnchecked);
|
||||||
|
|
||||||
|
g.SetFont(gApp.mBodyFont);
|
||||||
|
using (g.PushColor(0xFF000000))
|
||||||
|
g.DrawString(mLabel, 40, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void MouseEnter()
|
||||||
|
{
|
||||||
|
base.MouseEnter();
|
||||||
|
gApp.SetCursor(.Hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void MouseLeave()
|
||||||
|
{
|
||||||
|
base.MouseLeave();
|
||||||
|
gApp.SetCursor(.Pointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BiInstallPathBox : Widget
|
||||||
|
{
|
||||||
|
public String mInstallPath = new .() ~ delete _;
|
||||||
|
ImageWidget mBrowseButton;
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
mBrowseButton = new ImageWidget();
|
||||||
|
mBrowseButton.mImage = Images.sBrowse;
|
||||||
|
mBrowseButton.mDownImage = Images.sBrowseDown;
|
||||||
|
mBrowseButton.mOnMouseClick.Add(new (mouseArgs) =>
|
||||||
|
{
|
||||||
|
var folderDialog = scope FolderBrowserDialog();
|
||||||
|
if (folderDialog.ShowDialog(mWidgetWindow).GetValueOrDefault() == .OK)
|
||||||
|
{
|
||||||
|
var selectedPath = scope String..AppendF(folderDialog.SelectedPath);
|
||||||
|
mInstallPath.Set(selectedPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AddWidget(mBrowseButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResizeComponenets()
|
||||||
|
{
|
||||||
|
mBrowseButton.Resize(mWidth - 30, 2, Images.sBrowse.mWidth, Images.sBrowse.mHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Resize(float x, float y, float width, float height)
|
||||||
|
{
|
||||||
|
base.Resize(x, y, width, height);
|
||||||
|
ResizeComponenets();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
ResizeComponenets();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(Graphics g)
|
||||||
|
{
|
||||||
|
base.Draw(g);
|
||||||
|
|
||||||
|
g.DrawButton(Images.sTextBox, 0, 0, mWidth);
|
||||||
|
using (g.PushColor(0xFF000000))
|
||||||
|
{
|
||||||
|
g.SetFont(gApp.mBodyFont);
|
||||||
|
g.DrawString("Installation path", 0, -32);
|
||||||
|
g.SetFont(gApp.mBoxFont);
|
||||||
|
g.DrawString(mInstallPath, 4, 0, .Left, mWidth - 36, .Ellipsis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Board : Widget
|
||||||
|
{
|
||||||
|
const float cBodyX = 0;
|
||||||
|
const float cBodyY = 20;
|
||||||
|
|
||||||
|
LabelWidget mHeaderLabel;
|
||||||
|
BiButtonWidget mCloseButton;
|
||||||
|
BiDialogButton mCancelButton;
|
||||||
|
BiDialogButton mInstallButton;
|
||||||
|
BiCheckbox mInstallForAllCheckbox;
|
||||||
|
BiCheckbox mAddToStartCheckbox;
|
||||||
|
BiCheckbox mAddToDesktopCheckbox;
|
||||||
|
BiCheckbox mStartAfterCheckbox;
|
||||||
|
BiInstallPathBox mInstallPathBox;
|
||||||
|
|
||||||
|
float mScale = 0.35f;
|
||||||
|
float mScaleVel = 0.2f;
|
||||||
|
|
||||||
|
float mSurprisePct = 1.0f;
|
||||||
|
float mHeadRaise = 1.0f;
|
||||||
|
float mEatPct;
|
||||||
|
|
||||||
|
int mCloseTicks;
|
||||||
|
public bool mIsClosed;
|
||||||
|
|
||||||
|
public bool mInstalling;
|
||||||
|
public float mInstallPct = 0.5f;
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
mHeaderLabel = new LabelWidget();
|
||||||
|
mHeaderLabel.mLabel = new String("Beef Development Tools");
|
||||||
|
mHeaderLabel.mAlign = .Centered;
|
||||||
|
mHeaderLabel.mColor = 0xFF000000;
|
||||||
|
mHeaderLabel.mFont = gApp.mHeaderFont;
|
||||||
|
mHeaderLabel.mMouseVisible = false;
|
||||||
|
AddWidget(mHeaderLabel);
|
||||||
|
|
||||||
|
mCloseButton = new BiButtonWidget();
|
||||||
|
mCloseButton.mImage = Images.sClose;
|
||||||
|
mCloseButton.mImageHi = Images.sCloseHi;
|
||||||
|
mCloseButton.mOnMouseClick.Add(new (mouseArgs) =>
|
||||||
|
{
|
||||||
|
gApp.mCancelling = true;
|
||||||
|
});
|
||||||
|
mCloseButton.mMouseInsets = new Insets(4, 4, 4, 4);
|
||||||
|
AddWidget(mCloseButton);
|
||||||
|
|
||||||
|
mInstallForAllCheckbox = new BiCheckbox();
|
||||||
|
mInstallForAllCheckbox.mState = .Checked;
|
||||||
|
mInstallForAllCheckbox.mLabel = new String("Install for all users");
|
||||||
|
AddWidget(mInstallForAllCheckbox);
|
||||||
|
|
||||||
|
mAddToStartCheckbox = new BiCheckbox();
|
||||||
|
mAddToStartCheckbox.mState = .Checked;
|
||||||
|
mAddToStartCheckbox.mLabel = new String("Add to Start menu");
|
||||||
|
AddWidget(mAddToStartCheckbox);
|
||||||
|
|
||||||
|
mAddToDesktopCheckbox = new BiCheckbox();
|
||||||
|
mAddToDesktopCheckbox.mState = .Checked;
|
||||||
|
mAddToDesktopCheckbox.mLabel = new String("Add to desktop");
|
||||||
|
AddWidget(mAddToDesktopCheckbox);
|
||||||
|
|
||||||
|
mStartAfterCheckbox = new BiCheckbox();
|
||||||
|
mStartAfterCheckbox.mState = .Checked;
|
||||||
|
mStartAfterCheckbox.mLabel = new String("Run after install");
|
||||||
|
AddWidget(mStartAfterCheckbox);
|
||||||
|
|
||||||
|
mInstallPathBox = new BiInstallPathBox();
|
||||||
|
AddWidget(mInstallPathBox);
|
||||||
|
|
||||||
|
mCancelButton = new BiDialogButton();
|
||||||
|
mCancelButton.mLabel = new .("Cancel");
|
||||||
|
mCancelButton.mImage = Images.sButton;
|
||||||
|
mCancelButton.mImageHi = Images.sButtonHi;
|
||||||
|
mCancelButton.mOnMouseClick.Add(new (mouseArgs) =>
|
||||||
|
{
|
||||||
|
gApp.mCancelling = true;
|
||||||
|
});
|
||||||
|
mCancelButton.mMouseInsets = new Insets(4, 4, 4, 4);
|
||||||
|
AddWidget(mCancelButton);
|
||||||
|
|
||||||
|
mInstallButton = new BiDialogButton();
|
||||||
|
mInstallButton.mLabel = new .("Install");
|
||||||
|
mInstallButton.mImage = Images.sButton;
|
||||||
|
mInstallButton.mImageHi = Images.sButtonHi;
|
||||||
|
mInstallButton.mOnMouseClick.Add(new (mouseArgs) =>
|
||||||
|
{
|
||||||
|
StartInstall();
|
||||||
|
});
|
||||||
|
mInstallButton.mMouseInsets = new Insets(4, 4, 4, 4);
|
||||||
|
AddWidget(mInstallButton);
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
int pidl = 0;
|
||||||
|
Windows.SHGetSpecialFolderLocation(gApp.mMainWindow.HWND, Windows.CSIDL_PROGRAM_FILES, ref pidl);
|
||||||
|
if (pidl != 0)
|
||||||
|
{
|
||||||
|
char8* selectedPathCStr = scope char8[Windows.MAX_PATH]*;
|
||||||
|
Windows.SHGetPathFromIDList(pidl, selectedPathCStr);
|
||||||
|
mInstallPathBox.mInstallPath.Set(StringView(selectedPathCStr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mInstallPathBox.mInstallPath.Set(@"C:\Program Files");
|
||||||
|
}
|
||||||
|
mInstallPathBox.mInstallPath.Append(@"\BeefLang");
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartInstall()
|
||||||
|
{
|
||||||
|
mInstalling = true;
|
||||||
|
mInstallButton.mDisabled = true;
|
||||||
|
mInstallButton.mMouseVisible = false;
|
||||||
|
mInstallPathBox.mVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(Graphics g)
|
||||||
|
{
|
||||||
|
float bodyX = cBodyX;
|
||||||
|
float bodyY = cBodyY;
|
||||||
|
|
||||||
|
g.Draw(Images.sBody, bodyX, bodyY);
|
||||||
|
|
||||||
|
float headRaise = mHeadRaise;
|
||||||
|
headRaise += Math.Sin(Math.Clamp((mEatPct - 0.2f) * 1.4f, 0, 1.0f) * Math.PI_f*6) * 0.02f;
|
||||||
|
|
||||||
|
float headX = bodyX + 664 - headRaise * 6;
|
||||||
|
float headY = bodyY + 192 - headRaise * 30;
|
||||||
|
|
||||||
|
headY += Math.Clamp(Math.Sin(Math.PI_f * mEatPct) * 3.0f, 0, 1) * 8.0f;
|
||||||
|
|
||||||
|
Images.sHead.mPixelSnapping = .Never;
|
||||||
|
Images.sEyesOpen.mPixelSnapping = .Never;
|
||||||
|
Images.sEyesClosed.mPixelSnapping = .Never;
|
||||||
|
g.Draw(Images.sHead, headX, headY);
|
||||||
|
g.Draw((mSurprisePct > 0) ? Images.sEyesOpen : Images.sEyesClosed, headX + 70, headY + 190);
|
||||||
|
|
||||||
|
if (mInstalling)
|
||||||
|
{
|
||||||
|
float installDiv = 1000.0f;
|
||||||
|
//mInstallPct = (mUpdateCnt % installDiv) / installDiv;
|
||||||
|
|
||||||
|
//mInstallPct = 1.0f;
|
||||||
|
|
||||||
|
float totalWidth = 410;
|
||||||
|
float fillWidth = totalWidth * (mInstallPct*0.9f + 0.1f);
|
||||||
|
|
||||||
|
float barX = 200;
|
||||||
|
float barY = 280;
|
||||||
|
|
||||||
|
float barHeight = Images.sPBBarBottom.mHeight;
|
||||||
|
using (g.PushClip(barX, barY, totalWidth, barHeight))
|
||||||
|
{
|
||||||
|
g.DrawButton(Images.sPBBarBottom, barX, barY, totalWidth);
|
||||||
|
|
||||||
|
Color colorLeft = 0x800288E9;
|
||||||
|
Color colorRight = 0x80FFFFFF;
|
||||||
|
g.FillRectGradient(barX, barY, fillWidth, barHeight, colorLeft, colorRight, colorLeft, colorRight);
|
||||||
|
|
||||||
|
float pct = (mUpdateCnt % 60) / 60.0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
Images.sPBBarHilite.mPixelSnapping = .Never;
|
||||||
|
using (g.PushColor(0x22FFFFFF))
|
||||||
|
g.Draw(Images.sPBBarHilite, barX - 16 - totalWidth + fillWidth + (i + pct) * 26, barY + 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
g.DrawButton(Images.sPBBarEmpty, barX + fillWidth - 30, barY + 5, totalWidth - fillWidth + 40);
|
||||||
|
|
||||||
|
g.DrawButton(Images.sPBFrameTop, barX, barY, totalWidth);
|
||||||
|
|
||||||
|
g.DrawButton(Images.sPBFrameGlow, barX, barY, fillWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*g.SetFont(gApp.mHdrFont);
|
||||||
|
using (g.PushColor(0xFF000000))
|
||||||
|
g.DrawString("Beef Development Tools", 400, 20, .Centered);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void MouseMove(float x, float y)
|
||||||
|
{
|
||||||
|
if (Rect(60, 24, 700, 420).Contains(x, y))
|
||||||
|
{
|
||||||
|
gApp.SetCursor(.SizeNESW);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gApp.SetCursor(.Pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
base.MouseMove(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DrawAll(Graphics g)
|
||||||
|
{
|
||||||
|
int cBodyX = 0;
|
||||||
|
int cBodyY = 0;
|
||||||
|
|
||||||
|
/*using (g.PushColor(0x80FF0000))
|
||||||
|
g.FillRect(0, 0, mWidth, mHeight);*/
|
||||||
|
|
||||||
|
//float scaleX = (Math.Cos(mUpdateCnt * 0.1f) + 1.0f) * 0.5f;
|
||||||
|
//float scaleY = scaleX;
|
||||||
|
float scaleX = mScale;
|
||||||
|
float scaleY = mScale;
|
||||||
|
|
||||||
|
if ((Math.Abs(scaleX - 1.0f) < 0.001) && (Math.Abs(scaleY - 1.0f) < 0.001))
|
||||||
|
base.DrawAll(g);
|
||||||
|
else using (g.PushScale(scaleX, scaleY, cBodyX + 400, cBodyY + 560))
|
||||||
|
base.DrawAll(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
ResizeComponents();
|
||||||
|
|
||||||
|
if (gApp.mClosing)
|
||||||
|
{
|
||||||
|
if (mCloseTicks == 0)
|
||||||
|
{
|
||||||
|
gApp.mSoundManager.PlaySound(Sounds.sAbort);
|
||||||
|
mScaleVel = 0.055f;
|
||||||
|
}
|
||||||
|
mCloseTicks++;
|
||||||
|
|
||||||
|
mScaleVel *= 0.90f;
|
||||||
|
mScaleVel -= 0.01f;
|
||||||
|
mScale += mScaleVel;
|
||||||
|
mSurprisePct = 1.0f;
|
||||||
|
mHeadRaise = Math.Clamp(mHeadRaise + 0.2f, 0, 1.0f);
|
||||||
|
|
||||||
|
if (mScale <= 0)
|
||||||
|
{
|
||||||
|
mScale = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCloseTicks == 60)
|
||||||
|
mIsClosed = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mUpdateCnt == 1)
|
||||||
|
gApp.mSoundManager.PlaySound(Sounds.sBoing);
|
||||||
|
|
||||||
|
float sizeTarget = Math.Min(0.5f + mUpdateCnt * 0.05f, 1.0f);
|
||||||
|
|
||||||
|
float scaleDiff = sizeTarget - mScale;
|
||||||
|
mScaleVel += scaleDiff * 0.05f;
|
||||||
|
mScaleVel *= 0.80f;
|
||||||
|
mScale += mScaleVel;
|
||||||
|
|
||||||
|
mSurprisePct = Math.Max(mSurprisePct - 0.005f, 0);
|
||||||
|
if (mUpdateCnt > 240)
|
||||||
|
{
|
||||||
|
mHeadRaise = Math.Max(mHeadRaise * 0.95f - 0.01f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mEatPct == 0.0f)
|
||||||
|
{
|
||||||
|
if ((mUpdateCnt == 600) || (mUpdateCnt % 2400 == 0))
|
||||||
|
{
|
||||||
|
mEatPct = 0.0001f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
let prev = mEatPct;
|
||||||
|
mEatPct += 0.004f;
|
||||||
|
if ((prev < 0.2f) && (mEatPct >= 0.2f))
|
||||||
|
gApp.mSoundManager.PlaySound(Sounds.sEating);
|
||||||
|
|
||||||
|
if (mEatPct >= 1.0f)
|
||||||
|
{
|
||||||
|
//Debug.WriteLine("Eat done");
|
||||||
|
mEatPct = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mUpdateCnt % 2200 == 0)
|
||||||
|
{
|
||||||
|
mSurprisePct = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateAll()
|
||||||
|
{
|
||||||
|
base.UpdateAll();
|
||||||
|
|
||||||
|
if (mWidgetWindow.IsKeyDown(.Control))
|
||||||
|
{
|
||||||
|
for (int i < 2)
|
||||||
|
base.UpdateAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void MouseDown(float x, float y, int32 btn, int32 btnCount)
|
||||||
|
{
|
||||||
|
base.MouseDown(x, y, btn, btnCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void KeyDown(KeyCode keyCode, bool isRepeat)
|
||||||
|
{
|
||||||
|
base.KeyDown(keyCode, isRepeat);
|
||||||
|
|
||||||
|
if (keyCode == .Space)
|
||||||
|
{
|
||||||
|
gApp.mWantRehup = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateComponent(Widget widget, int updateOffset, float centerX = 0.5f, float centerY = 0.5f, float speedMult = 1.0f)
|
||||||
|
{
|
||||||
|
float pct = Math.Clamp((mUpdateCnt - 50 - updateOffset) * 0.25f * speedMult, 0, 1.0f);
|
||||||
|
//float pct = Math.Clamp((mUpdateCnt - 50 - updateOffset) * 0.02f, 0, 1.0f);
|
||||||
|
if (pct == 0)
|
||||||
|
{
|
||||||
|
widget.SetVisible(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
widget.SetVisible(true);
|
||||||
|
if (pct == 1)
|
||||||
|
{
|
||||||
|
widget.ClearTransform();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix matrix = .IdentityMatrix;
|
||||||
|
matrix.Translate(-widget.mWidth * centerX, -widget.mHeight * centerY);
|
||||||
|
matrix.Scale(pct, pct);
|
||||||
|
matrix.Translate(widget.mWidth * centerX, widget.mHeight * centerY);
|
||||||
|
matrix.Translate(widget.mX, widget.mY);
|
||||||
|
widget.Transform = matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResizeComponents()
|
||||||
|
{
|
||||||
|
float headerWidth = mHeaderLabel.CalcWidth();
|
||||||
|
mHeaderLabel.Resize(cBodyX + 375 - headerWidth/2, cBodyY + 60, headerWidth, 60);
|
||||||
|
UpdateComponent(mHeaderLabel, 0, 0.5f, 2.0f, 0.4f);
|
||||||
|
|
||||||
|
mCloseButton.Resize(cBodyX + 660, cBodyY + 55, mCloseButton.mImage.mWidth, mCloseButton.mImage.mHeight);
|
||||||
|
UpdateComponent(mCloseButton, 5);
|
||||||
|
|
||||||
|
mInstallForAllCheckbox.Resize(cBodyX + 120, cBodyY + 136, 48, 48);
|
||||||
|
UpdateComponent(mInstallForAllCheckbox, 10);
|
||||||
|
|
||||||
|
mAddToStartCheckbox.Resize(cBodyX + 418, cBodyY + 136, 48, 48);
|
||||||
|
UpdateComponent(mAddToStartCheckbox, 12);
|
||||||
|
|
||||||
|
mAddToDesktopCheckbox.Resize(cBodyX + 120, cBodyY + 190, 48, 48);
|
||||||
|
UpdateComponent(mAddToDesktopCheckbox, 14);
|
||||||
|
|
||||||
|
mStartAfterCheckbox.Resize(cBodyX + 418, cBodyY + 190, 48, 48);
|
||||||
|
UpdateComponent(mStartAfterCheckbox, 16);
|
||||||
|
|
||||||
|
if (!mInstalling)
|
||||||
|
{
|
||||||
|
mInstallPathBox.Resize(cBodyX + 122, cBodyY + 276, 508, Images.sTextBox.mHeight);
|
||||||
|
UpdateComponent(mInstallPathBox, 5, 0.1f, 0.5f, 0.4f);
|
||||||
|
}
|
||||||
|
|
||||||
|
mCancelButton.Resize(cBodyX + 180, cBodyY + 320, mCancelButton.mImage.mWidth, mCancelButton.mImage.mHeight);
|
||||||
|
UpdateComponent(mCancelButton, 13, 0.5f, 0.2f);
|
||||||
|
|
||||||
|
mInstallButton.Resize(cBodyX + 404, cBodyY + 320, mInstallButton.mImage.mWidth, mInstallButton.mImage.mHeight);
|
||||||
|
UpdateComponent(mInstallButton, 15, 0.5f, 0.2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Resize(float x, float y, float width, float height)
|
||||||
|
{
|
||||||
|
base.Resize(x, y, width, height);
|
||||||
|
ResizeComponents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,14 +15,17 @@ namespace BIStubUI
|
||||||
Debug.WriteLine("Deinitializing StubUI");
|
Debug.WriteLine("Deinitializing StubUI");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Export]
|
[Export, CLink]
|
||||||
public static void Start(BIApp.InstallFunc installFunc, BIApp.ProgressFunc progressFunc, BIApp.CancelFunc cancelFunc)
|
public static void Start(BIApp.InstallFunc installFunc, BIApp.ProgressFunc progressFunc, BIApp.CancelFunc cancelFunc)
|
||||||
{
|
{
|
||||||
gApp = new BIApp();
|
gApp = new BIApp();
|
||||||
gApp.mInstallFunc = installFunc;
|
gApp.mInstallFunc = installFunc;
|
||||||
gApp.mProgressFunc = progressFunc;
|
gApp.mProgressFunc = progressFunc;
|
||||||
gApp.mCancelFunc = cancelFunc;
|
gApp.mCancelFunc = cancelFunc;
|
||||||
|
gApp.Init();
|
||||||
gApp.Run();
|
gApp.Run();
|
||||||
|
gApp.Shutdown();
|
||||||
|
DeleteAndNullify!(gApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Hello()
|
public static void Hello()
|
||||||
|
|
102
BeefTools/BeefInstall/StubUI/src/Resources.bf
Normal file
102
BeefTools/BeefInstall/StubUI/src/Resources.bf
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
using System;
|
||||||
|
using Beefy.gfx;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Beefy.sound;
|
||||||
|
|
||||||
|
namespace BIStubUI
|
||||||
|
{
|
||||||
|
class Images
|
||||||
|
{
|
||||||
|
public static Image sBody;
|
||||||
|
public static Image sHead;
|
||||||
|
public static Image sEyesOpen;
|
||||||
|
public static Image sEyesClosed;
|
||||||
|
public static Image sButton;
|
||||||
|
public static Image sButtonHi;
|
||||||
|
public static Image sSmButton;
|
||||||
|
public static Image sClose;
|
||||||
|
public static Image sCloseHi;
|
||||||
|
public static Image sChecked;
|
||||||
|
public static Image sUnchecked;
|
||||||
|
public static Image sTextBox;
|
||||||
|
public static Image sBrowse;
|
||||||
|
public static Image sBrowseDown;
|
||||||
|
public static Image sPBBarBottom;
|
||||||
|
public static Image sPBBarEmpty;
|
||||||
|
public static Image sPBBarHilite;
|
||||||
|
public static Image sPBFrameGlow;
|
||||||
|
public static Image sPBFrameTop;
|
||||||
|
|
||||||
|
static List<Image> sImages = new .() ~ delete _;
|
||||||
|
|
||||||
|
public static Result<Image> Load(String fileName, bool additive = false)
|
||||||
|
{
|
||||||
|
let image = Image.LoadFromFile(scope String(gApp.mInstallDir, "/", fileName), additive);
|
||||||
|
if (image == null)
|
||||||
|
{
|
||||||
|
delete image;
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
sImages.Add(image);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Dispose()
|
||||||
|
{
|
||||||
|
ClearAndDeleteItems(sImages);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result<void> Init()
|
||||||
|
{
|
||||||
|
sBody = Try!(Load("images/body.png"));
|
||||||
|
sHead = Try!(Load("images/head.png"));
|
||||||
|
sEyesOpen = Try!(Load("images/eyesopen.png"));
|
||||||
|
sEyesClosed = Try!(Load("images/eyesclosed.png"));
|
||||||
|
sButton = Try!(Load("images/button.png"));
|
||||||
|
sButtonHi = Try!(Load("images/button_hi.png"));
|
||||||
|
sSmButton = Try!(Load("images/smbutton.png"));
|
||||||
|
sClose = Try!(Load("images/close.png"));
|
||||||
|
sCloseHi = Try!(Load("images/close_hi.png"));
|
||||||
|
sChecked = Try!(Load("images/checked.png"));
|
||||||
|
sUnchecked = Try!(Load("images/unchecked.png"));
|
||||||
|
sTextBox = Try!(Load("images/textbox.png"));
|
||||||
|
sBrowse = Try!(Load("images/browse.png"));
|
||||||
|
sBrowseDown = Try!(Load("images/browsedown.png"));
|
||||||
|
sPBBarBottom = Try!(Load("images/pb_barbottom.png"));
|
||||||
|
sPBBarEmpty = Try!(Load("images/pb_barempty.png"));
|
||||||
|
sPBBarHilite = Try!(Load("images/pb_barhilite.png", true));
|
||||||
|
sPBFrameGlow = Try!(Load("images/pb_frameglow.png"));
|
||||||
|
sPBFrameTop = Try!(Load("images/pb_frametop.png"));
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Sounds
|
||||||
|
{
|
||||||
|
public static SoundSource sBoing;
|
||||||
|
public static SoundSource sEating;
|
||||||
|
public static SoundSource sButtonPress;
|
||||||
|
public static SoundSource sMouseOver;
|
||||||
|
public static SoundSource sAbort;
|
||||||
|
public static SoundSource sChecked;
|
||||||
|
|
||||||
|
public static Result<SoundSource> Load(String fileName)
|
||||||
|
{
|
||||||
|
let source = gApp.mSoundManager.LoadSound(scope String(gApp.mInstallDir, "/", fileName));
|
||||||
|
if (source.IsInvalid)
|
||||||
|
return .Err;
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result<void> Init()
|
||||||
|
{
|
||||||
|
sBoing = Try!(Load("sounds/boing.wav"));
|
||||||
|
sEating = Try!(Load("sounds/eating.wav"));
|
||||||
|
sButtonPress = Try!(Load("sounds/buttonpress.wav"));
|
||||||
|
sMouseOver = Try!(Load("sounds/mouseover.wav"));
|
||||||
|
sAbort = Try!(Load("sounds/abort.wav"));
|
||||||
|
sChecked = Try!(Load("sounds/checked.wav"));
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ BFApp::BFApp()
|
||||||
mCursor = CURSOR_POINTER;
|
mCursor = CURSOR_POINTER;
|
||||||
mInProcess = false;
|
mInProcess = false;
|
||||||
mUpdateCnt = 0;
|
mUpdateCnt = 0;
|
||||||
|
mNumPhysUpdates = 0;
|
||||||
mVSynched = true;
|
mVSynched = true;
|
||||||
mMaxUpdatesPerDraw = 60; // 8?
|
mMaxUpdatesPerDraw = 60; // 8?
|
||||||
|
|
||||||
|
@ -170,7 +171,10 @@ void BFApp::Process()
|
||||||
mFrameTimeAcc = 0;
|
mFrameTimeAcc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
updates = std::min(updates, mMaxUpdatesPerDraw);
|
// Compensate for "slow start" by limiting the number of catchup-updates we can do when starting the app
|
||||||
|
int maxUpdates = BF_MIN(mNumPhysUpdates + 1, mMaxUpdatesPerDraw);
|
||||||
|
|
||||||
|
updates = BF_MIN(updates, maxUpdates);
|
||||||
|
|
||||||
/*if (updates > 2)
|
/*if (updates > 2)
|
||||||
OutputDebugStrF("Updates: %d TickDelta: %d\n", updates, tickNow - mLastProcessTick);*/
|
OutputDebugStrF("Updates: %d TickDelta: %d\n", updates, tickNow - mLastProcessTick);*/
|
||||||
|
@ -198,8 +202,15 @@ void BFApp::Process()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (updates > 0)
|
||||||
|
mNumPhysUpdates++;
|
||||||
|
|
||||||
for (int updateNum = 0; updateNum < updates; updateNum++)
|
for (int updateNum = 0; updateNum < updates; updateNum++)
|
||||||
|
{
|
||||||
|
if (!mRunning)
|
||||||
|
break;
|
||||||
Update(updateNum == 0);
|
Update(updateNum == 0);
|
||||||
|
}
|
||||||
|
|
||||||
if ((mRunning) && (updates > 0))
|
if ((mRunning) && (updates > 0))
|
||||||
Draw();
|
Draw();
|
||||||
|
|
|
@ -9,6 +9,7 @@ typedef void (*BFApp_UpdateFunc)(bool batchStart);
|
||||||
typedef void (*BFApp_DrawFunc)();
|
typedef void (*BFApp_DrawFunc)();
|
||||||
|
|
||||||
class BFApp;
|
class BFApp;
|
||||||
|
class BFSoundManager;
|
||||||
class RenderDevice;
|
class RenderDevice;
|
||||||
class BFWindow;
|
class BFWindow;
|
||||||
class FileStream;
|
class FileStream;
|
||||||
|
@ -54,6 +55,7 @@ public:
|
||||||
RenderDevice* mRenderDevice;
|
RenderDevice* mRenderDevice;
|
||||||
int mSysDialogCnt;
|
int mSysDialogCnt;
|
||||||
int mUpdateCnt;
|
int mUpdateCnt;
|
||||||
|
int mNumPhysUpdates;
|
||||||
bool mVSynched;
|
bool mVSynched;
|
||||||
bool mVSyncFailed;
|
bool mVSyncFailed;
|
||||||
|
|
||||||
|
@ -99,6 +101,8 @@ public:
|
||||||
virtual BFSysBitmap* LoadSysBitmap(const wchar_t* fileName) = 0;
|
virtual BFSysBitmap* LoadSysBitmap(const wchar_t* fileName) = 0;
|
||||||
|
|
||||||
virtual FileStream* OpenBinaryFile(const StringImpl& fileName);
|
virtual FileStream* OpenBinaryFile(const StringImpl& fileName);
|
||||||
|
|
||||||
|
virtual BFSoundManager* GetSoundManager() { return NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
extern BFApp* gBFApp;
|
extern BFApp* gBFApp;
|
||||||
|
|
72
BeefySysLib/BFSound.cpp
Normal file
72
BeefySysLib/BFSound.cpp
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
#include "BFSound.h"
|
||||||
|
|
||||||
|
using namespace Beefy;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
BF_EXPORT int32 BF_CALLTYPE BFSoundManager_LoadSound(BFSoundManager* manager, const char* fileName)
|
||||||
|
{
|
||||||
|
return manager->LoadSound(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT BFSoundInstance* BF_CALLTYPE BFSoundManager_GetSoundInstance(BFSoundManager* manager, int32 sfxId)
|
||||||
|
{
|
||||||
|
return manager->GetSoundInstance(sfxId);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
BF_EXPORT void BF_CALLTYPE BFSoundInstance_Release(BFSoundInstance* instance)
|
||||||
|
{
|
||||||
|
instance->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT void BF_CALLTYPE BFSoundInstance_SetBaseVolume(BFSoundInstance* instance, float theBaseVolume)
|
||||||
|
{
|
||||||
|
instance->SetBaseVolume(theBaseVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT void BF_CALLTYPE BFSoundInstance_SetBasePan(BFSoundInstance* instance, int theBasePan)
|
||||||
|
{
|
||||||
|
instance->SetBasePan(theBasePan);
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT void BF_CALLTYPE BFSoundInstance_SetVolume(BFSoundInstance* instance, float theVolume)
|
||||||
|
{
|
||||||
|
instance->SetVolume(theVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT void BF_CALLTYPE BFSoundInstance_SetPan(BFSoundInstance* instance, int thePosition)
|
||||||
|
{
|
||||||
|
instance->SetPan(thePosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT void BF_CALLTYPE BFSoundInstance_AdjustPitch(BFSoundInstance* instance, float theNumSteps)
|
||||||
|
{
|
||||||
|
instance->AdjustPitch(theNumSteps);
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT bool BF_CALLTYPE BFSoundInstance_Play(BFSoundInstance* instance, bool looping, bool autoRelease)
|
||||||
|
{
|
||||||
|
return instance->Play(looping, autoRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT void BF_CALLTYPE BFSoundInstance_Stop(BFSoundInstance* instance)
|
||||||
|
{
|
||||||
|
instance->Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT bool BF_CALLTYPE BFSoundInstance_IsPlaying(BFSoundInstance* instance)
|
||||||
|
{
|
||||||
|
return instance->IsPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT bool BF_CALLTYPE BFSoundInstance_IsReleased(BFSoundInstance* instance)
|
||||||
|
{
|
||||||
|
return instance->IsReleased();
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT float BF_CALLTYPE BFSoundInstance_GetVolume(BFSoundInstance* instance)
|
||||||
|
{
|
||||||
|
return (float)instance->GetVolume();
|
||||||
|
}
|
61
BeefySysLib/BFSound.h
Normal file
61
BeefySysLib/BFSound.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
NS_BF_BEGIN;
|
||||||
|
|
||||||
|
#define MAX_SOURCE_SOUNDS 1024
|
||||||
|
#define MAX_CHANNELS 32
|
||||||
|
|
||||||
|
class BFSoundInstance
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~BFSoundInstance() {}
|
||||||
|
|
||||||
|
virtual void Release() = 0;
|
||||||
|
|
||||||
|
virtual void SetBaseVolume(float theBaseVolume) = 0;
|
||||||
|
virtual void SetBasePan(int theBasePan) = 0;
|
||||||
|
|
||||||
|
virtual void SetVolume(float theVolume) = 0;
|
||||||
|
virtual void SetPan(int thePosition) = 0; //-hundredth db to +hundredth db = left to right
|
||||||
|
virtual void AdjustPitch(float theNumSteps) = 0;
|
||||||
|
|
||||||
|
virtual bool Play(bool looping, bool autoRelease) = 0;
|
||||||
|
virtual void Stop() = 0;
|
||||||
|
virtual bool IsPlaying() = 0;
|
||||||
|
virtual bool IsReleased() = 0;
|
||||||
|
virtual float GetVolume() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BFSoundManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~BFSoundManager() {}
|
||||||
|
|
||||||
|
virtual bool Initialized() = 0;
|
||||||
|
|
||||||
|
virtual bool LoadSound(unsigned int theSfxID, const StringImpl& theFilename) = 0;
|
||||||
|
virtual int LoadSound(const StringImpl& theFilename) = 0;
|
||||||
|
virtual void ReleaseSound(unsigned int theSfxID) = 0;
|
||||||
|
|
||||||
|
virtual void SetVolume(float theVolume) = 0;
|
||||||
|
virtual bool SetBaseVolume(unsigned int theSfxID, float theBaseVolume) = 0;
|
||||||
|
virtual bool SetBasePan(unsigned int theSfxID, int theBasePan) = 0;
|
||||||
|
|
||||||
|
virtual BFSoundInstance* GetSoundInstance(unsigned int theSfxID) = 0;
|
||||||
|
|
||||||
|
virtual void ReleaseSounds() = 0;
|
||||||
|
virtual void ReleaseChannels() = 0;
|
||||||
|
|
||||||
|
virtual float GetMasterVolume() = 0;
|
||||||
|
virtual void SetMasterVolume(float theVolume) = 0;
|
||||||
|
|
||||||
|
virtual void Flush() = 0;
|
||||||
|
|
||||||
|
virtual void StopAllSounds() = 0;
|
||||||
|
virtual int GetFreeSoundId() = 0;
|
||||||
|
virtual int GetNumSounds() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_BF_END;
|
|
@ -255,6 +255,11 @@ BF_EXPORT void BF_CALLTYPE BFApp_RehupMouse()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_EXPORT BFSoundManager* BF_CALLTYPE BFApp_GetSoundManager()
|
||||||
|
{
|
||||||
|
return gBFApp->GetSoundManager();
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
BF_EXPORT void BF_CALLTYPE BFWindow_SetCallbacks(BFWindow* window, BFWindow_MovedFunc movedFunc, BFWindow_CloseQueryFunc closeQueryFunc, BFWindow_ClosedFunc closedFunc,
|
BF_EXPORT void BF_CALLTYPE BFWindow_SetCallbacks(BFWindow* window, BFWindow_MovedFunc movedFunc, BFWindow_CloseQueryFunc closeQueryFunc, BFWindow_ClosedFunc closedFunc,
|
||||||
|
|
|
@ -433,6 +433,7 @@ copy /y $(OutDir)$(TargetName).lib $(SolutionDir)\BeefLibs\Beefy2D\dist\</Comman
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="BFApp.cpp" />
|
<ClCompile Include="BFApp.cpp" />
|
||||||
<ClCompile Include="BeefySysLib.cpp" />
|
<ClCompile Include="BeefySysLib.cpp" />
|
||||||
|
<ClCompile Include="BFSound.cpp" />
|
||||||
<ClCompile Include="BFWindow.cpp" />
|
<ClCompile Include="BFWindow.cpp" />
|
||||||
<ClCompile Include="CachedDataStream.cpp" />
|
<ClCompile Include="CachedDataStream.cpp" />
|
||||||
<ClCompile Include="Common.cpp" />
|
<ClCompile Include="Common.cpp" />
|
||||||
|
@ -485,6 +486,8 @@ copy /y $(OutDir)$(TargetName).lib $(SolutionDir)\BeefLibs\Beefy2D\dist\</Comman
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="platform\win\CrashCatcher.cpp" />
|
<ClCompile Include="platform\win\CrashCatcher.cpp" />
|
||||||
|
<ClCompile Include="platform\win\DSoundInstance.cpp" />
|
||||||
|
<ClCompile Include="platform\win\DSoundManager.cpp" />
|
||||||
<ClCompile Include="platform\win\WinBFApp.cpp">
|
<ClCompile Include="platform\win\WinBFApp.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -1940,6 +1943,7 @@ copy /y $(OutDir)$(TargetName).lib $(SolutionDir)\BeefLibs\Beefy2D\dist\</Comman
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="BFApp.h" />
|
<ClInclude Include="BFApp.h" />
|
||||||
|
<ClInclude Include="BFSound.h" />
|
||||||
<ClInclude Include="BFWindow.h" />
|
<ClInclude Include="BFWindow.h" />
|
||||||
<ClInclude Include="CachedDataStream.h" />
|
<ClInclude Include="CachedDataStream.h" />
|
||||||
<ClInclude Include="Common.h" />
|
<ClInclude Include="Common.h" />
|
||||||
|
@ -1989,6 +1993,8 @@ copy /y $(OutDir)$(TargetName).lib $(SolutionDir)\BeefLibs\Beefy2D\dist\</Comman
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="platform\win\CrashCatcher.h" />
|
<ClInclude Include="platform\win\CrashCatcher.h" />
|
||||||
|
<ClInclude Include="platform\win\DSoundInstance.h" />
|
||||||
|
<ClInclude Include="platform\win\DSoundManager.h" />
|
||||||
<ClInclude Include="platform\win\PlatformApp.h" />
|
<ClInclude Include="platform\win\PlatformApp.h" />
|
||||||
<ClInclude Include="platform\win\WinBFApp.h">
|
<ClInclude Include="platform\win\WinBFApp.h">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||||
|
|
|
@ -688,6 +688,15 @@
|
||||||
<ClCompile Include="util\ThreadPool.cpp">
|
<ClCompile Include="util\ThreadPool.cpp">
|
||||||
<Filter>src\util</Filter>
|
<Filter>src\util</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="platform\win\DSoundInstance.cpp">
|
||||||
|
<Filter>src\platform\win</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="platform\win\DSoundManager.cpp">
|
||||||
|
<Filter>src\platform\win</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="BFSound.cpp">
|
||||||
|
<Filter>src\platform</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Common.h">
|
<ClInclude Include="Common.h">
|
||||||
|
@ -1038,6 +1047,15 @@
|
||||||
<ClInclude Include="util\MultiHashSet.h">
|
<ClInclude Include="util\MultiHashSet.h">
|
||||||
<Filter>src\util</Filter>
|
<Filter>src\util</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="platform\win\DSoundInstance.h">
|
||||||
|
<Filter>src\platform\win</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="platform\win\DSoundManager.h">
|
||||||
|
<Filter>src\platform\win</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="BFSound.h">
|
||||||
|
<Filter>src</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">
|
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">
|
||||||
|
|
|
@ -29,6 +29,7 @@ bool FileStream::Open(const StringImpl& filePath, const char* fopenOptions)
|
||||||
#else
|
#else
|
||||||
mFP = fopen(filePath.c_str(), fopenOptions);
|
mFP = fopen(filePath.c_str(), fopenOptions);
|
||||||
#endif
|
#endif
|
||||||
|
mReadPastEnd = false;
|
||||||
return mFP != NULL;
|
return mFP != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,10 +101,22 @@ VertexDefinition* Beefy::RenderDevice::CreateVertexDefinition(VertexDefData* ele
|
||||||
Texture* RenderDevice::LoadTexture(const StringImpl& fileName, int flags)
|
Texture* RenderDevice::LoadTexture(const StringImpl& fileName, int flags)
|
||||||
{
|
{
|
||||||
int dotPos = (int)fileName.LastIndexOf('.');
|
int dotPos = (int)fileName.LastIndexOf('.');
|
||||||
String ext = fileName.Substring(dotPos);
|
String ext;
|
||||||
|
if (dotPos != -1)
|
||||||
|
ext = fileName.Substring(dotPos);
|
||||||
|
|
||||||
ImageData* imageData = NULL;
|
ImageData* imageData = NULL;
|
||||||
if (ext == ".tga")
|
bool handled = false;
|
||||||
|
bool failed = false;
|
||||||
|
|
||||||
|
if (fileName == "!white")
|
||||||
|
{
|
||||||
|
imageData = new ImageData();
|
||||||
|
imageData->CreateNew(1, 1, true);
|
||||||
|
imageData->mBits[0] = 0xFFFFFFFF;
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
else if (ext == ".tga")
|
||||||
imageData = new TGAData();
|
imageData = new TGAData();
|
||||||
else if (ext == ".png")
|
else if (ext == ".png")
|
||||||
imageData = new PNGData();
|
imageData = new PNGData();
|
||||||
|
@ -118,21 +130,19 @@ Texture* RenderDevice::LoadTexture(const StringImpl& fileName, int flags)
|
||||||
return NULL; // Unknown format
|
return NULL; // Unknown format
|
||||||
}
|
}
|
||||||
|
|
||||||
imageData->mWantsAlphaPremultiplied = (flags & TextureFlag_NoPremult) == 0;
|
if (!handled)
|
||||||
|
{
|
||||||
|
imageData->mWantsAlphaPremultiplied = (flags & TextureFlag_NoPremult) == 0;
|
||||||
|
if (!imageData->LoadFromFile(fileName))
|
||||||
|
{
|
||||||
|
failed = true;
|
||||||
|
BF_FATAL("Failed to load image");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Texture* aTexture = NULL;
|
Texture* aTexture = NULL;
|
||||||
if (imageData->LoadFromFile(fileName))
|
if (!failed)
|
||||||
{
|
|
||||||
// if ((int)fileName.IndexOf("fft") != -1)
|
|
||||||
// {
|
|
||||||
// BFIData bFIData;
|
|
||||||
// bFIData.Compress(imageData);
|
|
||||||
// }
|
|
||||||
|
|
||||||
aTexture = LoadTexture(imageData, flags);
|
aTexture = LoadTexture(imageData, flags);
|
||||||
}
|
|
||||||
else
|
|
||||||
BF_FATAL("Failed to load image");
|
|
||||||
|
|
||||||
delete imageData;
|
delete imageData;
|
||||||
return aTexture;
|
return aTexture;
|
||||||
|
|
177
BeefySysLib/platform/win/DSoundInstance.cpp
Normal file
177
BeefySysLib/platform/win/DSoundInstance.cpp
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
#include "DSoundInstance.h"
|
||||||
|
#include "DSoundManager.h"
|
||||||
|
|
||||||
|
using namespace Beefy;
|
||||||
|
|
||||||
|
DSoundInstance::DSoundInstance(DSoundManager* theSoundManager, LPDIRECTSOUNDBUFFER theSourceSound)
|
||||||
|
{
|
||||||
|
mSoundManagerP = theSoundManager;
|
||||||
|
mReleased = false;
|
||||||
|
mAutoRelease = false;
|
||||||
|
mHasPlayed = false;
|
||||||
|
mSourceSoundBuffer = theSourceSound;
|
||||||
|
mSoundBuffer = NULL;
|
||||||
|
|
||||||
|
mBaseVolume = 1.0;
|
||||||
|
mBasePan = 0;
|
||||||
|
|
||||||
|
mVolume = 1.0;
|
||||||
|
mPan = 0;
|
||||||
|
|
||||||
|
mDefaultFrequency = 44100;
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (mSourceSoundBuffer != NULL)
|
||||||
|
{
|
||||||
|
hr=mSoundManagerP->mDirectSound->DuplicateSoundBuffer(mSourceSoundBuffer, &mSoundBuffer);
|
||||||
|
if (hr!=DS_OK)
|
||||||
|
{
|
||||||
|
switch (hr)
|
||||||
|
{
|
||||||
|
case DSERR_ALLOCATED: MessageBoxA(0,"DSERR_ALLOCATED","Hey",MB_OK);break;
|
||||||
|
case DSERR_INVALIDCALL: MessageBoxA(0,"DSERR_INVALIDCALL","Hey",MB_OK);break;
|
||||||
|
case DSERR_INVALIDPARAM: MessageBoxA(0,"DSERR_INVALIDPARAM","Hey",MB_OK);break;
|
||||||
|
case DSERR_OUTOFMEMORY: MessageBoxA(0,"DSERR_OUTOFMEMORY","Hey",MB_OK);break;
|
||||||
|
case DSERR_UNINITIALIZED: MessageBoxA(0,"DSERR_UNINITIALIZED","Hey",MB_OK);break;
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
mSoundBuffer->GetFrequency(&mDefaultFrequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
RehupVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
DSoundInstance::~DSoundInstance()
|
||||||
|
{
|
||||||
|
if (mSoundBuffer != NULL)
|
||||||
|
mSoundBuffer->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundInstance::RehupVolume()
|
||||||
|
{
|
||||||
|
if (mSoundBuffer != NULL)
|
||||||
|
mSoundBuffer->SetVolume(mSoundManagerP->VolumeToDB(mBaseVolume * mVolume * mSoundManagerP->mMasterVolume));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundInstance::RehupPan()
|
||||||
|
{
|
||||||
|
if (mSoundBuffer != NULL)
|
||||||
|
mSoundBuffer->SetPan(mBasePan + mPan);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundInstance::Release()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
mReleased = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundInstance::SetVolume(float theVolume) // 0 = max
|
||||||
|
{
|
||||||
|
mVolume = theVolume;
|
||||||
|
RehupVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundInstance::SetPan(int thePosition) //-db to =db = left to right
|
||||||
|
{
|
||||||
|
mPan = thePosition;
|
||||||
|
RehupPan();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundInstance::SetBaseVolume(float theBaseVolume)
|
||||||
|
{
|
||||||
|
mBaseVolume = theBaseVolume;
|
||||||
|
RehupVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundInstance::SetBasePan(int theBasePan)
|
||||||
|
{
|
||||||
|
mBasePan = theBasePan;
|
||||||
|
RehupPan();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DSoundInstance::Play(bool looping, bool autoRelease)
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
|
||||||
|
mHasPlayed = true;
|
||||||
|
mAutoRelease = autoRelease;
|
||||||
|
|
||||||
|
if (mSoundBuffer == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (looping)
|
||||||
|
{
|
||||||
|
if (mSoundBuffer->Play(0, 0, DSBPLAY_LOOPING) != DS_OK)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mSoundBuffer->Play(0, 0, 0) != DS_OK)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundInstance::Stop()
|
||||||
|
{
|
||||||
|
if (mSoundBuffer != NULL)
|
||||||
|
{
|
||||||
|
mSoundBuffer->Stop();
|
||||||
|
mSoundBuffer->SetCurrentPosition(0);
|
||||||
|
mAutoRelease = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#include "DirectXErrorString.h"
|
||||||
|
void DSoundInstance::AdjustPitch(float theNumSteps)
|
||||||
|
{
|
||||||
|
if (mSoundBuffer != NULL)
|
||||||
|
{
|
||||||
|
float aFrequencyMult = powf(1.0594630943592952645618252949463f, theNumSteps);
|
||||||
|
float aNewFrequency = mDefaultFrequency*aFrequencyMult;
|
||||||
|
if (aNewFrequency < DSBFREQUENCY_MIN)
|
||||||
|
aNewFrequency = DSBFREQUENCY_MIN;
|
||||||
|
if (aNewFrequency > DSBFREQUENCY_MAX)
|
||||||
|
aNewFrequency = DSBFREQUENCY_MAX;
|
||||||
|
|
||||||
|
mSoundBuffer->SetFrequency((DWORD)aNewFrequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DSoundInstance::IsPlaying()
|
||||||
|
{
|
||||||
|
if (!mHasPlayed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mSoundBuffer == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DWORD aStatus;
|
||||||
|
if (mSoundBuffer->GetStatus(&aStatus) == DS_OK)
|
||||||
|
// Has the sound stopped?
|
||||||
|
return ((aStatus & DSBSTATUS_PLAYING) != 0);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DSoundInstance::IsReleased()
|
||||||
|
{
|
||||||
|
if ((!mReleased) && (mAutoRelease) && (mHasPlayed) && (!IsPlaying()))
|
||||||
|
Release();
|
||||||
|
|
||||||
|
return mReleased;
|
||||||
|
}
|
||||||
|
|
||||||
|
float DSoundInstance::GetVolume()
|
||||||
|
{
|
||||||
|
return mVolume;
|
||||||
|
}
|
||||||
|
|
60
BeefySysLib/platform/win/DSoundInstance.h
Normal file
60
BeefySysLib/platform/win/DSoundInstance.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#ifndef __DSOUNDINSTANCE_H__
|
||||||
|
#define __DSOUNDINSTANCE_H__
|
||||||
|
|
||||||
|
#include <dsound.h>
|
||||||
|
#include "BFSound.h"
|
||||||
|
|
||||||
|
//#define _LPCWAVEFORMATEX_DEFINED
|
||||||
|
|
||||||
|
namespace Beefy
|
||||||
|
{
|
||||||
|
|
||||||
|
class DSoundManager;
|
||||||
|
|
||||||
|
class DSoundInstance : public BFSoundInstance
|
||||||
|
{
|
||||||
|
friend class DSoundManager;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DSoundManager* mSoundManagerP;
|
||||||
|
LPDIRECTSOUNDBUFFER mSourceSoundBuffer;
|
||||||
|
LPDIRECTSOUNDBUFFER mSoundBuffer;
|
||||||
|
bool mAutoRelease;
|
||||||
|
bool mHasPlayed;
|
||||||
|
bool mReleased;
|
||||||
|
|
||||||
|
int mBasePan;
|
||||||
|
float mBaseVolume;
|
||||||
|
|
||||||
|
int mPan;
|
||||||
|
float mVolume;
|
||||||
|
|
||||||
|
DWORD mDefaultFrequency;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void RehupVolume();
|
||||||
|
void RehupPan();
|
||||||
|
|
||||||
|
public:
|
||||||
|
DSoundInstance(DSoundManager* theSoundManager, LPDIRECTSOUNDBUFFER theSourceSound);
|
||||||
|
virtual ~DSoundInstance();
|
||||||
|
virtual void Release() override;
|
||||||
|
|
||||||
|
virtual void SetBaseVolume(float theBaseVolume) override;
|
||||||
|
virtual void SetBasePan(int theBasePan) override;
|
||||||
|
|
||||||
|
virtual void SetVolume(float theVolume) override;
|
||||||
|
virtual void SetPan(int thePosition) override; //-hundredth db to +hundredth db = left to right
|
||||||
|
virtual void AdjustPitch(float theNumSteps) override;
|
||||||
|
|
||||||
|
virtual bool Play(bool looping, bool autoRelease) override;
|
||||||
|
virtual void Stop() override;
|
||||||
|
virtual bool IsPlaying() override;
|
||||||
|
virtual bool IsReleased() override;
|
||||||
|
virtual float GetVolume() override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__DSOUNDINSTANCE_H__
|
535
BeefySysLib/platform/win/DSoundManager.cpp
Normal file
535
BeefySysLib/platform/win/DSoundManager.cpp
Normal file
|
@ -0,0 +1,535 @@
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
|
||||||
|
#include "DSoundManager.h"
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "DSoundInstance.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
using namespace Beefy;
|
||||||
|
|
||||||
|
static HMODULE gDSoundDLL;
|
||||||
|
|
||||||
|
#pragma comment(lib, "dsound.lib")
|
||||||
|
|
||||||
|
#define SOUND_FLAGS (DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLFREQUENCY)
|
||||||
|
DSoundManager::DSoundManager(HWND theHWnd)
|
||||||
|
{
|
||||||
|
mLastReleaseTick = 0;
|
||||||
|
mPrimaryBuffer = NULL;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_SOURCE_SOUNDS; i++)
|
||||||
|
{
|
||||||
|
mSourceSounds[i] = NULL;
|
||||||
|
mBaseVolumes[i] = 1;
|
||||||
|
mBasePans[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CHANNELS; i++)
|
||||||
|
mPlayingSounds[i] = NULL;
|
||||||
|
|
||||||
|
mDirectSound = NULL;
|
||||||
|
|
||||||
|
mMasterVolume = 1.0;
|
||||||
|
|
||||||
|
//typedef HRESULT (WINAPI *DirectSoundCreateFunc)(LPCGUID lpcGuid, LPDIRECTSOUND * ppDS, LPUNKNOWN pUnkOuter);
|
||||||
|
//DirectSoundCreateFunc aDirectSoundCreateFunc = (DirectSoundCreateFunc)GetProcAddress(gDSoundDLL,"DirectSoundCreate");
|
||||||
|
|
||||||
|
// Seems crazy but this was even suggested in MSDN docs for windowless applications
|
||||||
|
if (theHWnd == NULL)
|
||||||
|
theHWnd = ::GetDesktopWindow();
|
||||||
|
|
||||||
|
//if (aDirectSoundCreateFunc != NULL && aDirectSoundCreateFunc(NULL, &mDirectSound, NULL) == DS_OK)
|
||||||
|
|
||||||
|
if (DirectSoundCreate(NULL, &mDirectSound, NULL) == DS_OK)
|
||||||
|
{
|
||||||
|
bool handled = false;
|
||||||
|
|
||||||
|
if (theHWnd != NULL)
|
||||||
|
{
|
||||||
|
HRESULT aResult = mDirectSound->SetCooperativeLevel(theHWnd, DSSCL_PRIORITY);
|
||||||
|
if (SUCCEEDED(aResult))
|
||||||
|
{
|
||||||
|
// Set primary buffer to 16-bit 44.1Khz
|
||||||
|
WAVEFORMATEX aWaveFormat;
|
||||||
|
DSBUFFERDESC aBufferDesc;
|
||||||
|
|
||||||
|
// Set up wave format structure.
|
||||||
|
int aBitCount = 16;
|
||||||
|
int aChannelCount = 2;
|
||||||
|
int aSampleRate = 44100;
|
||||||
|
|
||||||
|
// Set up wave format structure.
|
||||||
|
memset(&aWaveFormat, 0, sizeof(WAVEFORMATEX));
|
||||||
|
aWaveFormat.cbSize = sizeof(WAVEFORMATEX);
|
||||||
|
aWaveFormat.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
|
aWaveFormat.nChannels = aChannelCount;
|
||||||
|
aWaveFormat.nSamplesPerSec = aSampleRate;
|
||||||
|
aWaveFormat.nBlockAlign = aChannelCount * aBitCount / 8;
|
||||||
|
aWaveFormat.nAvgBytesPerSec =
|
||||||
|
aWaveFormat.nSamplesPerSec * aWaveFormat.nBlockAlign;
|
||||||
|
aWaveFormat.wBitsPerSample = aBitCount;
|
||||||
|
|
||||||
|
// Set up DSBUFFERDESC structure.
|
||||||
|
memset(&aBufferDesc, 0, sizeof(DSBUFFERDESC)); // Zero it out.
|
||||||
|
aBufferDesc.dwSize = sizeof(DSBUFFERDESC1);
|
||||||
|
aBufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER;//| DSBCAPS_CTRL3D; // Need default controls (pan, volume, frequency).
|
||||||
|
aBufferDesc.dwBufferBytes = 0;
|
||||||
|
aBufferDesc.lpwfxFormat = NULL;//(LPWAVEFORMATEX)&aWaveFormat;
|
||||||
|
|
||||||
|
HRESULT aResult = mDirectSound->CreateSoundBuffer(&aBufferDesc, &mPrimaryBuffer, NULL);
|
||||||
|
if (aResult == DS_OK)
|
||||||
|
{
|
||||||
|
aResult = mPrimaryBuffer->SetFormat(&aWaveFormat);
|
||||||
|
}
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handled)
|
||||||
|
{
|
||||||
|
HRESULT aResult = mDirectSound->SetCooperativeLevel(theHWnd,DSSCL_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DSoundManager::~DSoundManager()
|
||||||
|
{
|
||||||
|
ReleaseChannels();
|
||||||
|
ReleaseSounds();
|
||||||
|
|
||||||
|
if (mPrimaryBuffer)
|
||||||
|
mPrimaryBuffer->Release();
|
||||||
|
|
||||||
|
if (mDirectSound != NULL)
|
||||||
|
{
|
||||||
|
mDirectSound->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int DSoundManager::FindFreeChannel()
|
||||||
|
{
|
||||||
|
DWORD aTick = GetTickCount();
|
||||||
|
if (aTick-mLastReleaseTick > 1000)
|
||||||
|
{
|
||||||
|
ReleaseFreeChannels();
|
||||||
|
mLastReleaseTick = aTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_CHANNELS; i++)
|
||||||
|
{
|
||||||
|
if (mPlayingSounds[i] == NULL)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
if (mPlayingSounds[i]->IsReleased())
|
||||||
|
{
|
||||||
|
delete mPlayingSounds[i];
|
||||||
|
mPlayingSounds[i] = NULL;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DSoundManager::Initialized()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if (mDirectSound!=NULL)
|
||||||
|
{
|
||||||
|
mDirectSound->SetCooperativeLevel(theHWnd,DSSCL_NORMAL);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return (mDirectSound != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DSoundManager::VolumeToDB(float theVolume)
|
||||||
|
{
|
||||||
|
int aVol = (int) ((log10(1 + theVolume*9) - 1.0) * 2333);
|
||||||
|
if (aVol < -2000)
|
||||||
|
aVol = -10000;
|
||||||
|
|
||||||
|
return aVol;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundManager::SetVolume(float theVolume)
|
||||||
|
{
|
||||||
|
mMasterVolume = theVolume;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_CHANNELS; i++)
|
||||||
|
if (mPlayingSounds[i] != NULL)
|
||||||
|
mPlayingSounds[i]->RehupVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DSoundManager::LoadWAVSound(unsigned int theSfxID, const StringImpl& theFilename)
|
||||||
|
{
|
||||||
|
int aDataSize;
|
||||||
|
|
||||||
|
FILE* fp;
|
||||||
|
|
||||||
|
fp = fopen(theFilename.c_str(), "rb");
|
||||||
|
|
||||||
|
if (fp <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char aChunkType[5];
|
||||||
|
aChunkType[4] = '\0';
|
||||||
|
uint32 aChunkSize;
|
||||||
|
|
||||||
|
fread(aChunkType, 1, 4, fp);
|
||||||
|
if (!strcmp(aChunkType, "RIFF") == 0)
|
||||||
|
return false;
|
||||||
|
fread(&aChunkSize, 4, 1, fp);
|
||||||
|
|
||||||
|
fread(aChunkType, 1, 4, fp);
|
||||||
|
if (!strcmp(aChunkType, "WAVE") == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint16 aBitCount = 16;
|
||||||
|
uint16 aChannelCount = 1;
|
||||||
|
uint32 aSampleRate = 22050;
|
||||||
|
uint8 anXor = 0;
|
||||||
|
|
||||||
|
while (!feof(fp))
|
||||||
|
{
|
||||||
|
fread(aChunkType, 1, 4, fp);
|
||||||
|
if (fread(&aChunkSize, 4, 1, fp) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int aCurPos = ftell(fp);
|
||||||
|
|
||||||
|
if (strcmp(aChunkType, "fmt ") == 0)
|
||||||
|
{
|
||||||
|
uint16 aFormatTag;
|
||||||
|
uint32 aBytesPerSec;
|
||||||
|
uint16 aBlockAlign;
|
||||||
|
|
||||||
|
fread(&aFormatTag, 2, 1, fp);
|
||||||
|
fread(&aChannelCount, 2, 1, fp);
|
||||||
|
fread(&aSampleRate, 4, 1, fp);
|
||||||
|
fread(&aBytesPerSec, 4, 1, fp);
|
||||||
|
fread(&aBlockAlign, 2, 1, fp);
|
||||||
|
fread(&aBitCount, 2, 1, fp);
|
||||||
|
|
||||||
|
if (aFormatTag != 1)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (strcmp(aChunkType, "data") == 0)
|
||||||
|
{
|
||||||
|
aDataSize = aChunkSize;
|
||||||
|
|
||||||
|
mSourceDataSizes[theSfxID] = aChunkSize;
|
||||||
|
|
||||||
|
PCMWAVEFORMAT aWaveFormat;
|
||||||
|
DSBUFFERDESC aBufferDesc;
|
||||||
|
|
||||||
|
// Set up wave format structure.
|
||||||
|
memset(&aWaveFormat, 0, sizeof(PCMWAVEFORMAT));
|
||||||
|
aWaveFormat.wf.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
|
aWaveFormat.wf.nChannels = aChannelCount;
|
||||||
|
aWaveFormat.wf.nSamplesPerSec = aSampleRate;
|
||||||
|
aWaveFormat.wf.nBlockAlign = aChannelCount*aBitCount/8;
|
||||||
|
aWaveFormat.wf.nAvgBytesPerSec =
|
||||||
|
aWaveFormat.wf.nSamplesPerSec * aWaveFormat.wf.nBlockAlign;
|
||||||
|
aWaveFormat.wBitsPerSample = aBitCount;
|
||||||
|
// Set up DSBUFFERDESC structure.
|
||||||
|
memset(&aBufferDesc, 0, sizeof(DSBUFFERDESC)); // Zero it out.
|
||||||
|
aBufferDesc.dwSize = sizeof(DSBUFFERDESC);
|
||||||
|
//aBufferDesc.dwFlags = DSBCAPS_CTRL3D;
|
||||||
|
aBufferDesc.dwFlags = SOUND_FLAGS; //DSBCAPS_CTRLDEFAULT;
|
||||||
|
|
||||||
|
//aBufferDesc.dwFlags = 0;
|
||||||
|
|
||||||
|
aBufferDesc.dwBufferBytes = aDataSize;
|
||||||
|
aBufferDesc.lpwfxFormat = (LPWAVEFORMATEX)&aWaveFormat;
|
||||||
|
|
||||||
|
if (mDirectSound->CreateSoundBuffer(&aBufferDesc, &mSourceSounds[theSfxID], NULL) != DS_OK)
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void* lpvPtr;
|
||||||
|
DWORD dwBytes;
|
||||||
|
if (mSourceSounds[theSfxID]->Lock(0, aDataSize, &lpvPtr, &dwBytes, NULL, NULL, 0) != DS_OK)
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aReadSize = (int)fread(lpvPtr, 1, aDataSize, fp);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
for (int i = 0; i < aDataSize; i++)
|
||||||
|
((uint8*) lpvPtr)[i] ^= anXor;
|
||||||
|
|
||||||
|
if (mSourceSounds[theSfxID]->Unlock(lpvPtr, dwBytes, NULL, NULL) != DS_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (aReadSize != aDataSize)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(fp, aCurPos+aChunkSize, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DSoundManager::LoadSound(unsigned int theSfxID, const StringImpl& theFilename)
|
||||||
|
{
|
||||||
|
if ((theSfxID < 0) || (theSfxID >= MAX_SOURCE_SOUNDS))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ReleaseSound(theSfxID);
|
||||||
|
|
||||||
|
if (!mDirectSound)
|
||||||
|
return true; // sounds just won't play, but this is not treated as a failure condition
|
||||||
|
|
||||||
|
mSourceFileNames[theSfxID] = theFilename;
|
||||||
|
|
||||||
|
StringImpl aFilename = theFilename;
|
||||||
|
|
||||||
|
if (aFilename.EndsWith(".wav", StringImpl::CompareKind_OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
if (LoadWAVSound(theSfxID, aFilename))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DSoundManager::LoadSound(const StringImpl& theFilename)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MAX_SOURCE_SOUNDS; i++)
|
||||||
|
if (mSourceFileNames[i] == theFilename)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
for (i = MAX_SOURCE_SOUNDS-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (mSourceSounds[i] == NULL)
|
||||||
|
{
|
||||||
|
if (!LoadSound(i, theFilename))
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundManager::ReleaseSound(unsigned int theSfxID)
|
||||||
|
{
|
||||||
|
if (mSourceSounds[theSfxID] != NULL)
|
||||||
|
{
|
||||||
|
mSourceSounds[theSfxID]->Release();
|
||||||
|
mSourceSounds[theSfxID] = NULL;
|
||||||
|
mSourceFileNames[theSfxID] = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int DSoundManager::GetFreeSoundId()
|
||||||
|
{
|
||||||
|
for (int i=0; i<MAX_SOURCE_SOUNDS; i++)
|
||||||
|
{
|
||||||
|
if (mSourceSounds[i]==NULL)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DSoundManager::GetNumSounds()
|
||||||
|
{
|
||||||
|
int aCount = 0;
|
||||||
|
for (int i=0; i<MAX_SOURCE_SOUNDS; i++)
|
||||||
|
{
|
||||||
|
if (mSourceSounds[i]!=NULL)
|
||||||
|
aCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return aCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DSoundManager::SetBaseVolume(unsigned int theSfxID, float theBaseVolume)
|
||||||
|
{
|
||||||
|
if ((theSfxID < 0) || (theSfxID >= MAX_SOURCE_SOUNDS))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mBaseVolumes[theSfxID] = theBaseVolume;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DSoundManager::SetBasePan(unsigned int theSfxID, int theBasePan)
|
||||||
|
{
|
||||||
|
if ((theSfxID < 0) || (theSfxID >= MAX_SOURCE_SOUNDS))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mBasePans[theSfxID] = theBasePan;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFSoundInstance* DSoundManager::GetSoundInstance(unsigned int theSfxID)
|
||||||
|
{
|
||||||
|
if (theSfxID > MAX_SOURCE_SOUNDS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
int aFreeChannel = FindFreeChannel();
|
||||||
|
if (aFreeChannel < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (mDirectSound==NULL)
|
||||||
|
{
|
||||||
|
mPlayingSounds[aFreeChannel] = new DSoundInstance(this, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mSourceSounds[theSfxID] == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
mPlayingSounds[aFreeChannel] = new DSoundInstance(this, mSourceSounds[theSfxID]);
|
||||||
|
}
|
||||||
|
|
||||||
|
mPlayingSounds[aFreeChannel]->SetBasePan(mBasePans[theSfxID]);
|
||||||
|
mPlayingSounds[aFreeChannel]->SetBaseVolume(mBaseVolumes[theSfxID]);
|
||||||
|
|
||||||
|
return mPlayingSounds[aFreeChannel];
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundManager::ReleaseSounds()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_SOURCE_SOUNDS; i++)
|
||||||
|
if (mSourceSounds[i] != NULL)
|
||||||
|
{
|
||||||
|
mSourceSounds[i]->Release();
|
||||||
|
mSourceSounds[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundManager::ReleaseChannels()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_CHANNELS; i++)
|
||||||
|
if (mPlayingSounds[i] != NULL)
|
||||||
|
{
|
||||||
|
delete mPlayingSounds[i];
|
||||||
|
mPlayingSounds[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundManager::ReleaseFreeChannels()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_CHANNELS; i++)
|
||||||
|
if (mPlayingSounds[i] != NULL && mPlayingSounds[i]->IsReleased())
|
||||||
|
{
|
||||||
|
delete mPlayingSounds[i];
|
||||||
|
mPlayingSounds[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundManager::StopAllSounds()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_CHANNELS; i++)
|
||||||
|
if (mPlayingSounds[i] != NULL)
|
||||||
|
{
|
||||||
|
bool isAutoRelease = mPlayingSounds[i]->mAutoRelease;
|
||||||
|
mPlayingSounds[i]->Stop();
|
||||||
|
mPlayingSounds[i]->mAutoRelease = isAutoRelease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float DSoundManager::GetMasterVolume()
|
||||||
|
{
|
||||||
|
MIXERCONTROLDETAILS mcd;
|
||||||
|
MIXERCONTROLDETAILS_UNSIGNED mxcd_u;
|
||||||
|
MIXERLINECONTROLS mxlc;
|
||||||
|
MIXERCONTROL mlct;
|
||||||
|
MIXERLINE mixerLine;
|
||||||
|
HMIXER hmx;
|
||||||
|
MIXERCAPS pmxcaps;
|
||||||
|
|
||||||
|
mixerOpen((HMIXER*) &hmx, 0, 0, 0, MIXER_OBJECTF_MIXER);
|
||||||
|
mixerGetDevCaps(0, &pmxcaps, sizeof(pmxcaps));
|
||||||
|
|
||||||
|
mxlc.cbStruct = sizeof(mxlc);
|
||||||
|
mxlc.cbmxctrl = sizeof(mlct);
|
||||||
|
mxlc.pamxctrl = &mlct;
|
||||||
|
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
|
||||||
|
mixerLine.cbStruct = sizeof(mixerLine);
|
||||||
|
mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
|
||||||
|
mixerGetLineInfo((HMIXEROBJ) hmx, &mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE);
|
||||||
|
mxlc.dwLineID = mixerLine.dwLineID;
|
||||||
|
mixerGetLineControls((HMIXEROBJ) hmx, &mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
|
||||||
|
|
||||||
|
mcd.cbStruct = sizeof(mcd);
|
||||||
|
mcd.dwControlID = mlct.dwControlID;
|
||||||
|
mcd.cChannels = 1;
|
||||||
|
mcd.cMultipleItems = 0;
|
||||||
|
mcd.cbDetails = sizeof(mxcd_u);
|
||||||
|
mcd.paDetails = &mxcd_u;
|
||||||
|
|
||||||
|
mixerGetControlDetails((HMIXEROBJ) hmx, &mcd, 0L);
|
||||||
|
|
||||||
|
mixerClose(hmx);
|
||||||
|
|
||||||
|
return mxcd_u.dwValue / (float) 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundManager::SetMasterVolume(float theVolume)
|
||||||
|
{
|
||||||
|
MIXERCONTROLDETAILS mcd;
|
||||||
|
MIXERCONTROLDETAILS_UNSIGNED mxcd_u;
|
||||||
|
MIXERLINECONTROLS mxlc;
|
||||||
|
MIXERCONTROL mlct;
|
||||||
|
MIXERLINE mixerLine;
|
||||||
|
HMIXER hmx;
|
||||||
|
MIXERCAPS pmxcaps;
|
||||||
|
|
||||||
|
mixerOpen((HMIXER*) &hmx, 0, 0, 0, MIXER_OBJECTF_MIXER);
|
||||||
|
mixerGetDevCaps(0, &pmxcaps, sizeof(pmxcaps));
|
||||||
|
|
||||||
|
mxlc.cbStruct = sizeof(mxlc);
|
||||||
|
mxlc.cbmxctrl = sizeof(mlct);
|
||||||
|
mxlc.pamxctrl = &mlct;
|
||||||
|
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
|
||||||
|
mixerLine.cbStruct = sizeof(mixerLine);
|
||||||
|
mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
|
||||||
|
mixerGetLineInfo((HMIXEROBJ) hmx, &mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE);
|
||||||
|
mxlc.dwLineID = mixerLine.dwLineID;
|
||||||
|
mixerGetLineControls((HMIXEROBJ) hmx, &mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
|
||||||
|
|
||||||
|
mcd.cbStruct = sizeof(mcd);
|
||||||
|
mcd.dwControlID = mlct.dwControlID;
|
||||||
|
mcd.cChannels = 1;
|
||||||
|
mcd.cMultipleItems = 0;
|
||||||
|
mcd.cbDetails = sizeof(mxcd_u);
|
||||||
|
mcd.paDetails = &mxcd_u;
|
||||||
|
|
||||||
|
mxcd_u.dwValue = (int) (0xFFFF * theVolume);
|
||||||
|
mixerSetControlDetails((HMIXEROBJ) hmx, &mcd, 0L);
|
||||||
|
|
||||||
|
mixerClose(hmx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundManager::Flush()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSoundManager::SetCooperativeWindow(HWND theHWnd, bool isWindowed)
|
||||||
|
{
|
||||||
|
if (mDirectSound != NULL)
|
||||||
|
mDirectSound->SetCooperativeLevel(theHWnd,DSSCL_NORMAL);
|
||||||
|
/*
|
||||||
|
if (isWindowed==true) mDirectSound->SetCooperativeLevel(theHWnd,DSSCL_NORMAL);
|
||||||
|
else mDirectSound->SetCooperativeLevel(theHWnd,DSSCL_EXCLUSIVE);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
#undef SOUND_FLAGS
|
68
BeefySysLib/platform/win/DSoundManager.h
Normal file
68
BeefySysLib/platform/win/DSoundManager.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#ifndef __DSOUNDMANAGER_H__
|
||||||
|
#define __DSOUNDMANAGER_H__
|
||||||
|
|
||||||
|
#include <dsound.h>
|
||||||
|
#include "BFSound.h"
|
||||||
|
|
||||||
|
namespace Beefy
|
||||||
|
{
|
||||||
|
|
||||||
|
class DSoundInstance;
|
||||||
|
|
||||||
|
class DSoundManager : public BFSoundManager
|
||||||
|
{
|
||||||
|
friend class DSoundInstance;
|
||||||
|
friend class DSoundMusicInterface;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LPDIRECTSOUNDBUFFER mSourceSounds[MAX_SOURCE_SOUNDS];
|
||||||
|
String mSourceFileNames[MAX_SOURCE_SOUNDS];
|
||||||
|
LPDIRECTSOUNDBUFFER mPrimaryBuffer;
|
||||||
|
int32 mSourceDataSizes[MAX_SOURCE_SOUNDS];
|
||||||
|
float mBaseVolumes[MAX_SOURCE_SOUNDS];
|
||||||
|
int mBasePans[MAX_SOURCE_SOUNDS];
|
||||||
|
DSoundInstance* mPlayingSounds[MAX_CHANNELS];
|
||||||
|
float mMasterVolume;
|
||||||
|
DWORD mLastReleaseTick;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int FindFreeChannel();
|
||||||
|
int VolumeToDB(float theVolume);
|
||||||
|
bool LoadWAVSound(unsigned int theSfxID, const StringImpl& theFilename);
|
||||||
|
void ReleaseFreeChannels();
|
||||||
|
|
||||||
|
public:
|
||||||
|
LPDIRECTSOUND mDirectSound;
|
||||||
|
|
||||||
|
DSoundManager(HWND theHWnd);
|
||||||
|
virtual ~DSoundManager();
|
||||||
|
|
||||||
|
virtual bool Initialized() override;
|
||||||
|
|
||||||
|
virtual bool LoadSound(unsigned int theSfxID, const StringImpl& theFilename) override;
|
||||||
|
virtual int LoadSound(const StringImpl& theFilename) override;
|
||||||
|
virtual void ReleaseSound(unsigned int theSfxID) override;
|
||||||
|
|
||||||
|
virtual void SetVolume(float theVolume) override;
|
||||||
|
virtual bool SetBaseVolume(unsigned int theSfxID, float theBaseVolume) override;
|
||||||
|
virtual bool SetBasePan(unsigned int theSfxID, int theBasePan) override;
|
||||||
|
|
||||||
|
virtual BFSoundInstance* GetSoundInstance(unsigned int theSfxID);
|
||||||
|
|
||||||
|
virtual void ReleaseSounds() override;
|
||||||
|
virtual void ReleaseChannels() override;
|
||||||
|
|
||||||
|
virtual float GetMasterVolume() override;
|
||||||
|
virtual void SetMasterVolume(float theVolume) override;
|
||||||
|
|
||||||
|
virtual void Flush() override;
|
||||||
|
|
||||||
|
virtual void SetCooperativeWindow(HWND theHWnd, bool isWindowed);
|
||||||
|
virtual void StopAllSounds() override;
|
||||||
|
virtual int GetFreeSoundId() override;
|
||||||
|
virtual int GetNumSounds() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__DSOUNDMANAGER_H__
|
|
@ -1,7 +1,9 @@
|
||||||
|
#include <dsound.h>
|
||||||
#include "WinBFApp.h"
|
#include "WinBFApp.h"
|
||||||
#include "DXRenderDevice.h"
|
#include "DXRenderDevice.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "../../util/BeefPerf.h"
|
#include "../../util/BeefPerf.h"
|
||||||
|
#include "DSoundManager.h"
|
||||||
|
|
||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
#pragma comment(lib, "dwmapi.lib")
|
#pragma comment(lib, "dwmapi.lib")
|
||||||
|
@ -130,9 +132,9 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
|
||||||
::SystemParametersInfo(SPI_GETWORKAREA, NULL, &desktopRect, NULL);
|
::SystemParametersInfo(SPI_GETWORKAREA, NULL, &desktopRect, NULL);
|
||||||
|
|
||||||
if (x + width >= desktopRect.right)
|
if (x + width >= desktopRect.right)
|
||||||
x = std::max((int)desktopRect.left, requestedX - width);
|
x = BF_MAX((int)desktopRect.left, requestedX - width);
|
||||||
if (y + height >= desktopRect.bottom)
|
if (y + height >= desktopRect.bottom)
|
||||||
y = std::max((int)desktopRect.top, requestedY - height);
|
y = BF_MAX((int)desktopRect.top, requestedY - height);
|
||||||
}
|
}
|
||||||
|
|
||||||
mFlags = windowFlags;
|
mFlags = windowFlags;
|
||||||
|
@ -1037,11 +1039,13 @@ WinBFApp::WinBFApp()
|
||||||
|
|
||||||
mDataDir = mInstallDir;
|
mDataDir = mInstallDir;
|
||||||
mInMsgProc = false;
|
mInMsgProc = false;
|
||||||
|
mDSoundManager = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
WinBFApp::~WinBFApp()
|
WinBFApp::~WinBFApp()
|
||||||
{
|
{
|
||||||
delete mRenderDevice;
|
delete mRenderDevice;
|
||||||
|
delete mDSoundManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinBFApp::Init()
|
void WinBFApp::Init()
|
||||||
|
@ -1670,6 +1674,13 @@ BFSysBitmap* WinBFApp::LoadSysBitmap(const WCHAR* fileName)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BFSoundManager* WinBFApp::GetSoundManager()
|
||||||
|
{
|
||||||
|
if (mDSoundManager == NULL)
|
||||||
|
mDSoundManager = new DSoundManager(NULL);
|
||||||
|
return mDSoundManager;
|
||||||
|
}
|
||||||
|
|
||||||
void WinBFWindow::ModalsRemoved()
|
void WinBFWindow::ModalsRemoved()
|
||||||
{
|
{
|
||||||
::EnableWindow(mHWnd, TRUE);
|
::EnableWindow(mHWnd, TRUE);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
NS_BF_BEGIN;
|
NS_BF_BEGIN;
|
||||||
|
|
||||||
class RenderDevice;
|
class RenderDevice;
|
||||||
|
class DSoundManager;
|
||||||
|
|
||||||
typedef Dictionary<void*, HGLOBAL> PtrToHGlobalMap;
|
typedef Dictionary<void*, HGLOBAL> PtrToHGlobalMap;
|
||||||
typedef Dictionary<String, uint32> StringToUIntMap;
|
typedef Dictionary<String, uint32> StringToUIntMap;
|
||||||
|
@ -87,6 +88,7 @@ public:
|
||||||
bool mInMsgProc;
|
bool mInMsgProc;
|
||||||
PtrToHGlobalMap mLockedHGlobalMap;
|
PtrToHGlobalMap mLockedHGlobalMap;
|
||||||
StringToUIntMap mClipboardFormatMap;
|
StringToUIntMap mClipboardFormatMap;
|
||||||
|
DSoundManager* mDSoundManager;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Draw() override;
|
virtual void Draw() override;
|
||||||
|
@ -112,6 +114,8 @@ public:
|
||||||
virtual void RehupMouse() override;
|
virtual void RehupMouse() override;
|
||||||
|
|
||||||
virtual BFSysBitmap* LoadSysBitmap(const WCHAR* fileName) override;
|
virtual BFSysBitmap* LoadSysBitmap(const WCHAR* fileName) override;
|
||||||
|
|
||||||
|
virtual BFSoundManager* GetSoundManager() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_BF_END;
|
NS_BF_END;
|
||||||
|
|
|
@ -31,6 +31,25 @@ USING_NS_BF;
|
||||||
#define BP_ABI_VERSION 2
|
#define BP_ABI_VERSION 2
|
||||||
|
|
||||||
BpManager* BpManager::sBpManager = NULL;
|
BpManager* BpManager::sBpManager = NULL;
|
||||||
|
static bool gOwnsBpManager = false;
|
||||||
|
static BpThreadInfo sFakeThreadInfo;
|
||||||
|
|
||||||
|
struct BpManagerOwner
|
||||||
|
{
|
||||||
|
BpManager* mOwnedManager;
|
||||||
|
bool mDidShutdown;
|
||||||
|
BpManagerOwner()
|
||||||
|
{
|
||||||
|
mOwnedManager = NULL;
|
||||||
|
mDidShutdown = false;
|
||||||
|
}
|
||||||
|
~BpManagerOwner()
|
||||||
|
{
|
||||||
|
mDidShutdown = true;
|
||||||
|
delete mOwnedManager;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static BpManagerOwner gBpManagerOwner;
|
||||||
|
|
||||||
BF_TLS_DECLSPEC BpThreadInfo* Beefy::BpManager::sBpThreadInfo;
|
BF_TLS_DECLSPEC BpThreadInfo* Beefy::BpManager::sBpThreadInfo;
|
||||||
|
|
||||||
|
@ -314,7 +333,7 @@ const char* BpCmdTarget::ToStrPtr(const char* str)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BPCMD_PREPARE if (!BpManager::Get()->mCollectData) return; AutoCrit autoCrit(mCritSect)
|
#define BPCMD_PREPARE if ((gBpManagerOwner.mDidShutdown) || (!BpManager::Get()->mCollectData)) return; AutoCrit autoCrit(mCritSect)
|
||||||
|
|
||||||
#define GET_FROM(ptr, T) *((T*)(ptr += sizeof(T)) - 1)
|
#define GET_FROM(ptr, T) *((T*)(ptr += sizeof(T)) - 1)
|
||||||
|
|
||||||
|
@ -1527,6 +1546,8 @@ BpThreadInfo* BpManager::GetCurThreadInfo()
|
||||||
BpThreadInfo* threadInfo = sBpThreadInfo;
|
BpThreadInfo* threadInfo = sBpThreadInfo;
|
||||||
if (threadInfo == NULL)
|
if (threadInfo == NULL)
|
||||||
{
|
{
|
||||||
|
if (gBpManagerOwner.mDidShutdown)
|
||||||
|
return &sFakeThreadInfo;
|
||||||
threadInfo = Get()->SlowGetCurThreadInfo();
|
threadInfo = Get()->SlowGetCurThreadInfo();
|
||||||
sBpThreadInfo = threadInfo;
|
sBpThreadInfo = threadInfo;
|
||||||
}
|
}
|
||||||
|
@ -1583,11 +1604,12 @@ BpManager* BpManager::Get()
|
||||||
{
|
{
|
||||||
sBpManager = new BpManager();
|
sBpManager = new BpManager();
|
||||||
sBpManager->mMutex = mutex;
|
sBpManager->mMutex = mutex;
|
||||||
sBpManager->mSharedMemoryFile = sharedMem;
|
sBpManager->mSharedMemoryFile = fileMapping;
|
||||||
sharedMem->mBpManager = sBpManager;
|
sharedMem->mBpManager = sBpManager;
|
||||||
sharedMem->mABIVersion = BP_ABI_VERSION;
|
sharedMem->mABIVersion = BP_ABI_VERSION;
|
||||||
::UnmapViewOfFile(sharedMem);
|
::UnmapViewOfFile(sharedMem);
|
||||||
::ReleaseMutex(mutex);
|
::ReleaseMutex(mutex);
|
||||||
|
gBpManagerOwner.mOwnedManager = sBpManager;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1609,6 +1631,7 @@ BpManager* BpManager::Get()
|
||||||
if (sBpManager == NULL)
|
if (sBpManager == NULL)
|
||||||
{
|
{
|
||||||
sBpManager = new BpManager();
|
sBpManager = new BpManager();
|
||||||
|
gBpManagerOwner.mOwnedManager = sBpManager;
|
||||||
}
|
}
|
||||||
return sBpManager;
|
return sBpManager;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ TargetDirectory = "$(WorkspaceDir)/dist"
|
||||||
TargetName = "BeefIDE_d"
|
TargetName = "BeefIDE_d"
|
||||||
OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib"
|
OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib"
|
||||||
CLibType = "Dynamic"
|
CLibType = "Dynamic"
|
||||||
DebugCommandArguments = "-test=scripts\\Minidump.txt -testNoExit"
|
DebugCommandArguments = "-proddir=C:\\Beef\\IDE\\Tests\\Test1 -platform=Win32 -test=scripts\\Break.txt -testNoExit"
|
||||||
DebugWorkingDirectory = "c:\\Beef\\IDE\\Tests\\EmptyTest"
|
DebugWorkingDirectory = "c:\\Beef\\IDE\\Tests\\EmptyTest"
|
||||||
EnvironmentVars = ["_NO_DEBUG_HEAP=1"]
|
EnvironmentVars = ["_NO_DEBUG_HEAP=1"]
|
||||||
|
|
||||||
|
|
8
IDE/Tests/Test1/scripts/HotSwap_LocateSym01.txt
Normal file
8
IDE/Tests/Test1/scripts/HotSwap_LocateSym01.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
ShowFile("src/HotSwap_LocateSym01.bf")
|
||||||
|
GotoText("//Test_Start")
|
||||||
|
ToggleBreakpoint()
|
||||||
|
RunWithCompiling()
|
||||||
|
ToggleCommentAt("UseMod_Mod")
|
||||||
|
Compile()
|
||||||
|
StepOver()
|
||||||
|
AssertEvalEquals("f", "7")
|
23
IDE/Tests/Test1/src/HotSwap_LocateSym01.bf
Normal file
23
IDE/Tests/Test1/src/HotSwap_LocateSym01.bf
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma warning disable 168
|
||||||
|
|
||||||
|
namespace IDETest
|
||||||
|
{
|
||||||
|
class HotSwap_LocateSym01
|
||||||
|
{
|
||||||
|
static float UseMod()
|
||||||
|
{
|
||||||
|
float f = 100.0f;
|
||||||
|
/*UseMod_Mod
|
||||||
|
f = f % 31.0f;
|
||||||
|
*/
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Test()
|
||||||
|
{
|
||||||
|
int a = 0;
|
||||||
|
//Test_Start
|
||||||
|
float f = UseMod();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ namespace IDETest
|
||||||
HotSwap_Data.Test();
|
HotSwap_Data.Test();
|
||||||
HotSwap_GetUnusued.Test();
|
HotSwap_GetUnusued.Test();
|
||||||
HotSwap_Interfaces2.Test();
|
HotSwap_Interfaces2.Test();
|
||||||
|
HotSwap_LocateSym01.Test();
|
||||||
HotSwap_Reflection.Test();
|
HotSwap_Reflection.Test();
|
||||||
HotSwap_TLS.Test();
|
HotSwap_TLS.Test();
|
||||||
InlineTester.Test();
|
InlineTester.Test();
|
||||||
|
|
8
IDE/Tests/TestDynCrt1/BeefProj.toml
Normal file
8
IDE/Tests/TestDynCrt1/BeefProj.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
FileVersion = 1
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
Name = "TestStaticCrt1"
|
||||||
|
StartupObject = "TestStaticCrt1.Program"
|
||||||
|
|
||||||
|
[Configs.Debug.Win64]
|
||||||
|
CLibType = "DynamicDebug"
|
5
IDE/Tests/TestDynCrt1/BeefSpace.toml
Normal file
5
IDE/Tests/TestDynCrt1/BeefSpace.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
FileVersion = 1
|
||||||
|
Projects = {TestStaticCrt1 = {Path = "."}}
|
||||||
|
|
||||||
|
[Workspace]
|
||||||
|
StartupProject = "TestStaticCrt1"
|
8
IDE/Tests/TestDynCrt1/scripts/HotSwap_LocateSym01.txt
Normal file
8
IDE/Tests/TestDynCrt1/scripts/HotSwap_LocateSym01.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
ShowFile("src/HotSwap_LocateSym01.bf")
|
||||||
|
GotoText("//Test_Start")
|
||||||
|
ToggleBreakpoint()
|
||||||
|
RunWithCompiling()
|
||||||
|
ToggleCommentAt("UseMod_Mod")
|
||||||
|
Compile()
|
||||||
|
StepOver()
|
||||||
|
AssertEvalEquals("f", "7")
|
23
IDE/Tests/TestDynCrt1/src/HotSwap_LocateSym01.bf
Normal file
23
IDE/Tests/TestDynCrt1/src/HotSwap_LocateSym01.bf
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma warning disable 168
|
||||||
|
|
||||||
|
namespace TestStaticCrt1
|
||||||
|
{
|
||||||
|
class HotSwap_LocateSym01
|
||||||
|
{
|
||||||
|
static float UseMod()
|
||||||
|
{
|
||||||
|
float f = 100.0f;
|
||||||
|
/*UseMod_Mod
|
||||||
|
f = f % 31.0f;
|
||||||
|
*/
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Test()
|
||||||
|
{
|
||||||
|
int a = 0;
|
||||||
|
//Test_Start
|
||||||
|
float f = UseMod();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
IDE/Tests/TestDynCrt1/src/Program.bf
Normal file
10
IDE/Tests/TestDynCrt1/src/Program.bf
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace TestStaticCrt1
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
HotSwap_LocateSym01.Test();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
IDE/dist/BeefConfig.toml
vendored
4
IDE/dist/BeefConfig.toml
vendored
|
@ -9,3 +9,7 @@ Location = { Path = "../../BeefLibs/corlib" }
|
||||||
[Registry.Beefy2D]
|
[Registry.Beefy2D]
|
||||||
Version = "1.0.0"
|
Version = "1.0.0"
|
||||||
Location = { Path = "../../BeefLibs/Beefy2D" }
|
Location = { Path = "../../BeefLibs/Beefy2D" }
|
||||||
|
|
||||||
|
[Registry.SDL2]
|
||||||
|
Version = "1.0.0"
|
||||||
|
Location = { Path = "../../BeefLibs/SDL2" }
|
|
@ -8,7 +8,7 @@ DefaultNamespace = "Mintest"
|
||||||
Aliases = ["corlib"]
|
Aliases = ["corlib"]
|
||||||
|
|
||||||
[Configs.Debug.Win64]
|
[Configs.Debug.Win64]
|
||||||
CLibType = "DynamicDebug"
|
CLibType = "Static"
|
||||||
BeefLibType = "DynamicDebug"
|
BeefLibType = "DynamicDebug"
|
||||||
StackSize = 4194304
|
StackSize = 4194304
|
||||||
DebugCommandArguments = "hey=\"yo man\" zag= zoogles boof stoopers \"\"\"abc efg\"\"\""
|
DebugCommandArguments = "hey=\"yo man\" zag= zoogles boof stoopers \"\"\"abc efg\"\"\""
|
||||||
|
|
|
@ -125,15 +125,24 @@ class Blurg
|
||||||
|
|
||||||
public static int GetInt()
|
public static int GetInt()
|
||||||
{
|
{
|
||||||
|
float f = 10.0f;
|
||||||
|
//f = f % 3.0f;
|
||||||
|
|
||||||
return 123;
|
return 123;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Hey()
|
public static void Hey()
|
||||||
{
|
{
|
||||||
|
float f = 1.2f;
|
||||||
|
//f = f % 2.3f;
|
||||||
|
|
||||||
TestStruct ts = .();
|
TestStruct ts = .();
|
||||||
//int val = ts..mA;
|
//int val = ts..mA;
|
||||||
ts.mA = 123;
|
ts.mA = 123;
|
||||||
|
|
||||||
|
GetInt();
|
||||||
|
GetInt();
|
||||||
|
|
||||||
VoidCall();
|
VoidCall();
|
||||||
int val0 = GetInt();
|
int val0 = GetInt();
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ namespace IDE.Debugger
|
||||||
static extern bool Debugger_OpenMiniDump(char8* filename);
|
static extern bool Debugger_OpenMiniDump(char8* filename);
|
||||||
|
|
||||||
[StdCall,CLink]
|
[StdCall,CLink]
|
||||||
static extern bool Debugger_OpenFile(char8* fileName, char8* args, char8* workingDir, void* envBlockPtr, int32 envBlockLen);
|
static extern bool Debugger_OpenFile(char8* launchPath, char8* targetPath, char8* args, char8* workingDir, void* envBlockPtr, int32 envBlockLen);
|
||||||
|
|
||||||
[StdCall,CLink]
|
[StdCall,CLink]
|
||||||
static extern bool Debugger_Attach(int32 processId, AttachFlags attachFlags);
|
static extern bool Debugger_Attach(int32 processId, AttachFlags attachFlags);
|
||||||
|
@ -405,13 +405,13 @@ namespace IDE.Debugger
|
||||||
Debugger_FullReportMemory();
|
Debugger_FullReportMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OpenFile(String file, String args, String workingDir, Span<char8> envBlock, bool isCompiled)
|
public bool OpenFile(String launchPath, String targetPath, String args, String workingDir, Span<char8> envBlock, bool isCompiled)
|
||||||
{
|
{
|
||||||
DeleteAndNullify!(mRunningPath);
|
DeleteAndNullify!(mRunningPath);
|
||||||
mRunningPath = new String(file);
|
mRunningPath = new String(launchPath);
|
||||||
|
|
||||||
mIsRunningCompiled = isCompiled;
|
mIsRunningCompiled = isCompiled;
|
||||||
return Debugger_OpenFile(file, args, workingDir, envBlock.Ptr, (int32)envBlock.Length);
|
return Debugger_OpenFile(launchPath, targetPath, args, workingDir, envBlock.Ptr, (int32)envBlock.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSymSrvOptions(String symCacheDir, String symSrvStr, SymSrvFlags symSrvFlags)
|
public void SetSymSrvOptions(String symCacheDir, String symSrvStr, SymSrvFlags symSrvFlags)
|
||||||
|
|
|
@ -9295,8 +9295,8 @@ namespace IDE
|
||||||
|
|
||||||
//options.mDebugOptions.mCommand
|
//options.mDebugOptions.mCommand
|
||||||
|
|
||||||
String targetPath = scope String();
|
String launchPath = scope String();
|
||||||
ResolveConfigString(workspaceOptions, project, options, options.mDebugOptions.mCommand, "debug command", targetPath);
|
ResolveConfigString(workspaceOptions, project, options, options.mDebugOptions.mCommand, "debug command", launchPath);
|
||||||
String arguments = scope String();
|
String arguments = scope String();
|
||||||
ResolveConfigString(workspaceOptions, project, options, "$(Arguments)", "debug command arguments", arguments);
|
ResolveConfigString(workspaceOptions, project, options, "$(Arguments)", "debug command arguments", arguments);
|
||||||
String workingDirRel = scope String();
|
String workingDirRel = scope String();
|
||||||
|
@ -9304,8 +9304,14 @@ namespace IDE
|
||||||
var workingDir = scope String();
|
var workingDir = scope String();
|
||||||
Path.GetAbsolutePath(workingDirRel, project.mProjectDir, workingDir);
|
Path.GetAbsolutePath(workingDirRel, project.mProjectDir, workingDir);
|
||||||
|
|
||||||
|
String targetPath = scope .();
|
||||||
|
ResolveConfigString(workspaceOptions, project, options, "$(TargetPath)", "Target path", targetPath);
|
||||||
|
|
||||||
|
IDEUtils.FixFilePath(launchPath);
|
||||||
|
IDEUtils.FixFilePath(targetPath);
|
||||||
|
|
||||||
if (workingDir.IsEmpty)
|
if (workingDir.IsEmpty)
|
||||||
Path.GetDirectoryPath(targetPath, workingDir);
|
Path.GetDirectoryPath(launchPath, workingDir);
|
||||||
|
|
||||||
if (!Directory.Exists(workingDir))
|
if (!Directory.Exists(workingDir))
|
||||||
{
|
{
|
||||||
|
@ -9333,13 +9339,13 @@ namespace IDE
|
||||||
var envBlock = scope List<char8>();
|
var envBlock = scope List<char8>();
|
||||||
Environment.EncodeEnvironmentVariables(envVars, envBlock);
|
Environment.EncodeEnvironmentVariables(envVars, envBlock);
|
||||||
|
|
||||||
if (targetPath.IsWhiteSpace)
|
if (launchPath.IsWhiteSpace)
|
||||||
{
|
{
|
||||||
Fail(scope String()..AppendF("No debug command specified in '{}' properties", project.mProjectName));
|
Fail(scope String()..AppendF("No debug command specified in '{}' properties", project.mProjectName));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mDebugger.OpenFile(targetPath, arguments, workingDir, envBlock, wasCompiled))
|
if (!mDebugger.OpenFile(launchPath, targetPath, arguments, workingDir, envBlock, wasCompiled))
|
||||||
{
|
{
|
||||||
DeleteAndNullify!(mCompileAndRunStopwatch);
|
DeleteAndNullify!(mCompileAndRunStopwatch);
|
||||||
return false;
|
return false;
|
||||||
|
@ -11338,6 +11344,11 @@ namespace IDE
|
||||||
{
|
{
|
||||||
scope AutoBeefPerf("IDEApp.Update");
|
scope AutoBeefPerf("IDEApp.Update");
|
||||||
|
|
||||||
|
/*using (mWorkspace.mMonitor.Enter())
|
||||||
|
{
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
if (mDbgFastUpdate)
|
if (mDbgFastUpdate)
|
||||||
{
|
{
|
||||||
RefreshRate = 240;
|
RefreshRate = 240;
|
||||||
|
|
|
@ -458,7 +458,7 @@ namespace IDE
|
||||||
|
|
||||||
var envBlock = scope List<char8>();
|
var envBlock = scope List<char8>();
|
||||||
Environment.EncodeEnvironmentVariables(envVars, envBlock);
|
Environment.EncodeEnvironmentVariables(envVars, envBlock);
|
||||||
if (!gApp.mDebugger.OpenFile(curProjectInfo.mTestExePath, mTestInstance.mArgs, mTestInstance.mWorkingDir, envBlock, true))
|
if (!gApp.mDebugger.OpenFile(curProjectInfo.mTestExePath, curProjectInfo.mTestExePath, mTestInstance.mArgs, mTestInstance.mWorkingDir, envBlock, true))
|
||||||
{
|
{
|
||||||
QueueOutputLine("ERROR: Failed debug '{0}'", curProjectInfo.mTestExePath);
|
QueueOutputLine("ERROR: Failed debug '{0}'", curProjectInfo.mTestExePath);
|
||||||
TestFailed();
|
TestFailed();
|
||||||
|
|
|
@ -332,7 +332,7 @@ namespace IDE.ui
|
||||||
var envBlock = scope List<char8>();
|
var envBlock = scope List<char8>();
|
||||||
Environment.EncodeEnvironmentVariables(envVars, envBlock);
|
Environment.EncodeEnvironmentVariables(envVars, envBlock);
|
||||||
|
|
||||||
if (!gApp.mDebugger.OpenFile(targetPath, arguments, workingDir, envBlock, false))
|
if (!gApp.mDebugger.OpenFile(targetPath, targetPath, arguments, workingDir, envBlock, false))
|
||||||
{
|
{
|
||||||
gApp.Fail(scope String()..AppendF("Unable to open executable for debugging: {0}", targetPath));
|
gApp.Fail(scope String()..AppendF("Unable to open executable for debugging: {0}", targetPath));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -70,6 +70,11 @@ public:
|
||||||
mNextWithSameName = NULL;
|
mNextWithSameName = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~BeLibEntry()
|
||||||
|
{
|
||||||
|
delete mNextWithSameName;
|
||||||
|
}
|
||||||
|
|
||||||
void AddSymbol(const StringImpl& sym);
|
void AddSymbol(const StringImpl& sym);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -237,8 +237,6 @@ COFF::COFF(DebugTarget* debugTarget) : DbgModule(debugTarget)
|
||||||
mCvDataStream = NULL;
|
mCvDataStream = NULL;
|
||||||
mCvHeaderData = NULL;
|
mCvHeaderData = NULL;
|
||||||
mCvStrTableData = NULL;
|
mCvStrTableData = NULL;
|
||||||
mCvTypeSectionData = NULL;
|
|
||||||
mCvTypeSectionDataSize = -1;
|
|
||||||
mCvPublicSymbolData = NULL;
|
mCvPublicSymbolData = NULL;
|
||||||
mCvGlobalSymbolData = NULL;
|
mCvGlobalSymbolData = NULL;
|
||||||
mNewFPOData = NULL;
|
mNewFPOData = NULL;
|
||||||
|
@ -252,9 +250,6 @@ COFF::COFF(DebugTarget* debugTarget) : DbgModule(debugTarget)
|
||||||
mCvMappedFileSize = 0;
|
mCvMappedFileSize = 0;
|
||||||
//mParsedProcRecs = false;
|
//mParsedProcRecs = false;
|
||||||
|
|
||||||
mCvCompileUnitData = NULL;
|
|
||||||
mCvCompileUnitDataSize = 0;
|
|
||||||
|
|
||||||
mGlobalsTargetType = NULL;
|
mGlobalsTargetType = NULL;
|
||||||
mPrevScanName = NULL;
|
mPrevScanName = NULL;
|
||||||
mProcSymCount = 0;
|
mProcSymCount = 0;
|
||||||
|
@ -3209,7 +3204,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD
|
||||||
_FlushDeferredVariableLocations();
|
_FlushDeferredVariableLocations();
|
||||||
}
|
}
|
||||||
|
|
||||||
CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, uint8* sectionData, int sectionSize)
|
CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* compileUnit, uint8* sectionData, int sectionSize)
|
||||||
{
|
{
|
||||||
BP_ZONE("COFF::ParseCompileUnit");
|
BP_ZONE("COFF::ParseCompileUnit");
|
||||||
|
|
||||||
|
@ -3227,7 +3222,11 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, uint8* sectionDa
|
||||||
|
|
||||||
int allocSizeStart = mAlloc.GetAllocSize();
|
int allocSizeStart = mAlloc.GetAllocSize();
|
||||||
|
|
||||||
CvCompileUnit* compileUnit = new CvCompileUnit(this);
|
if (compileUnit == NULL)
|
||||||
|
{
|
||||||
|
compileUnit = new CvCompileUnit(this);
|
||||||
|
mCompileUnits.push_back(compileUnit);
|
||||||
|
}
|
||||||
compileUnit->mDbgModule = this;
|
compileUnit->mDbgModule = this;
|
||||||
if (moduleInfo != NULL)
|
if (moduleInfo != NULL)
|
||||||
{
|
{
|
||||||
|
@ -3240,7 +3239,6 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, uint8* sectionDa
|
||||||
compileUnit->mModuleIdx = NULL;
|
compileUnit->mModuleIdx = NULL;
|
||||||
compileUnit->mName = mFilePath.c_str();
|
compileUnit->mName = mFilePath.c_str();
|
||||||
}
|
}
|
||||||
mCompileUnits.push_back(compileUnit);
|
|
||||||
|
|
||||||
uint8* data = sectionData;
|
uint8* data = sectionData;
|
||||||
uint8* dataEnd = NULL;
|
uint8* dataEnd = NULL;
|
||||||
|
@ -3373,9 +3371,11 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, uint8* sectionDa
|
||||||
|
|
||||||
data = debugSubSectionsStart;
|
data = debugSubSectionsStart;
|
||||||
dataEnd = data + taggedSize;
|
dataEnd = data + taggedSize;
|
||||||
while (data < dataEnd)
|
while (true)
|
||||||
{
|
{
|
||||||
PTR_ALIGN(data, sectionData, 4);
|
PTR_ALIGN(data, sectionData, 4);
|
||||||
|
if (data >= dataEnd)
|
||||||
|
break;
|
||||||
GET_INTO(int32, lineInfoType);
|
GET_INTO(int32, lineInfoType);
|
||||||
GET_INTO(int32, lineInfoLength);
|
GET_INTO(int32, lineInfoLength);
|
||||||
uint8* dataStart = data;
|
uint8* dataStart = data;
|
||||||
|
@ -3895,7 +3895,7 @@ CvCompileUnit* COFF::ParseCompileUnit(int compileUnitId)
|
||||||
|
|
||||||
int sectionSize = 0;
|
int sectionSize = 0;
|
||||||
uint8* sectionData = CvReadStream(moduleInfo->mStream, §ionSize);
|
uint8* sectionData = CvReadStream(moduleInfo->mStream, §ionSize);
|
||||||
ParseCompileUnit(moduleInfo, sectionData, sectionSize);
|
ParseCompileUnit(moduleInfo, NULL, sectionData, sectionSize);
|
||||||
delete sectionData;
|
delete sectionData;
|
||||||
return moduleInfo->mCompileUnit;
|
return moduleInfo->mCompileUnit;
|
||||||
}
|
}
|
||||||
|
@ -5641,10 +5641,10 @@ void COFF::ReportMemory(MemReporter* memReporter)
|
||||||
|
|
||||||
if (mCvHeaderData != NULL)
|
if (mCvHeaderData != NULL)
|
||||||
memReporter->Add("mCvHeaderData", mCvStreamSizes[1]);
|
memReporter->Add("mCvHeaderData", mCvStreamSizes[1]);
|
||||||
if (mCvTypeSectionData != NULL)
|
for (auto& entry : mCvTypeSectionData)
|
||||||
{
|
{
|
||||||
if (mCvTypeSectionDataSize != -1)
|
if (entry.mSize != -1)
|
||||||
memReporter->Add("mCvTypeSectionData", mCvTypeSectionDataSize);
|
memReporter->Add("mCvTypeSectionData", entry.mSize);
|
||||||
else
|
else
|
||||||
memReporter->Add("mCvTypeSectionData", mCvStreamSizes[2]);
|
memReporter->Add("mCvTypeSectionData", mCvStreamSizes[2]);
|
||||||
}
|
}
|
||||||
|
@ -5784,10 +5784,12 @@ void COFF::ClosePDB()
|
||||||
mCvHeaderData = NULL;
|
mCvHeaderData = NULL;
|
||||||
delete mCvStrTableData;
|
delete mCvStrTableData;
|
||||||
mCvStrTableData = NULL;
|
mCvStrTableData = NULL;
|
||||||
delete mCvTypeSectionData;
|
for (auto& entry : mCvTypeSectionData)
|
||||||
mCvTypeSectionData = NULL;
|
delete entry.mData;
|
||||||
delete mCvCompileUnitData;
|
mCvTypeSectionData.Clear();
|
||||||
mCvCompileUnitData = NULL;
|
for (auto& entry : mCvCompileUnitData)
|
||||||
|
delete entry.mData;
|
||||||
|
mCvCompileUnitData.Clear();
|
||||||
delete mCvPublicSymbolData;
|
delete mCvPublicSymbolData;
|
||||||
mCvPublicSymbolData = NULL;
|
mCvPublicSymbolData = NULL;
|
||||||
delete mCvGlobalSymbolData;
|
delete mCvGlobalSymbolData;
|
||||||
|
@ -5807,6 +5809,7 @@ void COFF::ClosePDB()
|
||||||
for (auto kv : mHotLibMap)
|
for (auto kv : mHotLibMap)
|
||||||
delete kv.mValue;
|
delete kv.mValue;
|
||||||
mHotLibMap.Clear();
|
mHotLibMap.Clear();
|
||||||
|
mHotLibSymMap.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool COFF::LoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge)
|
bool COFF::LoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge)
|
||||||
|
@ -5883,15 +5886,19 @@ bool COFF::CheckSection(const char* name, uint8* sectionData, int sectionSize)
|
||||||
if (strcmp(name, ".debug$T") == 0)
|
if (strcmp(name, ".debug$T") == 0)
|
||||||
{
|
{
|
||||||
mDbgFlavor = DbgFlavor_MS;
|
mDbgFlavor = DbgFlavor_MS;
|
||||||
mCvTypeSectionData = sectionData;
|
DbgSectionData entry;
|
||||||
mCvTypeSectionDataSize = sectionSize;
|
entry.mData = sectionData;
|
||||||
|
entry.mSize = sectionSize;
|
||||||
|
mCvTypeSectionData.Add(entry);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(name, ".debug$S") == 0)
|
if (strcmp(name, ".debug$S") == 0)
|
||||||
{
|
{
|
||||||
mCvCompileUnitData = sectionData;
|
DbgSectionData entry;
|
||||||
mCvCompileUnitDataSize = sectionSize;
|
entry.mData = sectionData;
|
||||||
|
entry.mSize = sectionSize;
|
||||||
|
mCvCompileUnitData.Add(entry);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5902,20 +5909,23 @@ void COFF::ProcessDebugInfo()
|
||||||
{
|
{
|
||||||
BP_ZONE("COFF::ProcessDebugInfo");
|
BP_ZONE("COFF::ProcessDebugInfo");
|
||||||
|
|
||||||
if ((mCvTypeSectionDataSize > 0) && (mCvCompileUnitDataSize > 0))
|
if ((!mCvTypeSectionData.IsEmpty()) && (!mCvCompileUnitData.IsEmpty()))
|
||||||
{
|
{
|
||||||
auto linkedModule = (COFF*)GetLinkedModule();
|
auto linkedModule = (COFF*)GetLinkedModule();
|
||||||
int startingTypeIdx = (int)linkedModule->mTypes.size();
|
int startingTypeIdx = (int)linkedModule->mTypes.size();
|
||||||
|
|
||||||
InitCvTypes();
|
InitCvTypes();
|
||||||
|
|
||||||
uint8* data = mCvTypeSectionData;
|
for (auto entry : mCvTypeSectionData)
|
||||||
GET_INTO(uint32, infoType);
|
{
|
||||||
BF_ASSERT(infoType == CV_SIGNATURE_C13);
|
uint8* data = entry.mData;
|
||||||
|
GET_INTO(uint32, infoType);
|
||||||
|
BF_ASSERT(infoType == CV_SIGNATURE_C13);
|
||||||
|
|
||||||
CvInitStreamRaw(mCvTypeSectionReader, mCvTypeSectionData + 4, mCvTypeSectionDataSize - 4);
|
CvInitStreamRaw(mCvTypeSectionReader, entry.mData + 4, entry.mSize - 4);
|
||||||
//ParseTypeData(data, mCvTypeSectionDataSize - sizeof(uint32));
|
//ParseTypeData(data, mCvTypeSectionDataSize - sizeof(uint32));
|
||||||
ParseTypeData(mCvTypeSectionReader, 0);
|
ParseTypeData(mCvTypeSectionReader, 0);
|
||||||
|
}
|
||||||
|
|
||||||
FixTypes(startingTypeIdx);
|
FixTypes(startingTypeIdx);
|
||||||
linkedModule->MapTypes(startingTypeIdx);
|
linkedModule->MapTypes(startingTypeIdx);
|
||||||
|
@ -5930,7 +5940,11 @@ void COFF::ProcessDebugInfo()
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
auto compileUnit = ParseCompileUnit(NULL, mCvCompileUnitData, mCvCompileUnitDataSize);
|
CvCompileUnit* compileUnit = NULL;
|
||||||
|
for (auto entry : mCvCompileUnitData)
|
||||||
|
{
|
||||||
|
compileUnit = ParseCompileUnit(NULL, compileUnit, entry.mData, entry.mSize);
|
||||||
|
}
|
||||||
compileUnit->mLanguage = DbgLanguage_Beef;
|
compileUnit->mLanguage = DbgLanguage_Beef;
|
||||||
mMasterCompileUnit->mLanguage = DbgLanguage_Beef;
|
mMasterCompileUnit->mLanguage = DbgLanguage_Beef;
|
||||||
MapCompileUnitMethods(compileUnit);
|
MapCompileUnitMethods(compileUnit);
|
||||||
|
@ -6538,6 +6552,12 @@ addr_target COFF::LocateSymbol(const StringImpl& name)
|
||||||
{
|
{
|
||||||
for (auto sym : libEntry->mSymbols)
|
for (auto sym : libEntry->mSymbols)
|
||||||
{
|
{
|
||||||
|
#ifdef BF_DBG_32
|
||||||
|
if (sym.StartsWith('_'))
|
||||||
|
mHotLibSymMap[sym.Substring(1)] = libEntry;
|
||||||
|
else
|
||||||
|
// Fallthrough
|
||||||
|
#endif
|
||||||
mHotLibSymMap[sym] = libEntry;
|
mHotLibSymMap[sym] = libEntry;
|
||||||
}
|
}
|
||||||
libEntry = libEntry->mNextWithSameName;
|
libEntry = libEntry->mNextWithSameName;
|
||||||
|
@ -6626,9 +6646,21 @@ addr_target COFF::LocateSymbol(const StringImpl& name)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfLogDbg("Loading obj '%s' in '%s'\n", libEntry->mName.c_str(), libEntry->mLibFile->mFilePath.c_str());
|
BfLogDbg("Loading obj '%s' in '%s'\n", libEntry->mName.c_str(), libEntry->mLibFile->mFilePath.c_str());
|
||||||
|
|
||||||
|
// #ifdef _DEBUG
|
||||||
|
// FILE* fpTest = fopen("c:\\temp\\locateSym.obj", "wb");
|
||||||
|
//
|
||||||
|
// uint8* data = new uint8[libEntry->mLength];
|
||||||
|
//
|
||||||
|
// fseek(libEntry->mLibFile->mOldFileStream.mFP, libEntry->mOldDataPos + sizeof(BeLibMemberHeader), SEEK_SET);
|
||||||
|
// fread(data, 1, libEntry->mLength, libEntry->mLibFile->mOldFileStream.mFP);
|
||||||
|
// fwrite(data, 1, libEntry->mLength, fpTest);
|
||||||
|
// fclose(fpTest);
|
||||||
|
// delete data;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
|
||||||
FileSubStream fileStream;
|
FileSubStream fileStream;
|
||||||
fileStream.mFP = libEntry->mLibFile->mOldFileStream.mFP;
|
fileStream.mFP = libEntry->mLibFile->mOldFileStream.mFP;
|
||||||
fileStream.mOffset = libEntry->mOldDataPos + sizeof(BeLibMemberHeader);
|
fileStream.mOffset = libEntry->mOldDataPos + sizeof(BeLibMemberHeader);
|
||||||
|
@ -6789,21 +6821,21 @@ void COFF::ParseFrameDescriptors()
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_BF_DBG_BEGIN
|
NS_BF_DBG_BEGIN
|
||||||
void TestCoff(void* tdata, int tdataSize, void* cuData, int cuDataSize)
|
// void TestCoff(void* tdata, int tdataSize, void* cuData, int cuDataSize)
|
||||||
{
|
// {
|
||||||
DebugTarget* debugTarget = new DebugTarget(NULL);
|
// DebugTarget* debugTarget = new DebugTarget(NULL);
|
||||||
{
|
// {
|
||||||
COFF coff(debugTarget);
|
// COFF coff(debugTarget);
|
||||||
coff.mCvTypeSectionData = (uint8*)tdata;
|
// coff.mCvTypeSectionData = (uint8*)tdata;
|
||||||
coff.mCvTypeSectionDataSize = tdataSize;
|
// coff.mCvTypeSectionDataSize = tdataSize;
|
||||||
|
//
|
||||||
coff.mCvCompileUnitData = (uint8*)cuData;
|
// coff.mCvCompileUnitData = (uint8*)cuData;
|
||||||
coff.mCvCompileUnitDataSize = cuDataSize;
|
// coff.mCvCompileUnitDataSize = cuDataSize;
|
||||||
|
//
|
||||||
coff.ProcessDebugInfo();
|
// coff.ProcessDebugInfo();
|
||||||
}
|
// }
|
||||||
delete debugTarget;
|
// delete debugTarget;
|
||||||
}
|
// }
|
||||||
|
|
||||||
void TestPDB(const String& fileName)
|
void TestPDB(const String& fileName)
|
||||||
{
|
{
|
||||||
|
|
|
@ -202,6 +202,7 @@ public:
|
||||||
Dictionary<String, BeLibEntry*> mSymDict;
|
Dictionary<String, BeLibEntry*> mSymDict;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class COFF : public DbgModule
|
class COFF : public DbgModule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -248,7 +249,7 @@ public:
|
||||||
SafeMemStream* mCvDataStream;
|
SafeMemStream* mCvDataStream;
|
||||||
CvStringTable mStringTable;
|
CvStringTable mStringTable;
|
||||||
uint8* mCvHeaderData;
|
uint8* mCvHeaderData;
|
||||||
uint8* mCvTypeSectionData;
|
//uint8* mCvTypeSectionData
|
||||||
uint8* mCvStrTableData;
|
uint8* mCvStrTableData;
|
||||||
uint8* mCvPublicSymbolData;
|
uint8* mCvPublicSymbolData;
|
||||||
uint8* mCvGlobalSymbolData;
|
uint8* mCvGlobalSymbolData;
|
||||||
|
@ -270,9 +271,11 @@ public:
|
||||||
const char* mPrevScanName;
|
const char* mPrevScanName;
|
||||||
|
|
||||||
// For hot data
|
// For hot data
|
||||||
int mCvTypeSectionDataSize;
|
Array<DbgSectionData> mCvTypeSectionData;
|
||||||
uint8* mCvCompileUnitData;
|
Array<DbgSectionData> mCvCompileUnitData;
|
||||||
int mCvCompileUnitDataSize;
|
//int mCvTypeSectionDataSize;
|
||||||
|
//uint8* mCvCompileUnitData;
|
||||||
|
//int mCvCompileUnitDataSize;
|
||||||
|
|
||||||
HANDLE mCvMappedFile;
|
HANDLE mCvMappedFile;
|
||||||
void* mCvMappedViewOfFile;
|
void* mCvMappedViewOfFile;
|
||||||
|
@ -292,7 +295,7 @@ public:
|
||||||
void ParseTypeData(int sectionNum, CvStreamReader& reader, int& sectionSize, int& dataOfs, int& hashStream, int& hashAdjOffset, int& hashAdjSize, int& minVal, int& maxVal);
|
void ParseTypeData(int sectionNum, CvStreamReader& reader, int& sectionSize, int& dataOfs, int& hashStream, int& hashAdjOffset, int& hashAdjSize, int& minVal, int& maxVal);
|
||||||
virtual void ParseTypeData() override;
|
virtual void ParseTypeData() override;
|
||||||
void ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionData, uint8* data, uint8* dataEnd, CvInlineInfoVec& inlineDataVec, bool deferInternals, DbgSubprogram* useSubprogram);
|
void ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionData, uint8* data, uint8* dataEnd, CvInlineInfoVec& inlineDataVec, bool deferInternals, DbgSubprogram* useSubprogram);
|
||||||
CvCompileUnit* ParseCompileUnit(CvModuleInfo* moduleInfo, uint8* sectionData, int sectionSize);
|
CvCompileUnit* ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* compileUnit, uint8* sectionData, int sectionSize);
|
||||||
virtual CvCompileUnit* ParseCompileUnit(int compileUnitId) override;
|
virtual CvCompileUnit* ParseCompileUnit(int compileUnitId) override;
|
||||||
virtual void MapCompileUnitMethods(DbgCompileUnit* compileUnit) override;
|
virtual void MapCompileUnitMethods(DbgCompileUnit* compileUnit) override;
|
||||||
virtual void MapCompileUnitMethods(int compileUnitId) override;
|
virtual void MapCompileUnitMethods(int compileUnitId) override;
|
||||||
|
|
|
@ -5050,11 +5050,6 @@ void BfCompiler::HotResolve_ReportType(BfHotTypeVersion* hotTypeVersion, HotType
|
||||||
bool applyFlags = true;
|
bool applyFlags = true;
|
||||||
if ((flags & (BfCompiler::HotTypeFlag_ActiveFunction | BfCompiler::HotTypeFlag_Delegate | BfCompiler::HotTypeFlag_FuncPtr)) != 0)
|
if ((flags & (BfCompiler::HotTypeFlag_ActiveFunction | BfCompiler::HotTypeFlag_Delegate | BfCompiler::HotTypeFlag_FuncPtr)) != 0)
|
||||||
{
|
{
|
||||||
// These flags only get applied if we detect we're using an old version
|
|
||||||
// auto hotTypeData = mContext->GetHotTypeData(hotTypeVersion->mTypeId);
|
|
||||||
// auto latestTypeVersion = hotTypeData->GetLatestVersion();
|
|
||||||
// applyFlags = hotTypeVersion->mDataHash != latestTypeVersion->mDataHash;
|
|
||||||
|
|
||||||
applyFlags = (hotTypeVersion->mCommittedHotCompileIdx != -1) && (mHotState->mPendingDataChanges.Contains(hotTypeVersion->mTypeId));
|
applyFlags = (hotTypeVersion->mCommittedHotCompileIdx != -1) && (mHotState->mPendingDataChanges.Contains(hotTypeVersion->mTypeId));
|
||||||
|
|
||||||
if ((!applyFlags) && (hotTypeVersion->mCommittedHotCompileIdx != -1))
|
if ((!applyFlags) && (hotTypeVersion->mCommittedHotCompileIdx != -1))
|
||||||
|
@ -5074,12 +5069,9 @@ void BfCompiler::HotResolve_ReportType(BfHotTypeVersion* hotTypeVersion, HotType
|
||||||
|
|
||||||
BfLogSysM("HotResolve_ReportType %p %s Flags:%X DeclHotIdx:%d\n", hotTypeVersion, mContext->TypeIdToString(hotTypeVersion->mTypeId).c_str(), flags, hotTypeVersion->mDeclHotCompileIdx);
|
BfLogSysM("HotResolve_ReportType %p %s Flags:%X DeclHotIdx:%d\n", hotTypeVersion, mContext->TypeIdToString(hotTypeVersion->mTypeId).c_str(), flags, hotTypeVersion->mDeclHotCompileIdx);
|
||||||
|
|
||||||
//if ((flags & (BfCompiler::HotTypeFlag_Heap | BfCompiler::HotTypeFlag_Delegate | BfCompiler::HotTypeFlag_CanAllocate)) != 0)
|
for (auto member : hotTypeVersion->mMembers)
|
||||||
{
|
{
|
||||||
for (auto member : hotTypeVersion->mMembers)
|
HotResolve_ReportType(member, flags, reason);
|
||||||
{
|
|
||||||
HotResolve_ReportType(member, flags, reason);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5465,6 +5457,8 @@ void BfCompiler::ClearOldHotData()
|
||||||
if (typeInst->mHotTypeData == NULL)
|
if (typeInst->mHotTypeData == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
bool foundCommittedVersion = false;
|
||||||
|
|
||||||
auto latestVersionHead = typeInst->mHotTypeData->GetLatestVersionHead();
|
auto latestVersionHead = typeInst->mHotTypeData->GetLatestVersionHead();
|
||||||
for (int typeIdx = (int)typeInst->mHotTypeData->mTypeVersions.size() - 1; typeIdx >= 0; typeIdx--)
|
for (int typeIdx = (int)typeInst->mHotTypeData->mTypeVersions.size() - 1; typeIdx >= 0; typeIdx--)
|
||||||
{
|
{
|
||||||
|
@ -5475,7 +5469,12 @@ void BfCompiler::ClearOldHotData()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hotVersion->mRefCount == 1)
|
if ((!foundCommittedVersion) && (mHotState != NULL) && (hotVersion->mDeclHotCompileIdx <= mHotState->mCommittedHotCompileIdx))
|
||||||
|
{
|
||||||
|
// Don't remove the latest committed version
|
||||||
|
foundCommittedVersion = true;
|
||||||
|
}
|
||||||
|
else if (hotVersion->mRefCount == 1)
|
||||||
{
|
{
|
||||||
typeInst->mHotTypeData->mTypeVersions.RemoveAt(typeIdx);
|
typeInst->mHotTypeData->mTypeVersions.RemoveAt(typeIdx);
|
||||||
hotVersion->Deref();
|
hotVersion->Deref();
|
||||||
|
|
|
@ -14504,8 +14504,6 @@ void BfModule::CallChainedMethods(BfMethodInstance* methodInstance, bool reverse
|
||||||
|
|
||||||
void BfModule::AddHotDataReferences(BfHotDataReferenceBuilder* builder)
|
void BfModule::AddHotDataReferences(BfHotDataReferenceBuilder* builder)
|
||||||
{
|
{
|
||||||
//auto methodName = MethodToString(mCurMethodInstance, BfMethodNameFlag_OmitTypeName);
|
|
||||||
|
|
||||||
BF_ASSERT(mCurMethodInstance->mIsReified);
|
BF_ASSERT(mCurMethodInstance->mIsReified);
|
||||||
|
|
||||||
if (mCurTypeInstance->mHotTypeData == NULL)
|
if (mCurTypeInstance->mHotTypeData == NULL)
|
||||||
|
@ -14519,8 +14517,6 @@ void BfModule::AddHotDataReferences(BfHotDataReferenceBuilder* builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_ASSERT(hotMethod->mSrcTypeVersion != NULL);
|
BF_ASSERT(hotMethod->mSrcTypeVersion != NULL);
|
||||||
//hotMethod->mSrcTypeVersion = mCurTypeInstance->mHotTypeData->GetLatestVersion();
|
|
||||||
//hotMethod->mSrcTypeVersion->mRefCount++;
|
|
||||||
|
|
||||||
int prevSize = (int)hotMethod->mReferences.size();
|
int prevSize = (int)hotMethod->mReferences.size();
|
||||||
int refCount = (int)(prevSize + builder->mUsedData.size() + builder->mCalledMethods.size() + builder->mDevirtualizedCalledMethods.size());
|
int refCount = (int)(prevSize + builder->mUsedData.size() + builder->mCalledMethods.size() + builder->mDevirtualizedCalledMethods.size());
|
||||||
|
@ -17167,14 +17163,6 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
else if (wantsRemoveBody)
|
else if (wantsRemoveBody)
|
||||||
mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction);
|
mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction);
|
||||||
|
|
||||||
//TODO: Can we actually do this?
|
|
||||||
/*if ((!HasCompiledOutput()) && (!mCompiler->mOptions.mExtraResolveChecks))
|
|
||||||
{
|
|
||||||
mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction);
|
|
||||||
mBfIRBuilder->Func_EraseFromParent(mCurMethodInstance->mIRFunction);
|
|
||||||
mCurMethodInstance->mIRFunction = BfIRFunction();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// We don't want to hold on to pointers to LLVMFunctions of unspecialized types.
|
// We don't want to hold on to pointers to LLVMFunctions of unspecialized types.
|
||||||
// This allows us to delete the mScratchModule LLVM module without rebuilding all
|
// This allows us to delete the mScratchModule LLVM module without rebuilding all
|
||||||
// unspecialized types
|
// unspecialized types
|
||||||
|
|
|
@ -4536,7 +4536,7 @@ void BfModule::FixIntUnknown(BfTypedValue& typedVal)
|
||||||
|
|
||||||
void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs)
|
void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs)
|
||||||
{
|
{
|
||||||
if ((lhs.mType != NULL) && (lhs.mType->IsIntUnknown()))
|
if ((lhs.mType != NULL) && (lhs.mType->IsIntUnknown()) && (rhs.mType != NULL) && (rhs.mType->IsInteger()))
|
||||||
{
|
{
|
||||||
if (CanImplicitlyCast(lhs, rhs.mType))
|
if (CanImplicitlyCast(lhs, rhs.mType))
|
||||||
{
|
{
|
||||||
|
@ -4547,7 +4547,7 @@ void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rhs.mType != NULL) && (rhs.mType->IsIntUnknown()))
|
if ((rhs.mType != NULL) && (rhs.mType->IsIntUnknown()) && (lhs.mType != NULL) && (lhs.mType->IsInteger()))
|
||||||
{
|
{
|
||||||
if (CanImplicitlyCast(rhs, lhs.mType))
|
if (CanImplicitlyCast(rhs, lhs.mType))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1121,6 +1121,9 @@ bool DbgExprEvaluator::TypeIsSubTypeOf(DbgType* srcType, DbgType* wantType, int*
|
||||||
|
|
||||||
DbgTypedValue DbgExprEvaluator::GetBeefTypeById(int typeId)
|
DbgTypedValue DbgExprEvaluator::GetBeefTypeById(int typeId)
|
||||||
{
|
{
|
||||||
|
if (mDebugTarget->mTargetBinary == NULL)
|
||||||
|
return DbgTypedValue();
|
||||||
|
|
||||||
auto typeTypeEntry = mDebugTarget->mTargetBinary->FindType("System.Type", DbgLanguage_Beef);
|
auto typeTypeEntry = mDebugTarget->mTargetBinary->FindType("System.Type", DbgLanguage_Beef);
|
||||||
if ((typeTypeEntry == NULL) || (typeTypeEntry->mValue == NULL))
|
if ((typeTypeEntry == NULL) || (typeTypeEntry->mValue == NULL))
|
||||||
return DbgTypedValue();
|
return DbgTypedValue();
|
||||||
|
@ -3433,9 +3436,11 @@ DbgTypedValue DbgExprEvaluator::LookupIdentifier(BfAstNode* identifierNode, bool
|
||||||
else if (findName == "$ThreadName")
|
else if (findName == "$ThreadName")
|
||||||
return GetString(mDebugger->mActiveThread->mName);
|
return GetString(mDebugger->mActiveThread->mName);
|
||||||
else if (findName == "$TargetName")
|
else if (findName == "$TargetName")
|
||||||
return GetString(GetFileName(mDebugTarget->mTargetBinary->mFilePath));
|
return GetString(GetFileName(mDebugTarget->mTargetPath));
|
||||||
|
else if (findName == "LaunchName")
|
||||||
|
return GetString(GetFileName(mDebugTarget->mLaunchBinary->mFilePath));
|
||||||
else if (findName == "$TargetPath")
|
else if (findName == "$TargetPath")
|
||||||
return GetString(mDebugTarget->mTargetBinary->mFilePath);
|
return GetString(mDebugTarget->mTargetPath);
|
||||||
else if (findName == "$ModuleName")
|
else if (findName == "$ModuleName")
|
||||||
return GetString(GetFileName(mDbgModule->mFilePath));
|
return GetString(GetFileName(mDbgModule->mFilePath));
|
||||||
else if (findName == "$ModulePath")
|
else if (findName == "$ModulePath")
|
||||||
|
|
|
@ -1923,8 +1923,6 @@ DbgModule::DbgModule(DebugTarget* debugTarget) : mDefaultCompileUnit(this)
|
||||||
mDebugRangesData = NULL;
|
mDebugRangesData = NULL;
|
||||||
mDebugAbbrevData = NULL;
|
mDebugAbbrevData = NULL;
|
||||||
mDebugStrData = NULL;
|
mDebugStrData = NULL;
|
||||||
mExceptionDirectoryData = NULL;
|
|
||||||
mExceptionDirectoryDataLen = 0;
|
|
||||||
mDebugAbbrevPtrData = NULL;
|
mDebugAbbrevPtrData = NULL;
|
||||||
mEHFrameData = NULL;
|
mEHFrameData = NULL;
|
||||||
mEHFrameAddress = 0;
|
mEHFrameAddress = 0;
|
||||||
|
@ -1986,7 +1984,8 @@ DbgModule::~DbgModule()
|
||||||
delete mDebugAbbrevData;
|
delete mDebugAbbrevData;
|
||||||
delete mDebugAbbrevPtrData;
|
delete mDebugAbbrevPtrData;
|
||||||
delete mDebugStrData;
|
delete mDebugStrData;
|
||||||
delete mExceptionDirectoryData;
|
for (auto entry : mExceptionDirectory)
|
||||||
|
delete entry.mData;
|
||||||
delete mEHFrameData;
|
delete mEHFrameData;
|
||||||
|
|
||||||
delete mOrigImageData;
|
delete mOrigImageData;
|
||||||
|
@ -2123,47 +2122,50 @@ void DbgModule::ParseAbbrevData(const uint8* data)
|
||||||
|
|
||||||
void DbgModule::ParseExceptionData()
|
void DbgModule::ParseExceptionData()
|
||||||
{
|
{
|
||||||
if (mExceptionDirectoryData == NULL)
|
if (mExceptionDirectory.IsEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BP_ZONE("DbgModule::ParseExceptionData");
|
BP_ZONE("DbgModule::ParseExceptionData");
|
||||||
|
|
||||||
const uint8* data = mExceptionDirectoryData;
|
for (auto entry : mExceptionDirectory)
|
||||||
const uint8* dataEnd = data + mExceptionDirectoryDataLen;
|
|
||||||
|
|
||||||
static int entryCount = 0;
|
|
||||||
|
|
||||||
addr_target imageBase = GetTargetImageBase();
|
|
||||||
|
|
||||||
while (data < dataEnd)
|
|
||||||
{
|
{
|
||||||
addr_target beginAddress = GET(uint32);
|
const uint8* data = entry.mData;
|
||||||
addr_target endAddress = GET(uint32);
|
const uint8* dataEnd = data + entry.mSize;
|
||||||
uint32 unwindData = GET(uint32);
|
|
||||||
|
|
||||||
//TODO: Apparently unwindData can refer to another runtime entry in the .pdata if the LSB is set to 1?
|
static int entryCount = 0;
|
||||||
|
|
||||||
beginAddress += (addr_target)imageBase;
|
addr_target imageBase = GetTargetImageBase();
|
||||||
endAddress += (addr_target)imageBase;
|
|
||||||
|
|
||||||
int exSize = (int)(endAddress - beginAddress);
|
while (data < dataEnd)
|
||||||
for (int exOffset = 0; true; exOffset += DBG_MAX_LOOKBACK)
|
|
||||||
{
|
{
|
||||||
int curSize = exSize - exOffset;
|
addr_target beginAddress = GET(uint32);
|
||||||
if (curSize <= 0)
|
addr_target endAddress = GET(uint32);
|
||||||
break;
|
uint32 unwindData = GET(uint32);
|
||||||
|
|
||||||
BP_ALLOC_T(DbgExceptionDirectoryEntry);
|
//TODO: Apparently unwindData can refer to another runtime entry in the .pdata if the LSB is set to 1?
|
||||||
DbgExceptionDirectoryEntry* exceptionDirectoryEntry = mAlloc.Alloc<DbgExceptionDirectoryEntry>();
|
|
||||||
|
|
||||||
exceptionDirectoryEntry->mAddress = beginAddress + exOffset;
|
beginAddress += (addr_target)imageBase;
|
||||||
exceptionDirectoryEntry->mOrigAddressOffset = exOffset;
|
endAddress += (addr_target)imageBase;
|
||||||
exceptionDirectoryEntry->mAddressLength = curSize;
|
|
||||||
exceptionDirectoryEntry->mExceptionPos = (int)unwindData;
|
|
||||||
exceptionDirectoryEntry->mDbgModule = this;
|
|
||||||
mDebugTarget->mExceptionDirectoryMap.Insert(exceptionDirectoryEntry);
|
|
||||||
|
|
||||||
entryCount++;
|
int exSize = (int)(endAddress - beginAddress);
|
||||||
|
for (int exOffset = 0; true; exOffset += DBG_MAX_LOOKBACK)
|
||||||
|
{
|
||||||
|
int curSize = exSize - exOffset;
|
||||||
|
if (curSize <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BP_ALLOC_T(DbgExceptionDirectoryEntry);
|
||||||
|
DbgExceptionDirectoryEntry* exceptionDirectoryEntry = mAlloc.Alloc<DbgExceptionDirectoryEntry>();
|
||||||
|
|
||||||
|
exceptionDirectoryEntry->mAddress = beginAddress + exOffset;
|
||||||
|
exceptionDirectoryEntry->mOrigAddressOffset = exOffset;
|
||||||
|
exceptionDirectoryEntry->mAddressLength = curSize;
|
||||||
|
exceptionDirectoryEntry->mExceptionPos = (int)unwindData;
|
||||||
|
exceptionDirectoryEntry->mDbgModule = this;
|
||||||
|
mDebugTarget->mExceptionDirectoryMap.Insert(exceptionDirectoryEntry);
|
||||||
|
|
||||||
|
entryCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5310,7 +5312,9 @@ bool DbgModule::ReadCOFF(DataStream* stream, bool isHotObjectFile)
|
||||||
targetSection->mNoTargetAlloc = true;
|
targetSection->mNoTargetAlloc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!mIsHotObjectFile) /*&& (!isUnwindSection)*/)
|
bool isExportDataDir = ((exportDataDir->mVirtualAddress != 0) && (exportDataDir->mVirtualAddress >= sectHdr.mVirtualAddress) && (exportDataDir->mVirtualAddress < sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData));
|
||||||
|
|
||||||
|
if ((!mIsHotObjectFile) && (!isExportDataDir))
|
||||||
{
|
{
|
||||||
if (((strcmp(name, ".text")) == 0) ||
|
if (((strcmp(name, ".text")) == 0) ||
|
||||||
((strcmp(name, ".textbss")) == 0) ||
|
((strcmp(name, ".textbss")) == 0) ||
|
||||||
|
@ -5341,7 +5345,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, bool isHotObjectFile)
|
||||||
targetSection->mData = data;
|
targetSection->mData = data;
|
||||||
|
|
||||||
addr_target addrOffset = sectHdr.mVirtualAddress;
|
addr_target addrOffset = sectHdr.mVirtualAddress;
|
||||||
if ((exportDataDir->mVirtualAddress != 0) && (exportDataDir->mVirtualAddress >= sectHdr.mVirtualAddress) && (exportDataDir->mVirtualAddress < sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData))
|
if (isExportDataDir)
|
||||||
{
|
{
|
||||||
BP_ZONE("DbgModule::ReadCOFF_SymbolMap");
|
BP_ZONE("DbgModule::ReadCOFF_SymbolMap");
|
||||||
|
|
||||||
|
@ -5566,8 +5570,10 @@ bool DbgModule::ReadCOFF(DataStream* stream, bool isHotObjectFile)
|
||||||
|
|
||||||
if (strcmp(name, ".pdata") == 0)
|
if (strcmp(name, ".pdata") == 0)
|
||||||
{
|
{
|
||||||
mExceptionDirectoryData = data;
|
DbgSectionData entry;
|
||||||
mExceptionDirectoryDataLen = sectHdr.mSizeOfRawData;
|
entry.mData = data;
|
||||||
|
entry.mSize = sectHdr.mSizeOfRawData;
|
||||||
|
mExceptionDirectory.Add(entry);
|
||||||
}
|
}
|
||||||
/*else if (strcmp(name, ".rdata") == 0)
|
/*else if (strcmp(name, ".rdata") == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -122,6 +122,12 @@ enum DbgFileExistKind : uint8
|
||||||
|
|
||||||
class DbgCompileUnit;
|
class DbgCompileUnit;
|
||||||
|
|
||||||
|
struct DbgSectionData
|
||||||
|
{
|
||||||
|
uint8* mData;
|
||||||
|
int mSize;
|
||||||
|
};
|
||||||
|
|
||||||
class DbgDebugData
|
class DbgDebugData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -1096,8 +1102,7 @@ public:
|
||||||
const uint8* mDebugAbbrevData;
|
const uint8* mDebugAbbrevData;
|
||||||
const uint8* mDebugStrData;
|
const uint8* mDebugStrData;
|
||||||
const uint8** mDebugAbbrevPtrData;
|
const uint8** mDebugAbbrevPtrData;
|
||||||
const uint8* mExceptionDirectoryData;
|
Array<DbgSectionData> mExceptionDirectory;
|
||||||
int mExceptionDirectoryDataLen;
|
|
||||||
const uint8* mEHFrameData;
|
const uint8* mEHFrameData;
|
||||||
const char* mStringTable;
|
const char* mStringTable;
|
||||||
const uint8* mSymbolData;
|
const uint8* mSymbolData;
|
||||||
|
|
|
@ -795,18 +795,18 @@ BF_EXPORT int BF_CALLTYPE Debugger_GetAddrSize()
|
||||||
return gDebugger->GetAddrSize();
|
return gDebugger->GetAddrSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_EXPORT bool BF_CALLTYPE Debugger_OpenFile(const char* fileName, const char* args, const char* workingDir, void* envBlockPtr, int envBlockSize)
|
BF_EXPORT bool BF_CALLTYPE Debugger_OpenFile(const char* launchPath, const char* targetPath, const char* args, const char* workingDir, void* envBlockPtr, int envBlockSize)
|
||||||
{
|
{
|
||||||
BF_ASSERT(gDebugger == NULL);
|
BF_ASSERT(gDebugger == NULL);
|
||||||
|
|
||||||
if (!FileExists(fileName))
|
if (!FileExists(launchPath))
|
||||||
{
|
{
|
||||||
gDebugManager->mOutMessages.push_back(StrFormat("error Unable to locate specified debug target '%s'", fileName));
|
gDebugManager->mOutMessages.push_back(StrFormat("error Unable to locate specified launch target '%s'", launchPath));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerResult debuggerResult = DebuggerResult_Ok;
|
DebuggerResult debuggerResult = DebuggerResult_Ok;
|
||||||
if ((gDebugManager->mDebugger64 != NULL) && (gDebugManager->mDebugger64->CanOpen(fileName, &debuggerResult)))
|
if ((gDebugManager->mDebugger64 != NULL) && (gDebugManager->mDebugger64->CanOpen(launchPath, &debuggerResult)))
|
||||||
gDebugger = gDebugManager->mDebugger64;
|
gDebugger = gDebugManager->mDebugger64;
|
||||||
else
|
else
|
||||||
gDebugger = gDebugManager->mDebugger32;
|
gDebugger = gDebugManager->mDebugger32;
|
||||||
|
@ -814,7 +814,7 @@ BF_EXPORT bool BF_CALLTYPE Debugger_OpenFile(const char* fileName, const char* a
|
||||||
if (gDebugger == NULL)
|
if (gDebugger == NULL)
|
||||||
{
|
{
|
||||||
if (debuggerResult == DebuggerResult_WrongBitSize)
|
if (debuggerResult == DebuggerResult_WrongBitSize)
|
||||||
gDebugManager->mOutMessages.push_back(StrFormat("error The file 32-bit file '%s' cannot be debugged because 32-bit debugger has been disabled", fileName));
|
gDebugManager->mOutMessages.push_back(StrFormat("error The file 32-bit file '%s' cannot be debugged because 32-bit debugger has been disabled", launchPath));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,7 +825,7 @@ BF_EXPORT bool BF_CALLTYPE Debugger_OpenFile(const char* fileName, const char* a
|
||||||
envBlock.Insert(0, (uint8*)envBlockPtr, envBlockSize);
|
envBlock.Insert(0, (uint8*)envBlockPtr, envBlockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
gDebugger->OpenFile(fileName, args, workingDir, envBlock);
|
gDebugger->OpenFile(launchPath, targetPath, args, workingDir, envBlock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ DebugTarget::DebugTarget(WinDebugger* debugger)
|
||||||
mBfObjectVDataIntefaceSlotCount = -1;
|
mBfObjectVDataIntefaceSlotCount = -1;
|
||||||
mBfObjectSize = -1;
|
mBfObjectSize = -1;
|
||||||
mDebugger = debugger;
|
mDebugger = debugger;
|
||||||
|
mLaunchBinary = NULL;
|
||||||
mTargetBinary = NULL;
|
mTargetBinary = NULL;
|
||||||
mCapturedNamesPtr = NULL;
|
mCapturedNamesPtr = NULL;
|
||||||
mCapturedTypesPtr = NULL;
|
mCapturedTypesPtr = NULL;
|
||||||
|
@ -50,31 +51,113 @@ DebugTarget::~DebugTarget()
|
||||||
mHotHeap = NULL;
|
mHotHeap = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgModule* DebugTarget::Init(const StringImpl& fileName, intptr imageBase)
|
static bool PathEquals(const String& pathA, String& pathB)
|
||||||
|
{
|
||||||
|
const char* ptrA = pathA.c_str();
|
||||||
|
const char* ptrB = pathB.c_str();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
char cA = *(ptrA++);
|
||||||
|
char cB = *(ptrB++);
|
||||||
|
|
||||||
|
if ((cA == 0) || (cB == 0))
|
||||||
|
{
|
||||||
|
return (cA == 0) && (cB == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cA = toupper((uint8)cA);
|
||||||
|
cB = toupper((uint8)cB);
|
||||||
|
if (cA == '\\')
|
||||||
|
cA = '/';
|
||||||
|
if (cB == '\\')
|
||||||
|
cB = '/';
|
||||||
|
if (cA != cB)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugTarget::SetupTargetBinary()
|
||||||
|
{
|
||||||
|
bool wantsHotHeap = mDebugger->mDbgProcessId == 0;
|
||||||
|
|
||||||
|
#ifdef BF_DBG_32
|
||||||
|
if (wantsHotHeap)
|
||||||
|
mHotHeap = new HotHeap();
|
||||||
|
#else
|
||||||
|
if (wantsHotHeap)
|
||||||
|
{
|
||||||
|
// 64-bit hot loaded code needs to be placed close to the original EXE so 32-bit relative
|
||||||
|
// offsets within the hot code can still reach the old code
|
||||||
|
addr_target checkHotReserveAddr = (addr_target)mTargetBinary->mImageBase + mTargetBinary->mImageSize;
|
||||||
|
int mb = 1024 * 1024;
|
||||||
|
int reserveSize = 512 * mb;
|
||||||
|
|
||||||
|
// Round up to MB boundary + 64MB, to help keep other DLLs at their preferred base addresses
|
||||||
|
checkHotReserveAddr = ((checkHotReserveAddr + 64 * mb) & ~(mb - 1));
|
||||||
|
|
||||||
|
checkHotReserveAddr = (addr_target)mTargetBinary->mImageBase;
|
||||||
|
|
||||||
|
addr_target reservedPtr = NULL;
|
||||||
|
while ((addr_target)checkHotReserveAddr < (addr_target)mTargetBinary->mImageBase + 0x30000000)
|
||||||
|
{
|
||||||
|
reservedPtr = (addr_target)VirtualAllocEx(mDebugger->mProcessInfo.hProcess, (void*)(intptr)checkHotReserveAddr, reserveSize, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
|
if (reservedPtr != NULL)
|
||||||
|
break;
|
||||||
|
checkHotReserveAddr += 4 * mb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reservedPtr != 0)
|
||||||
|
{
|
||||||
|
BF_ASSERT(mHotHeap == NULL);
|
||||||
|
mHotHeap = new HotHeap(reservedPtr, reserveSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Throw actual error if we can't reserve HOT area
|
||||||
|
BF_ASSERT(reservedPtr != NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugTarget::CheckTargetBinary(DbgModule* module)
|
||||||
|
{
|
||||||
|
if (mTargetBinary != NULL)
|
||||||
|
return;
|
||||||
|
if (!PathEquals(module->mFilePath, mTargetPath))
|
||||||
|
return;
|
||||||
|
mTargetBinary = module;
|
||||||
|
if (mTargetBinary != mLaunchBinary)
|
||||||
|
SetupTargetBinary();
|
||||||
|
}
|
||||||
|
|
||||||
|
DbgModule* DebugTarget::Init(const StringImpl& launchPath, const StringImpl& targetPath, intptr imageBase)
|
||||||
{
|
{
|
||||||
BP_ZONE("DebugTarget::Init");
|
BP_ZONE("DebugTarget::Init");
|
||||||
|
|
||||||
AutoDbgTime dbgTime("DebugTarget::Init " + fileName);
|
AutoDbgTime dbgTime("DebugTarget::Init Launch:" + launchPath + " Target:" + targetPath);
|
||||||
|
|
||||||
|
mTargetPath = targetPath;
|
||||||
FileStream fileStream;
|
FileStream fileStream;
|
||||||
fileStream.mFP = _wfopen(UTF8Decode(fileName).c_str(), L"rb");
|
fileStream.mFP = _wfopen(UTF8Decode(launchPath).c_str(), L"rb");
|
||||||
if (fileStream.mFP == NULL)
|
if (fileStream.mFP == NULL)
|
||||||
{
|
{
|
||||||
mDebugger->OutputMessage(StrFormat("Debugger failed to open binary: %s\n", fileName.c_str()));
|
mDebugger->OutputMessage(StrFormat("Debugger failed to open binary: %s\n", launchPath.c_str()));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgModule* dwarf = new COFF(this);
|
DbgModule* dwarf = new COFF(this);
|
||||||
mTargetBinary = dwarf;
|
mLaunchBinary = dwarf;
|
||||||
dwarf->mDisplayName = GetFileName(fileName);
|
dwarf->mDisplayName = GetFileName(launchPath);
|
||||||
dwarf->mFilePath = fileName;
|
dwarf->mFilePath = launchPath;
|
||||||
dwarf->mImageBase = (intptr)imageBase;
|
dwarf->mImageBase = (intptr)imageBase;
|
||||||
if (!dwarf->ReadCOFF(&fileStream, false))
|
if (!dwarf->ReadCOFF(&fileStream, false))
|
||||||
{
|
{
|
||||||
mDebugger->OutputMessage(StrFormat("Debugger failed to read binary: %s\n", fileName.c_str()));
|
mDebugger->OutputMessage(StrFormat("Debugger failed to read binary: %s\n", launchPath.c_str()));
|
||||||
delete dwarf;
|
delete dwarf;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
CheckTargetBinary(dwarf);
|
||||||
|
|
||||||
mDbgModules.push_back(dwarf);
|
mDbgModules.push_back(dwarf);
|
||||||
return dwarf;
|
return dwarf;
|
||||||
|
@ -85,6 +168,7 @@ void DebugTarget::CreateEmptyTarget()
|
||||||
auto emptyTarget = new DbgModule(this);
|
auto emptyTarget = new DbgModule(this);
|
||||||
mDbgModules.push_back(emptyTarget);
|
mDbgModules.push_back(emptyTarget);
|
||||||
mTargetBinary = emptyTarget;
|
mTargetBinary = emptyTarget;
|
||||||
|
mLaunchBinary = emptyTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgModule* DebugTarget::HotLoad(const StringImpl& fileName, int hotIdx)
|
DbgModule* DebugTarget::HotLoad(const StringImpl& fileName, int hotIdx)
|
||||||
|
@ -134,7 +218,7 @@ DbgModule* DebugTarget::SetupDyn(const StringImpl& filePath, DataStream* stream,
|
||||||
|
|
||||||
dwarf->mDisplayName = GetFileName(filePath);
|
dwarf->mDisplayName = GetFileName(filePath);
|
||||||
dwarf->mOrigImageData = new DbgModuleMemoryCache(dwarf->mImageBase, dwarf->mImageSize);
|
dwarf->mOrigImageData = new DbgModuleMemoryCache(dwarf->mImageBase, dwarf->mImageSize);
|
||||||
|
CheckTargetBinary(dwarf);
|
||||||
|
|
||||||
/*dbgModule->mOrigImageData = new uint8[dbgModule->mImageSize];
|
/*dbgModule->mOrigImageData = new uint8[dbgModule->mImageSize];
|
||||||
memset(dbgModule->mOrigImageData, 0xCC, dbgModule->mImageSize);
|
memset(dbgModule->mOrigImageData, 0xCC, dbgModule->mImageSize);
|
||||||
|
@ -163,6 +247,9 @@ String DebugTarget::UnloadDyn(addr_target imageBase)
|
||||||
RemoveTargetData();
|
RemoveTargetData();
|
||||||
filePath = dwarf->mFilePath;
|
filePath = dwarf->mFilePath;
|
||||||
|
|
||||||
|
if (mTargetBinary == dwarf)
|
||||||
|
mTargetBinary = NULL;
|
||||||
|
|
||||||
delete dwarf;
|
delete dwarf;
|
||||||
mDbgModules.erase(mDbgModules.begin() + i);
|
mDbgModules.erase(mDbgModules.begin() + i);
|
||||||
return filePath;
|
return filePath;
|
||||||
|
@ -801,7 +888,10 @@ void DebugTarget::GetCompilerSettings()
|
||||||
{
|
{
|
||||||
if (!mCheckedCompilerSettings)
|
if (!mCheckedCompilerSettings)
|
||||||
{
|
{
|
||||||
DbgType* bfObjectType = GetMainDbgModule()->FindType("System.CompilerSettings", NULL, DbgLanguage_Beef);
|
auto dbgModule = GetMainDbgModule();
|
||||||
|
if (dbgModule == NULL)
|
||||||
|
return;
|
||||||
|
DbgType* bfObjectType = dbgModule->FindType("System.CompilerSettings", NULL, DbgLanguage_Beef);
|
||||||
if (bfObjectType != NULL)
|
if (bfObjectType != NULL)
|
||||||
{
|
{
|
||||||
bfObjectType->PopulateType();
|
bfObjectType->PopulateType();
|
||||||
|
|
|
@ -35,7 +35,10 @@ public:
|
||||||
|
|
||||||
HotHeap* mHotHeap;
|
HotHeap* mHotHeap;
|
||||||
int mLastHotHeapCleanIdx;
|
int mLastHotHeapCleanIdx;
|
||||||
|
String mTargetPath;
|
||||||
|
DbgModule* mLaunchBinary;
|
||||||
DbgModule* mTargetBinary;
|
DbgModule* mTargetBinary;
|
||||||
|
//DbgModule* m
|
||||||
Array<DbgModule*> mDbgModules;
|
Array<DbgModule*> mDbgModules;
|
||||||
//DbgModule* mLastDWARF;
|
//DbgModule* mLastDWARF;
|
||||||
HashSet<DbgSrcFile*> mPendingSrcFileRehup; // Waiting to remove old/invalid line info
|
HashSet<DbgSrcFile*> mPendingSrcFileRehup; // Waiting to remove old/invalid line info
|
||||||
|
@ -70,7 +73,9 @@ public:
|
||||||
DebugTarget(WinDebugger* debugger);
|
DebugTarget(WinDebugger* debugger);
|
||||||
~DebugTarget();
|
~DebugTarget();
|
||||||
|
|
||||||
DbgModule* Init(const StringImpl& fileName, intptr imageBase = 0);
|
DbgModule* Init(const StringImpl& launchPath, const StringImpl& targetPath, intptr imageBase = 0);
|
||||||
|
void SetupTargetBinary();
|
||||||
|
void CheckTargetBinary(DbgModule* module);
|
||||||
void CreateEmptyTarget();
|
void CreateEmptyTarget();
|
||||||
DbgModule* HotLoad(const StringImpl& fileName, int hotIdx);
|
DbgModule* HotLoad(const StringImpl& fileName, int hotIdx);
|
||||||
DbgModule* SetupDyn(const StringImpl& filePath, DataStream* stream, intptr imageBase);
|
DbgModule* SetupDyn(const StringImpl& filePath, DataStream* stream, intptr imageBase);
|
||||||
|
|
|
@ -230,7 +230,7 @@ public:
|
||||||
virtual void OutputRawMessage(const StringImpl& msg) = 0;
|
virtual void OutputRawMessage(const StringImpl& msg) = 0;
|
||||||
virtual int GetAddrSize() = 0;
|
virtual int GetAddrSize() = 0;
|
||||||
virtual bool CanOpen(const StringImpl& fileName, DebuggerResult* outResult) = 0;
|
virtual bool CanOpen(const StringImpl& fileName, DebuggerResult* outResult) = 0;
|
||||||
virtual void OpenFile(const StringImpl& fileName, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock) = 0;
|
virtual void OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock) = 0;
|
||||||
virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) = 0;
|
virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) = 0;
|
||||||
virtual void Run() = 0;
|
virtual void Run() = 0;
|
||||||
virtual void HotLoad(const Array<String>& objectFiles, int hotIdx) = 0;
|
virtual void HotLoad(const Array<String>& objectFiles, int hotIdx) = 0;
|
||||||
|
|
|
@ -44,7 +44,10 @@ MiniDumpDebugger::MiniDumpDebugger(DebugManager* debugManager, DbgMiniDump* mini
|
||||||
auto& module = moduleList.Modules[moduleIdx];
|
auto& module = moduleList.Modules[moduleIdx];
|
||||||
COFF* dbgModule = new COFF(mDebugTarget);
|
COFF* dbgModule = new COFF(mDebugTarget);
|
||||||
if (mDebugTarget->mTargetBinary == NULL)
|
if (mDebugTarget->mTargetBinary == NULL)
|
||||||
|
{
|
||||||
|
mDebugTarget->mLaunchBinary = dbgModule;
|
||||||
mDebugTarget->mTargetBinary = dbgModule;
|
mDebugTarget->mTargetBinary = dbgModule;
|
||||||
|
}
|
||||||
dbgModule->mImageBase = module.BaseOfImage;
|
dbgModule->mImageBase = module.BaseOfImage;
|
||||||
dbgModule->mImageSize = module.SizeOfImage;
|
dbgModule->mImageSize = module.SizeOfImage;
|
||||||
|
|
||||||
|
|
|
@ -879,12 +879,12 @@ void WinDebugger::DebugThreadProc()
|
||||||
|
|
||||||
if (!IsMiniDumpDebugger())
|
if (!IsMiniDumpDebugger())
|
||||||
{
|
{
|
||||||
if (!DoOpenFile(mFileName, mArgs, mWorkingDir, mEnvBlock))
|
if (!DoOpenFile(mLaunchPath, mArgs, mWorkingDir, mEnvBlock))
|
||||||
{
|
{
|
||||||
if (mDbgProcessId != 0)
|
if (mDbgProcessId != 0)
|
||||||
OutputRawMessage("error Unable to attach to process");
|
OutputRawMessage("error Unable to attach to process");
|
||||||
else
|
else
|
||||||
OutputRawMessage(StrFormat("error Failed to launch: %s", mFileName.c_str()));
|
OutputRawMessage(StrFormat("error Failed to launch: %s", mLaunchPath.c_str()));
|
||||||
mShuttingDown = true;
|
mShuttingDown = true;
|
||||||
mRunState = RunState_Terminated;
|
mRunState = RunState_Terminated;
|
||||||
}
|
}
|
||||||
|
@ -960,10 +960,11 @@ bool WinDebugger::CanOpen(const StringImpl& fileName, DebuggerResult* outResult)
|
||||||
return canRead;
|
return canRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinDebugger::OpenFile(const StringImpl& fileName, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock)
|
void WinDebugger::OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock)
|
||||||
{
|
{
|
||||||
BF_ASSERT(!mIsRunning);
|
BF_ASSERT(!mIsRunning);
|
||||||
mFileName = fileName;
|
mLaunchPath = launchPath;
|
||||||
|
mTargetPath = targetPath;
|
||||||
mArgs = args;
|
mArgs = args;
|
||||||
mWorkingDir = workingDir;
|
mWorkingDir = workingDir;
|
||||||
mEnvBlock = envBlock;
|
mEnvBlock = envBlock;
|
||||||
|
@ -1000,7 +1001,8 @@ bool WinDebugger::Attach(int processId, BfDbgAttachFlags attachFlags)
|
||||||
|
|
||||||
WCHAR fileName[MAX_PATH] = {0};
|
WCHAR fileName[MAX_PATH] = {0};
|
||||||
GetModuleFileNameExW(mDbgProcessHandle, mainModule, fileName, MAX_PATH);
|
GetModuleFileNameExW(mDbgProcessHandle, mainModule, fileName, MAX_PATH);
|
||||||
mFileName = UTF8Encode(fileName);
|
mLaunchPath = UTF8Encode(fileName);
|
||||||
|
mTargetPath = mLaunchPath;
|
||||||
|
|
||||||
mDbgProcessId = processId;
|
mDbgProcessId = processId;
|
||||||
mDbgProcessHandle = 0;
|
mDbgProcessHandle = 0;
|
||||||
|
@ -1209,7 +1211,7 @@ bool WinDebugger::DoOpenFile(const StringImpl& fileName, const StringImpl& args,
|
||||||
|
|
||||||
ContinueDebugEvent();
|
ContinueDebugEvent();
|
||||||
|
|
||||||
if ((mDebugTarget->mTargetBinary != NULL) && (mDebugTarget->mTargetBinary->mOrigImageData != NULL))
|
if ((mDebugTarget->mLaunchBinary != NULL) && (mDebugTarget->mLaunchBinary->mOrigImageData != NULL))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1534,55 +1536,19 @@ bool WinDebugger::DoUpdate()
|
||||||
BF_GetThreadContext(threadInfo->mHThread, &lcContext);
|
BF_GetThreadContext(threadInfo->mHThread, &lcContext);
|
||||||
threadInfo->mStartSP = BF_CONTEXT_SP(lcContext);
|
threadInfo->mStartSP = BF_CONTEXT_SP(lcContext);
|
||||||
|
|
||||||
DbgModule* targetBinary = mDebugTarget->Init(mFileName, (addr_target)(intptr)mDebugEvent.u.CreateProcessInfo.lpBaseOfImage);
|
DbgModule* launchBinary = mDebugTarget->Init(mLaunchPath, mTargetPath, (addr_target)(intptr)mDebugEvent.u.CreateProcessInfo.lpBaseOfImage);
|
||||||
addr_target gotImageBase = (addr_target)(intptr)mDebugEvent.u.CreateProcessInfo.lpBaseOfImage;
|
addr_target gotImageBase = (addr_target)(intptr)mDebugEvent.u.CreateProcessInfo.lpBaseOfImage;
|
||||||
if (targetBinary->mImageBase != gotImageBase)
|
if (launchBinary->mImageBase != gotImageBase)
|
||||||
{
|
{
|
||||||
BF_FATAL("Image base didn't match");
|
BF_FATAL("Image base didn't match");
|
||||||
}
|
}
|
||||||
|
|
||||||
targetBinary->mImageBase = gotImageBase;
|
launchBinary->mImageBase = gotImageBase;
|
||||||
targetBinary->mImageSize = (int)targetBinary->GetImageSize();
|
launchBinary->mImageSize = (int)launchBinary->GetImageSize();
|
||||||
targetBinary->mOrigImageData = new DbgModuleMemoryCache(targetBinary->mImageBase, targetBinary->mImageSize);
|
launchBinary->mOrigImageData = new DbgModuleMemoryCache(launchBinary->mImageBase, launchBinary->mImageSize);
|
||||||
|
|
||||||
bool wantsHotHeap = mDbgProcessId == 0;
|
if (launchBinary == mDebugTarget->mTargetBinary)
|
||||||
|
mDebugTarget->SetupTargetBinary();
|
||||||
#ifdef BF_DBG_32
|
|
||||||
if (wantsHotHeap)
|
|
||||||
mDebugTarget->mHotHeap = new HotHeap();
|
|
||||||
#else
|
|
||||||
if (wantsHotHeap)
|
|
||||||
{
|
|
||||||
// 64-bit hot loaded code needs to be placed close to the original EXE so 32-bit relative
|
|
||||||
// offsets within the hot code can still reach the old code
|
|
||||||
addr_target checkHotReserveAddr = (addr_target)targetBinary->mImageBase + targetBinary->mImageSize;
|
|
||||||
int mb = 1024 * 1024;
|
|
||||||
int reserveSize = 512 * mb;
|
|
||||||
|
|
||||||
// Round up to MB boundary + 64MB, to help keep other DLLs at their preferred base addresses
|
|
||||||
checkHotReserveAddr = ((checkHotReserveAddr + 64 * mb) & ~(mb - 1));
|
|
||||||
|
|
||||||
checkHotReserveAddr = (addr_target)targetBinary->mImageBase;
|
|
||||||
|
|
||||||
addr_target reservedPtr = NULL;
|
|
||||||
while ((addr_target)checkHotReserveAddr < (addr_target)targetBinary->mImageBase + 0x30000000)
|
|
||||||
{
|
|
||||||
reservedPtr = (addr_target)VirtualAllocEx(mProcessInfo.hProcess, (void*)(intptr)checkHotReserveAddr, reserveSize, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
|
||||||
if (reservedPtr != NULL)
|
|
||||||
break;
|
|
||||||
checkHotReserveAddr += 4 * mb;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reservedPtr != 0)
|
|
||||||
{
|
|
||||||
BF_ASSERT(mDebugTarget->mHotHeap == NULL);
|
|
||||||
mDebugTarget->mHotHeap = new HotHeap(reservedPtr, reserveSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Throw actual error if we can't reserve HOT area
|
|
||||||
BF_ASSERT(reservedPtr != NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mDebugEvent.u.CreateProcessInfo.hFile != NULL)
|
if (mDebugEvent.u.CreateProcessInfo.hFile != NULL)
|
||||||
CloseHandle(mDebugEvent.u.CreateProcessInfo.hFile);
|
CloseHandle(mDebugEvent.u.CreateProcessInfo.hFile);
|
||||||
|
@ -3225,7 +3191,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint)
|
||||||
{
|
{
|
||||||
if (symbolName == ".")
|
if (symbolName == ".")
|
||||||
{
|
{
|
||||||
targetAddr = mDebugTarget->mTargetBinary->mImageBase + mDebugTarget->mTargetBinary->mEntryPoint;
|
targetAddr = mDebugTarget->mLaunchBinary->mImageBase + mDebugTarget->mLaunchBinary->mEntryPoint;
|
||||||
onlyBindFirst = true;
|
onlyBindFirst = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4559,8 +4525,12 @@ void WinDebugger::CheckNonDebuggerBreak()
|
||||||
PopulateRegisters(®isters);
|
PopulateRegisters(®isters);
|
||||||
addr_target pcAddress = registers.GetPC();
|
addr_target pcAddress = registers.GetPC();
|
||||||
|
|
||||||
mDebugTarget->mTargetBinary->ParseSymbolData();
|
addr_target debugMessageDataAddr = (addr_target)-1;
|
||||||
addr_target debugMessageDataAddr = mDebugTarget->FindSymbolAddr("gBfDebugMessageData");
|
if (mDebugTarget->mTargetBinary != NULL)
|
||||||
|
{
|
||||||
|
mDebugTarget->mTargetBinary->ParseSymbolData();
|
||||||
|
debugMessageDataAddr = mDebugTarget->FindSymbolAddr("gBfDebugMessageData");
|
||||||
|
}
|
||||||
if (debugMessageDataAddr != (addr_target)-1)
|
if (debugMessageDataAddr != (addr_target)-1)
|
||||||
{
|
{
|
||||||
struct BfDebugMessageData
|
struct BfDebugMessageData
|
||||||
|
@ -4684,7 +4654,7 @@ void WinDebugger::CheckNonDebuggerBreak()
|
||||||
DbgModule* dbgModule;
|
DbgModule* dbgModule;
|
||||||
if (mDebugTarget->FindSymbolAt(pcAddress, &symbol, &offset, &dbgModule))
|
if (mDebugTarget->FindSymbolAt(pcAddress, &symbol, &offset, &dbgModule))
|
||||||
{
|
{
|
||||||
if (symbol == "DbgBreakPoint")
|
if ((symbol == "DbgBreakPoint") || (symbol == "RtlUserThreadStart@8"))
|
||||||
{
|
{
|
||||||
showMainThread = true;
|
showMainThread = true;
|
||||||
}
|
}
|
||||||
|
@ -8864,10 +8834,13 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dbgModule = GetCallStackDbgModule(pendingExpr->mCallStackIdx);
|
dbgModule = GetCallStackDbgModule(pendingExpr->mCallStackIdx);
|
||||||
if (!dbgModule->mDebugTarget->mIsEmpty)
|
if ((dbgModule != NULL) &&(!dbgModule->mDebugTarget->mIsEmpty))
|
||||||
dbgCompileUnit = GetCallStackCompileUnit(pendingExpr->mCallStackIdx);
|
dbgCompileUnit = GetCallStackCompileUnit(pendingExpr->mCallStackIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dbgModule == NULL)
|
||||||
|
dbgModule = mEmptyDebugTarget->GetMainDbgModule();
|
||||||
|
|
||||||
if (!pendingExpr->mException.empty())
|
if (!pendingExpr->mException.empty())
|
||||||
{
|
{
|
||||||
RestoreAllRegisters();
|
RestoreAllRegisters();
|
||||||
|
@ -10147,7 +10120,8 @@ String WinDebugger::GetThreadInfo()
|
||||||
|
|
||||||
if ((mActiveThread == mExplicitStopThread) && (mActiveBreakpoint != NULL))
|
if ((mActiveThread == mExplicitStopThread) && (mActiveBreakpoint != NULL))
|
||||||
{
|
{
|
||||||
if ((mActiveBreakpoint->mAddr < subProgram->mBlock.mLowPC) ||
|
if ((subProgram == NULL) ||
|
||||||
|
(mActiveBreakpoint->mAddr < subProgram->mBlock.mLowPC) ||
|
||||||
(mActiveBreakpoint->mAddr >= subProgram->mBlock.mHighPC))
|
(mActiveBreakpoint->mAddr >= subProgram->mBlock.mHighPC))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,7 +369,8 @@ public:
|
||||||
volatile bool mShuttingDown;
|
volatile bool mShuttingDown;
|
||||||
volatile bool mIsRunning;
|
volatile bool mIsRunning;
|
||||||
bool mDestroying;
|
bool mDestroying;
|
||||||
String mFileName;
|
String mLaunchPath;
|
||||||
|
String mTargetPath;
|
||||||
String mArgs;
|
String mArgs;
|
||||||
String mWorkingDir;
|
String mWorkingDir;
|
||||||
Array<uint8> mEnvBlock;
|
Array<uint8> mEnvBlock;
|
||||||
|
@ -558,7 +559,7 @@ public:
|
||||||
virtual void OutputRawMessage(const StringImpl& msg) override;
|
virtual void OutputRawMessage(const StringImpl& msg) override;
|
||||||
virtual int GetAddrSize() override;
|
virtual int GetAddrSize() override;
|
||||||
virtual bool CanOpen(const StringImpl& fileName, DebuggerResult* outResult) override;
|
virtual bool CanOpen(const StringImpl& fileName, DebuggerResult* outResult) override;
|
||||||
virtual void OpenFile(const StringImpl& fileName, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock) override;
|
virtual void OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock) override;
|
||||||
virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) override;
|
virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) override;
|
||||||
virtual void Run() override;
|
virtual void Run() override;
|
||||||
virtual void HotLoad(const Array<String>& objectFiles, int hotIdx) override;
|
virtual void HotLoad(const Array<String>& objectFiles, int hotIdx) override;
|
||||||
|
|
|
@ -19,6 +19,10 @@ PUSHD %~dp0..\
|
||||||
@CALL :TEST
|
@CALL :TEST
|
||||||
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||||
|
|
||||||
|
@SET TESTPATH=IDE\Tests\TestDynCrt1
|
||||||
|
@CALL :TEST
|
||||||
|
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||||
|
|
||||||
@SET TESTPATH=IDE\Tests\SlotTest
|
@SET TESTPATH=IDE\Tests\SlotTest
|
||||||
@CALL :TEST
|
@CALL :TEST
|
||||||
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue