-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x64 Configurations (implements #284) #289
Conversation
Some things got messed up from the rebase. Make this file match RetroAchievements. Rebase and pulling didn't work. complete rebase Some things got messed up from the rebase. complete rebase Some things got messed up from the rebase. complete rebase Rebase again.
Because this is a big change I'm gonna mark it WIP until it's been tested and recommend on not merging until after release. |
Thanks for working on it. Oricutron has a 64-bit configuration, but because of #287 RAOricutron is probably not a good target for testing this yet unless setting up a config compiling against SDL2. |
I just went ahead and rolled back to SDL2 for |
Alright, I'll probably do that after work or something. |
@rzumer I can't seem to get it to build. The Edit: How'd you get it to build? |
@SyrianBallaS I think you are missing the |
recloning worked. |
@rzumer I'm not sure if I'm doing this wrong but Oricutron has memory leaks. I don't think it's been debuged before either because I keep on getting errors from SDL running it without debugging |
This should only appear when performing operations like quitting or changing renderers or machines while debugging, and the application still functions despite them. Just ignore them. Personally I am not interested in fixing all the bugs in the emulators I am working with, but if you want to raise this issue in the upstream |
I can't even get it to run in a Win32 configuration with the released version of the toolkit. I'll need to know more requirements. |
Right, you will need to merge in my branch from #288 and recompile Also make sure that
I am not sure what you mean by that. |
I'm not sure if I can pull in PRs from other repos but I'll try. I'm used to working in branches at work and other collab but for RA stuff I had to fork. |
Yeah I don't think I can pull in a |
Not branch I meant PR. |
bi.pszDisplayName = pDisplayName.get(); | ||
#else | ||
#error Unknown Character Set! | ||
#endif /* _MBCS */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't the whole point of TCHAR to avoid things like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RA_MAX_PATH
has a different value for Unicode, 32,767 characters, which is too big for the stack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has nothing to do with TCHAR
src/RA_Dlg_Memory.cpp
Outdated
unsigned int MemoryViewerControl::m_nEditNibble = 0; | ||
bool MemoryViewerControl::m_bHasCaret = 0; | ||
unsigned int MemoryViewerControl::m_nCaretWidth = 0; | ||
unsigned int MemoryViewerControl::m_nCaretHeight = 0; | ||
unsigned int MemoryViewerControl::m_nDisplayedLines = 8; | ||
unsigned short MemoryViewerControl::m_nActiveMemBank = 0; | ||
|
||
unsigned int m_nPage = 0; | ||
std::size_t m_nPage = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you explain why you use gsl::index
in some places and size_t
in others?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 64-bit based architectures (usually still varies a bit by micro), a user-mode application can't index past PTRDIFF_MAX
. The result of pointer math is also ptrdiff_t
. gsl::index
is an alias of ptrdiff_t
(which is either int
or long long
depending on the platform). I wasn't sure if this was supposed to be an index or not. It was already unsigned, because of truncation it needed to be different but still preserve the type for x86/Win32.
src/RA_LeaderboardPopup.cpp
Outdated
@@ -171,12 +169,14 @@ _Use_decl_annotations_ void LeaderboardPopup::Render(ra::ui::drawing::ISurface& | |||
if (!pConfiguration.IsFeatureEnabled(ra::services::Feature::LeaderboardCounters)) | |||
break; | |||
|
|||
const auto& pSurfaceFactory = ra::services::ServiceLocator::Get<ra::ui::drawing::ISurfaceFactory>(); | |||
using default_isurfacefactory_t = ra::ui::drawing::ISurfaceFactory; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this alias is undesirable. it's barely shorted, and abstracts the usage in the lookup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I must have forgotten to get rid of it. I was originally trying to make the class a class template that accepted any integral type for the dimensions.
src/RA_LeaderboardPopup.cpp
Outdated
@@ -263,8 +266,8 @@ _Use_decl_annotations_ void LeaderboardPopup::Render(ra::ui::drawing::ISurface& | |||
|
|||
const auto sScore = ra::Widen(pLB->FormatScore(lbInfo.m_nScore)); | |||
const auto szScore = m_pScoreboardSurface->MeasureText(nFontText, sScore); | |||
m_pScoreboardSurface->WriteText(m_pScoreboardSurface->GetWidth() - 4 - szScore.Width - 8, nY, | |||
nFontText, nTextColor, sScore); | |||
const auto nX = gsl::narrow_cast<int>(m_pScoreboardSurface->GetWidth()) - 4 - szScore.Width - 8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should use iWidth
too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I guess iWidth
should be nWidth
as well.
src/RA_LeaderboardPopup.cpp
Outdated
m_pScoreboardSurface->FillRectangle(0, 0, m_pScoreboardSurface->GetWidth() - nShadowOffset, | ||
m_pScoreboardSurface->GetHeight() - nShadowOffset, | ||
const auto iWidth = gsl::narrow_cast<int>(m_pScoreboardSurface->GetWidth()); | ||
const auto iHeight = gsl::narrow_cast<int>(m_pScoreboardSurface->GetHeight()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggest nWidth
and nHeight
. I don't think we use i
as a prefix anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure
src/ui/drawing/ISurface.hh
Outdated
@@ -23,12 +23,12 @@ public: | |||
/// <summary> | |||
/// Gets the width of the surface. | |||
/// </summary> | |||
virtual size_t GetWidth() const = 0; | |||
virtual std::ptrdiff_t GetWidth() const = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not size_t
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because size_t is not an appropriate type for dimensions or coordinates. Plus in all derived classes, the dimensions are signed.
|
||
void Blend(HDC hTargetDC, int nX, int nY) const; | ||
void Blend(HDC hTargetDC, std::ptrdiff_t nX, std::ptrdiff_t nY) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nX
and nY
should have a consistent data type. you've changed this to ptrdiff_t
, but not FillRectangle
or WriteText
(probably others).
is there a better type for coordinates? there's no pointers involved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's intptr_t
, or should we just make a Point
structure? Or maybe alias Point from Position in types.hh. It does make sense to use to use int, I'll see if I can do that without narrowing, I do think pairs can abstracted.
using Point = Position;
{ | ||
auto nWidth32 = gsl::narrow_cast<std::uint32_t>(nWidth); | ||
auto nHeight32 = gsl::narrow_cast<std::uint32_t>(nHeight); | ||
hr = pOriginalBitmapSource->GetSize(&nWidth32, &nHeight32); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetSize
parameters are both out. the conversion should be from nWidth32
to nWidth
, not the other way around. this code is attempting to determine the width if it's not already known.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
size_t
is unsigned long long
in x64, so for GetSize
, should we just make the returns for GetHeight
and GetWidth
int/unsigned int
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't understand. The point of calling GetSize is to set nWidth and nHeight. You've changed the code to pass in values and ignore the changes, so on line 339 below, nWidth and nHeight will both still be 0!
https://docs.microsoft.com/en-us/windows/desktop/api/wincodec/nf-wincodec-iwicbitmapsource-getsize
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK I got you.
tests/Exports_Tests.cpp
Outdated
@@ -244,7 +244,7 @@ TEST_CLASS(Exports_Tests) | |||
Assert::IsFalse(mockUserContext.IsLoggedIn()); | |||
Assert::AreEqual(std::string(""), mockUserContext.GetUsername()); | |||
Assert::AreEqual(std::string(""), mockUserContext.GetApiToken()); | |||
Assert::AreEqual(0U, mockUserContext.GetScore()); | |||
Assert::AreEqual({0U}, mockUserContext.GetScore()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To preserve the x86/Win32 version. GetScore
return size_t
, but U
is a literal for unsigned int
, there exists no literal for size_t
. If the braces aren't there it won't compile. This is the only way as-is to do it without a user-defined literal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetScore
returns unsigned int
, and I don't see anything in this PR that changes that.
…ration into x64_config # Conflicts: # src/data/GameContext.cpp
They have to be enabled by project in configuration manager.
Upon inspection, m_nPage seems to be used in indexing so it was made gsl::index.
src/RA_Dlg_Memory.h
Outdated
ComparisonType m_nCompareType = ComparisonType::Equals; | ||
std::vector<ra::ByteAddress> m_modifiedAddresses; | ||
bool m_bUseLastValue{}; | ||
ra::ByteAddress m_nLastQueryVal{}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't an address, it's a 32-bit search value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it's a bit confusing when ra::ByteAddress
is assigned to it. It'll change back.
src/pch.h
Outdated
@@ -39,6 +39,7 @@ | |||
/* STL Stuff */ | |||
#include <array> // algorithm, iterator, tuple | |||
#include <atomic> | |||
#include <filesystem> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be in pch.h, it's only used by one line currently, and that will eventually get replaced with a call to IFileSystem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got you, I have a different branch that uses standard api instead of Windows api. I guess this should go in IFileSystem implementations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Standard filesystem api works on Windows, Linux, and Mac. Sure it's not the only thing that make this portable but it's start.
src/ui/Types.hh
Outdated
[[nodiscard]] inline operator LPSIZE() const noexcept | ||
{ | ||
static SIZE sz{Width, Height}; | ||
return &sz; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not threadsafe, and since you're defining an implicit conversion, it'll be very difficult to track down should it become a problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I'll get rid of this. For the SIZE
one I'll add explicit
to force a static_cast
.
src/ui/drawing/ISurface.hh
Outdated
/// <param name="pImage">The surface to draw.</param> | ||
virtual void DrawSurface(int nX, int nY, const ISurface& pSurface) = 0; | ||
virtual void DrawSurface(const Point& nXY, const ISurface& pSurface) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this changes is causing compilation errors:
3>e:\source\raintegration\src\ui\viewmodels\overlaymanager.cpp(64): error C2660: 'ra::ui::drawing::ISurface::DrawSurface': function does not take 3 arguments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't looked at this in awhile, built fine last time I did but the code did change.
src/ui/drawing/ISurface.hh
Outdated
|
||
/// <summary> | ||
/// Creates a new offscren surface with an alpha channel. | ||
/// </summary> | ||
virtual std::unique_ptr<ISurface> CreateTransparentSurface(int nWidth, int nHeight) const = 0; | ||
virtual std::unique_ptr<ISurface> CreateTransparentSurface(const Size& nWH) const = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the justification for these changes? The methods were fine the way they were. Now you're creating new temporary objects to pass data by reference that previously would have just been pushed onto the stack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was to reduce number of parameters needed. Not a big deal. If you want they could be just passed by value because they are literal types.
To save headache I'll just put it back.
tests/data/EmulatorContext_Tests.cpp
Outdated
@@ -386,7 +386,7 @@ TEST_CLASS(EmulatorContext_Tests) | |||
emulator.mockServer.HandleRequest<ra::api::FetchUserUnlocks>([&bUnlocksRequested](const ra::api::FetchUserUnlocks::Request& request, ra::api::FetchUserUnlocks::Response& response) | |||
{ | |||
bUnlocksRequested = true; | |||
Assert::AreEqual(1U, request.GameId); | |||
Assert::AreEqual({1U}, request.GameId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GameId
is an unsigned int.
tests/data/GameContext_Tests.cpp
Outdated
@@ -192,7 +192,7 @@ TEST_CLASS(GameContext_Tests) | |||
Assert::AreEqual(5, pAch2->Category()); | |||
Assert::AreEqual(1234567890, (int)pAch2->CreatedDate()); | |||
Assert::AreEqual(1234599999, (int)pAch2->ModifiedDate()); | |||
Assert::AreEqual(15U, pAch2->Points()); | |||
Assert::AreEqual({15U}, pAch2->Points()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Points
returns an unsigned int
tests/data/GameContext_Tests.cpp
Outdated
Assert::AreEqual(std::string("1=1"), pAch->CreateMemString()); | ||
|
||
// new achievement should be allocated an ID higher than the largest existing local | ||
// ID, even if intermediate values are available | ||
const auto& pAch2 = game.NewAchievement(AchievementSet::Type::Local); | ||
Assert::AreEqual(999000004U, pAch2.ID()); | ||
Assert::AreEqual({999000004U}, pAch2.ID()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ID is an AchievementId, which is a unit32_t
src/base.props
Outdated
<OutDir>$(SolutionDir)bin\$(Configuration)\</OutDir> | ||
<IntDir>$(SolutionDir)obj\$(Configuration)\</IntDir> | ||
<OutDir>$(SolutionDir)bin\$(Configuration)\$(Platform)\$(ProjectName)\</OutDir> | ||
<IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many of the projects override these, so they don't have any effect. Building Win32 debug creates a Win32\RAIntegration folder, but tests and rcheevos still end up at the top level.
And frankly, I prefer that structure. The dll should be at the top level, with the tests and rcheevos files in subdirectories. I'm fine with adding the
src/services/SearchResults.cpp
Outdated
for (auto& block : m_vBlocks) | ||
nCount += block.GetSize() - nPadding; | ||
|
||
if (m_nSize == MemSize::Nibble_Lower) | ||
nCount *= 2; | ||
|
||
return nCount; | ||
return {nCount}; // NB: The braces are required |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment doesn't explain any of that, and as such, is not a very good comment.
I was unable to generate the error you describe. It did not appear in either the Win32 or x64 builds of the Debug or Analysis projects. There were two warnings that only appeared in the Win32 builds that should be addressed:
1>e:\source\raintegration\src\ra_achievementoverlay.cpp(837): warning C4018: '<': signed/unsigned mismatch
1>e:\source\raintegration\src\ra_core.cpp(1093): warning C4244: 'argument': conversion from 'std::streamsize' to 'size_t', possible loss of data
And one warning that only appeared in the x64 builds:
1>e:\source\raintegration\src\ra_dlg_acheditor.cpp(1750): warning C4267: '=': conversion from 'size_t' to 'unsigned int', possible loss of data
…ration into x64_config # Conflicts: # src/ui/drawing/gdi/GDIBitmapSurface.cpp # src/ui/drawing/gdi/GDIBitmapSurface.hh
rcheevos isn't updating for some strange reason
I think this is ready, unless I missed a few things. Edit: Win32 build works like normal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please test your changes. I can't load this DLL in any emulator (32-bit debug build), as it throws a "Write access violation" trying to draw the "Welcome back" popup.
I'll reopen this later |
The unit tests pass in all configurations but we need a 64-bit build of an RA Emulator to test with this.
Breakdown
std::ptrdiff_t
,std::intptr_t
, orgsl::index
(they are all the same, they are just aliases of the same type)long long
instead of justint
).