Results 1 to 10 of 48

Thread: Cheb's project will be here.

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1


    (last progress long time ago, next should hopefully be around December 2019 or January 2020)

    The project's website:

    The full saga in Russian

    The project history: [pending update and re-checking, will re-post at the same time I upload the public Test #21]
    Last edited by Chebmaster; 12-12-2019 at 09:00 PM. Reason: updating the titular post

  2. #2

    Yet another !surprise! from this newfangled string encoding auto-management.

    I launched my engine compiled in fpc 3.0.4 on the mammoth coprolite I call my file server:
    Chentrah version 0.21.3847 for Win32-i386, 
      compiled at 12:21:52 on 2018/01/28 using Free Pascal 3.0.4.
      (developer mode on)
    Operating System: Wine 1.3.28 / Ubuntu 11.10
    User name: cheb
    CPU Phenom II X2 550
      x2 logical cores
      level 2 cache: 512 Kbytes, line size 64 bytes
      TSC invariancy: yes
      TSC frequency: 3.11 GHz)
    Lo and behold it crashed with "Failed to load "GL_ARB_framebuffer_object"".
    Scratching the bone between my ears, I checked the extension string. Nope, the extension was there. So why?

    Unearthed an old function naively assuming that String = AnsiString:
    function glext_ExtensionSupported(const extension: String; const searchIn: String): Boolean;
      extensions: PAnsiChar;
      start: PAnsiChar;
      where, terminator: PAnsiChar;
      if (Pos(' ', extension) <> 0) or (extension = '') then
        Result := FALSE;
      if searchIn = '' then extensions := PAnsiChar(glGetString(GL_EXTENSIONS))
      else extensions := PAnsiChar(searchIn);
      start := extensions;
      while TRUE do
        where := StrPos(start, PAnsiChar(extension));
        if where = nil then Break;
        terminator := Pointer(PtrUInt(where) + Length(extension));
        if (where = start) or (PAnsiChar(PtrUInt(where) - 1)^ = ' ') then
          if (terminator^ = ' ') or (terminator^ = #0) then
            Result := TRUE;
        start := terminator;
      Result := FALSE;
    Corrected it to AnsiString and my engine started up, proving there is life on GeForce 7025.

    The wrong version was working fine in real Windows.
    I can only assume that that fossilized wine did not have some mechanism the auto-recoding of the FPC RTL relies on.
    That's another thing to watch out for, I suppose.
    Last edited by Chebmaster; 20-11-2019 at 08:58 AM.

  3. #3
    Cheb's Game Engine is that eternally worked on thing that never releases its next build.

    Today, seeing the compilation process complete, I roared like a bear overcoming horrible constipation: I spent a full year refactoring my code. A full year!


    A debugging hell lies ahead of me but all I could feel is relief. Finally!

    The previous build was released at December 17, 2016 (please don't go looking at it: I am horribly ashamed of that mess by some mistake called my sources).

    The last year I looked at Fidel Castro's example and gave a vow to never shave or trim my beard until my engine goes past the rotating cube stage. I am now forced to resort to dirty life hacks like putting my t-shirt over my beard so that it stays stuffed down my collar to look presentable ...

    My track record of making side trips, each holding me back for a year or two:
    2007: Linux support
    2009: Migrating from OpenGL ~1.4 to OpenGL 2.1 (later GL ES 2)
    2010: Tired of never getting anywhere, almost abandoned the project
    2013: Changing architecture to multi-threaded for multi-core CPU support
    2015: x86-64 support (still not finished, dammit, requires FPC 3.2 released to continue)
    2016: Raspberry Pi support
    2018: Epic refactoring of my horribly dated ODBMS I created back in 2006

  4. #4
    Ah yes.. strings! i've done migration of my game to widestrings everywhere 2-3 years ago, i still feel some pain, but it was worth it in the end!

    Same with "epic refactoring" - after converting my project from delphi 7 to freepascal, i've done so much refactoring and consequentially simplifications - make use of operator overlading, generics and methods in records, code writes a hell lot cleaner in modern pascal

    You have interesting way of building your engine, especially that you can keep resources loaded and re-load the game logic, i assume it's done via sort of dll mechanism?
    This is my game project - Top Down City:

    My OpenAL audio wrapper with Intelligent Source Manager to use unlimited:

  5. #5
    Yes, indeed. All game logic resides in a module DLL hosted by the mother EXE. When the DLL unloads it uses the same serialization mechanism used for saving to selectively gather all asset classes (owning OpenGL handles and such) and store them into a memory stream owned by the EXE.
    The process is not as simple as it looks (because of interdependent nested assets like fbos and their textures I have the assets loaded from the save "devour" their counterparts received from the mother taking over their handles) but I had it working almost perfectly before the rehaul.

    Generics, turns out I have invented them as well, back when fpc 1.x didn't have dynamic arrays yet but already had modern classes. Worked via tricky includes and preprocessor. I plan to re-do the static remains of those classes, still used everywhere, using real generics. But that is a secondary task.

    What I was going to do before rehauling my ODBMS was replacing the old, horribly awkward module switching GUI in the EXE with the standard GUI that is available to the DLL, making them into a specialized module DLL of their own thus leaving the EXE a dumb container only able to render console. And because I interrupted that task half-way in October 2018, I forgot what I was going to do and where I stopped. Now my engine finally runs... rendering a blank screen and not responding to inputs.
    Where do I start... Boo-hoo-hoo...

  6. #6
    During debugging, encountered a grievous documentation error:
    function TChepersyMemoryManagerChunk.Alloc: pointer;
      i, k: integer;
      j: cardinal;
      m: ptruint;
      i:= 0;
      // the mask bits of non-valid indexes are pre-set to 1, see the constructor
      for i:= 0 to High(f_AllocMask) do begin
        m:= not f_AllocMask[i];
        if m = 0 then continue; 
        // incorrectly states that BsfDWord returns 255 if no bits are set
        // while in fact it returns 0! (at least in fp 2.6.4 it does)
            j:= {$ifdef cpu64}BsfQWord( {$else}BsfDWord( {$endif} m );
    addlog(' i=%0, j=%1, k=%2, mask=%3',[i,j,k,pointer(f_AllocMask[i])])    ;
    //    if j < 255 then begin
          k:= (i * 8 * sizeof(pointer)) + j;
          Assert((k >= f_IdxLow) and (k <= f_IdxHigh)
                , 'TChepersyMemoryManagerChunk.Alloc: index ' + IntToStr(k) 
                + ' is out of bounds (' + IntToStr(f_IdxLow) + ',' 
                + IntToStr(f_IdxHigh) + ')');
          if f_FreeCount = 0 then CpsMemoryManager.OnChunkBecomingFull(Self);
          f_AllocMask[i]:= f_AllocMask[i] or (ptruint(1) shl j); 
          Exit(pointer(ptruint(Self) + ptruint(k) * f_Size));
    //    end;
                               'TChepersyMemoryManagerChunk.Alloc algorithm fail']);
    ..aaand I'd say this is more than just twitching:



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts