• Content count

  • Joined

  • Last visited

Community Reputation

1163 Excellent

About Finalspace

  • Rank

Personal Information


  • Github
  1. This thread is for annoncing new releases only, so its appreciated to create a seperate thread for discussions. But thanks for the tip with the releases, i will try to do that. Seems i have forget about that entirely, since i am using another version control system at work... What do you mean with warning level 3 instead of 4? (Visual Studio Project configuration?)
  2. Update v0.4.1 alpha: Cleanup: Internal cleanup Changed: All the settings constructors removed and replaced by a simple inline function. Added: Added native C++ unit test project to demos solution Fixed: FPL_OFFSETOF was not working Fixed: All file size macros like FPL_MEGABYTES was returning invalid results. Removed: FPL_PETABYTES and higher are removed, just because its useless. State: I cleaned up all the internals so i have a single block per platform and fixed some small bugs. Also i decided to continue with the subnamespace style - one nested level is fine. Next big thing will be audio output using directsound or xaudio and implementing the linux platform.
  3. Nested namespaces useless typing?

    I am talking about nested namespaces in C++. For example: // One nested namespace namespace my { namespace paths { const char *ExtractFileName(const char *path); }; namespace strings { size_t GetAnsiStringLength(const char *str); }; }; // Multiple nested namespaces namespace my { namespace system { namespace io { namespace path { const char *ExtractFileName(const char *path); }; }; }; namespace strings { size_t GetAnsiLength(const char *str); }; }; // Single namespace with category prefix namespace my { const char *PathExtractFileName(const char *path); size_t StringGetAnsiLength(const char *str); };
  4. November 2017 GameDev Challenge: Pong!

    Looks really great, i will try to test it when i get home.
  5. Nested namespaces useless typing?

    Do you think that C++ api structured by nested namespaces are a good thing? Or do you see its just useless typing and it should rather have a prefix or something? Or do you think that one or two levels are just fine? What do you think? I personally think that C++ namespaces are there to prevent conflicts between other api´s and for nothing else. But for medium to large size api´s one nested level is fine. Too long: my::IO::Path::Combine(my::IO::Path::GetHome(), my::IO::Path::ExtractFileName(...)); Fine: my::Paths::CombinePath(my::Paths::GetHomePath(), my::Paths::ExtractFileName(...)); Better (using namespace my): Paths::CombinePath(Paths::GetHomePath(), Paths::ExtractFileName(...));
  6. Update v0.4.0 alpha: Changed: All FPL_ENABLE_ defines are internal now, the caller must use FPL_NO_ or FPL_YES_ respectivily. Changed: AtomicCompareExchange is now AtomicCompareAndExchange Changed: InitFlags::VideoOpenGL is now InitFlags::Video Added: Software rendering support Added: VideoDriverType enumeration for selecting the active video driver Added: video::GetVideoBackBuffer with [Win32] implementation Added: video::ResizeVideoBackBuffer with [Win32] implementation Added: FPL_PETABYTES macro Added: FPL_EXABYTES macro Added: FPL_ZETTABYTES macro Added: FPL_YOTTABYTES macro Added: FPL_MIN macro Added: FPL_MAX macro Added: MutexCreate with [Win32] implementation Added: MutexDestroy with [Win32] implementation Added: MutexLock with [Win32] implementation Added: MutexUnlock with [Win32] implementation Added: SignalCreate with [Win32] implementation Added: SignalDestroy with [Win32] implementation Added: SignalWait with [Win32] implementation Added: SignalWakeUp with [Win32] implementation Added: GetClipboardAnsiText with [Win32] implementation Added: GetClipboardWideText with [Win32] implementation Added: SetClipboardText with [Win32] implementation for ansi and wide strings Added [MSVC]: AtomicExchangeS32 (Signed integer) Added [MSVC]: AtomicExchangeS64 (Signed integer) Added [MSVC]: AtomicAddS32 (Signed integer) Added [MSVC]: AtomicAddS64 (Signed integer) Added [MSVC]: AtomicCompareExchangeS32 (Signed integer) Added [MSVC]: AtomicCompareExchangeS64 (Signed integer) Fixed [MSVC]: AtomicExchangeU32 was not using unsigned intrinsic Fixed [MSVC]: AtomicExchangeU64 was not using unsigned intrinsic Fixed [MSVC]: AtomicAddU32 was not using unsigned intrinsic Fixed [MSVC]: AtomicAddU64 was not using unsigned intrinsic Fixed [MSVC]: AtomicCompareExchangeU32 was not using unsigned intrinsic Fixed [MSVC]: AtomicCompareExchangeU64 was not using unsigned intrinsic Implemented [Win32]: GetProcessorCoreCount Implemented [Win32]: Main thread infos Performance [Win32]: GetProcessorName (3 loop iterations at max) State: Its almost feature complete for Win32, only audio output is missing. Next i will clean up all the ifdef madness to get a more clean code structure - so i have a single ifdef block for each platform/backend. Also i am thinking about removing the sub namespaces, just because its so much useless typing for no reason.
  7. Update: Renamed: All memory/library/threading functions Renamed: CopyFile/DeleteFile renamed (Stupid win32!) Renamed: All internal opengl defines renamed, so that it wont conflict with other libraries Fixed: [Win32] strings::All Wide conversions was not working properly Removed: [Win32] All undefs removed Changed: [Win32/OpenGL] Check for already included gl.h Added: Basic threading creation and handling Todo: Create full documentation / upload doxygen documentation. Win32 audio output + api Win32 mutex / condition + api Win32 clipboard get/set Linux platform support
  8. 1/2. I already have the signature of passing in a buffer in all functions, but i (browser crashed in the middle of the sentence) thought i might be a good idea to support passing nullptr as the destination buffer. But you are right it was a bad idea, i should support returning a object instead, string memory allocated on the heap - which is the same std::string does under the hood. But overall my goal was to let the user decide how to handle the memory - not the library. So using a buffer always and never allocate memory would be more sane for that goal. 3. I copied it from stackoverflow, i just wanted a quick result for the moment. I have not thought this through by any means but i will when i feature complete the library, which will take a while because i want linux support as well.
  9. Reinventing the wheel

    Neither quicksort or std::vector is a wheel - not even close. Quicksort is okay right know, but in the future i expect we have sorting algorythms which are 1000 times faster. Vector are based on a good idea (dynamic growing array), but it has a bad api, bad control of memory and the implementation is a nightmare of macros and templates, impossible to debug or to find errors which are related. Other languages does this much much better, but even those are still not a wheel. Each one have weaknesses and flaws, some have a great api but bad technical implementation and vice versa - the "wheel" has nothing of that sort, its near perfect. Sure its the best we have right know, but like casey sayd - nothing in the past 30 years of game development is a wheel. I would go even further and state that nothing in the past 30 years of any software development is a wheel, especially the web which is the clunkiest square wheel ever made. So we need people which question things and try to make the next wheel. If nobody tries that, we never get a wheel. Its as simple as that.
  10. I debugged it in visual studio 2015 and it fully jumps to the allocation directly. Its not inlined, i havent enabled aggresive inline rules. I think i know what happened, the branch is not compiled out - but rather moved/rearranged, so the comparison is not on the same line anymore. Looking at the disassembly output should make that clear. So the problem was definitly the alloca() allocating memory on the current stack frame, then leaving the function and then throwing it away. Depending on the inlining of a function is not a good idea i think. Inlining should simply help make your code faster by removing function calls - but it should never change the actual result. I hate switching between low level and high level languages all the time, so you forget such fundamental things.
  11. Pitfalls of pixels as unit in game

    Do never ever convert your pixels to units or vice versa for any math computations! Thats a rule of thumb. Just use your world units directly, which should be float or double. Integer is not great when you want to smooth movement. The conversion for world to screen units is only done in rendering or for screen to world conversions (mouse picking for example). You can precalculate a factor which you can multiply your world coordinates to convert to screen coordinates and vice versa. Building up your world from tiles/grid is totally fine and i do this too like this: static constexpr f32 TILE_SIZE = 0.5f; static constexpr u32 TILE_COUNT_FOR_WIDTH = 40; static constexpr u32 TILE_COUNT_FOR_HEIGHT = 22; static constexpr f32 GAME_ASPECT = TILE_COUNT_FOR_WIDTH / (f32)TILE_COUNT_FOR_HEIGHT; static constexpr f32 GAME_WIDTH = TILE_COUNT_FOR_WIDTH * TILE_SIZE; static constexpr f32 GAME_HEIGHT = GAME_WIDTH / GAME_ASPECT; static constexpr f32 HALF_GAME_WIDTH = GAME_WIDTH * 0.5f; static constexpr f32 HALF_GAME_HEIGHT = GAME_HEIGHT * 0.5f; Also my worlds are always built in a right handed coordinate system - which is the same as opengl. So negative Y is going down and positive Y is going up and half the screen dimension is added to X and Y so the world coordinate 0, 0 is always the center of the screen - without taking any translation into account of course. Keep in mind, that you need to take the aspect ratio into account as well - so you should letterbox your game view, so it will fit on any display. I do this for every frame once and store the result: // Calculate a letterboxed viewport offset and size // @NOTE: Scale is used later for doing unprojection viewSize = Vec2f(halfGameWidth, halfGameHeight) * 2.0f; viewScale = (f32)windowSize.w / (halfGameWidth * 2.0f); Vec2i viewportSize = Vec2i(windowSize.w, (u32)(windowSize.w / aspectRatio)); if (viewportSize.h > windowSize.h) { viewportSize.h = windowSize.h; viewportSize.w = (u32)(viewportSize.h * aspectRatio); viewScale = (f32)viewportSize.w / (halfGameWidth * 2.0f); } Vec2i viewportOffset = Vec2i((windowSize.w - viewportSize.w) / 2, (windowSize.h - viewportSize.h) / 2); viewport.size = viewportSize; viewport.offset = viewportOffset; // Update view projection Mat4f proj = Mat4f::CreateOrthoRH(-halfGameWidth, halfGameWidth, -halfGameHeight, halfGameHeight, 0.0f, 1.0f); Mat4f model = Mat4f::Identity; viewProjection = proj * model;
  12. I have no idea why the condition is optimized away... maybe because of the default argument of nullptr and zero for the destination length?
  13. I would recommend adding a visual "step" by "step" debug system, so you clearly see when something goes wrong. You can just use a bool to force to simulate one step or even step a single body pair. Its really hard to solve physics problems when you just look at the final output. Render your bounding boxes + orientation and render your contact points inluding the surface normal and penetration distance. Start simple like dirk already recommended and build up from there. Also making a realtime dragging tool to move/rotate two bodies around at realtime helps a lot! I made such stuff in the past for javascript if you are interested:
  14. It might be, but there are no guarantee for that - even if it would use the "inline" keyword. Maybe with a forced inline, but this would require to change the api signature...