• Recent Tutorials

  • TileD CSV Map Loading with Prometheus (Alternate & Obsolete way)

    First a little updated word that this is now OBSOLETE in the most part - prometheus has since been re-written to not use SDL at all as well as many architectural changes for better performance, this will be updated as soon as the rewrite is complete - the source for this in the SVN repository at sourceforge is under the GEN1/ Directory. Sorry for any inconvenience

    A little while back I found TileD. A really nice tile map editor, but it generates maps in XML containers which encode the actual data in Base64 and a few others among which is CSV... That's nice. For a better briefing, feel free to read dazappas tutorial on CSV loading since I will only give a quick demo for how you would load tilesets as per the TileD instructions in the TMX file, load the CSV data and draw it with the help of Prometheus_Vid.

    Performance wise I have yet to perform a few tweaks (at revision 59 at time of writing) but when running the ZenGl counterpart program I observe 59.5 frames/sec (culv processor and as commented in dazappa's tutorial, I believe it is cpu limited) in wine 1.3.17 which in my experience is marginally ~1-5% faster then my windows 7 install; whilst Prometheus churns out 60.5 frames/sec without performance optimization at all so its more or less neck and neck. Its is worth mentioning though, that r59 will not draw data beyond the +x and +y boundaries of the screen as defined by CreateWindow(x,y,bpp)... I do not know about dazappas Zengl code, however.

    On to the code, I whipped up a really fast demo program:

    Code:
    program TiledCsvDemoProgram;
    
    uses
        sdl,
        Prometheus_Vid;
    
    var
        Mp: Map;
        CycleStartTime: Int64;
        FpsFont: Font;
        CycleString: String;
            
    begin
        PrometheusVid_Start();
        CreateWindow(800, 600, 32);
        UpdateWindow();
        UpdateCanvas();
        
        FpsFont.Load('FpsFont.ttf', 14);
        
        Mp.LoadFromTMX('', 'map_csv.tmx');
        repeat
            CycleStartTime := Sdl_GetTicks;
            ClearCanvas();
            Mp.Draw(0,0);
        
            Str((Sdl_GetTicks - CycleStartTime), CycleString);
            FpsFont.Draw(10, 10, 'Cycle time: ' + CycleString + ' ms', QuickColour(255, 255, 255, 255));
            UpdateCanvas();
            CycleStartTime := Sdl_GetTicks();
            until 9-8=4; //WARNING: you have to killtask and cannot use the x button as I did not include the core unit to handle events...
    end.
    Loading the TMX file: MapVariable.LoadFromTMX(Directory, Path: ANSIString) is the full procedure write-up and is passed the directory of the TMX file you want to load (auto detects the trailing / and the path to the TMX file you want to load. By passing a directory of '' we load from the same directory as our exe. If we had a Maps folder and the TMX file was there we would do MapVariable.Load('Maps/','map_csv.tmx') From there is will automatically parse your XML and CSV data and load the appropriate tilesets and etc... So its all in one package.

    Drawing the Map: MapVariable.Draw(X, Y: Int64) is once again the full write up which draws the Map at X,Y on the screen so all nice there too. For the next revision I'll implement the variable allowing offsets of each layer and hide/show them too which will make it flexible to some degree.

    Again, as with everything I publish about my code, if you have any suggestions, even if you do not use my code, please post them. Feature requests and etc are always welcome and are encouraged as it helps develop projects further.

    All in all, the rest (if not all) of everything I do is, if I may say so myself, rather self-explanatory, but if there is anything unclear comment and ask please.

    Over-and out.
    Comments 11 Comments
    1. dazappa's Avatar
      dazappa -
      Neat! This is going to be built into Prometheus then? I like the idea having the object mostly draw itself, but what about drawing individual layers? Personally, I like to put the objects into the map, above some layers and behind others. Drawing all of the layers at once would make this impossible.

      Yes, ZenGL can draw outside of the main window size (for instance; drawing at x=-16, y=0)

      Hovering around 59 and 61 FPS (for either of them) sounds an awful lot like VSync to me If it is VSync, either it (Wine) or your drivers are overriding application settings. If it's not Vsync, then your computer must be very dated! For reference, I have a netbook running at 900mhz with integrated intel graphics that can draw around 600 sprites at 60 FPS.
    1. code_glitch's Avatar
      code_glitch -
      Thanks, for those kind works... For drawing an individual layer I would to a MapVariable.DrawLayer(X, Y, Layer: Int64) its the same procedure as used by MapVariable draw since all mapvariable.draw() is is a loop drawing each layer from memory

      I actually cant say whether I am running off CPU or GPU in Prometheus but I can say ZenGL definitely does.

      PS: My comp is not dated, its a core 2 duo however in wine I cannot get any application to use more than 35% cpu? I'll have to look into that... For the record I play Starcraft 2 (great game, shame its named like world of warcraft - there is no comparison) on Med-High along with Far Cry, Battle Field 2142 and Supreme commander (max)

      TBH though, I think it might be down to wine since some stuff runs really well and some not. Eg. Mass Effect 2 is quite slow, when Supreme Commander is almost native. Although it may be vsync. As a test, I extended your map file to 200x200 and 60fps again with 2% extra CPU? so I have no clue.

      PS: The tutorial has now been updated for better support of tilesets (there was an issue with directories) in r59, sorry.
    1. Andru's Avatar
      Andru -
      I can't grab Prometheus from svn under Windows at work because of this name in directory Demos: "Prometheus Ship Demo SVNR-51|52.zip"
      Also Prometheus_Vid.pas is wrong(e.g. method Map.LoadFromTMX are not equal to the same method in Map_TMXPrivate unit). And when I fixed this I couldn't run a demo with data from dazappa tutorial, because it just crashed inside FindOccurenceLineInFile function... can you provide me binaries or just put together source code which can be compiled under Lazarus?

      About FPS question - just VSync and precision of calculation, which don't says anything to me.
    1. code_glitch's Avatar
      code_glitch -
      oh, my my my, I'm so sorry about that, I have absolutely no idea what is going on with my SVN layout... I believe I may accidentally have uploaded a stray Prometheus_vid from another version AAAH! and I didn't think that ship demo was still up there either, I'll fix up the SVN and post a TileD demo application under the demo/ folder in the SVN... However, I don't use lazarus so this really is all designed for plain FPC, although there should be no problems with lazarus I haven't got the faintest idea how to make it all stick together. I'll try and see if wine is happy compiling you an exe.

      Just wondering andru, what version of FPC are you using? I think that a 2.2.X compiler may have some issues... Just a hunch, but don't the 'older' versions of Lazarus use a compiler earlier to the nice 2.4.2? I remember having some issue with earlier compilers for new code. As for the windows thing, I have no idea what DLLs will be needed since I updated the 'runtime' on r35. I'll try and fix those in the next commit later today.
    1. Andru's Avatar
      Andru -
      Nope, I never use old versions of FPC. At work I have Lazarus 0.9.31 and FPC 2.4.2. Ok, I will wait for your commit with fixes and I will try something at home under my ArchLinux
    1. code_glitch's Avatar
      code_glitch -
      I've narrowed it down to something going wrong with file handling in windows. I found that the issue with finding the Map_TMXPrivate.pas file that is linked to from Maps.pas has to be written differently in windows and linux so I'll have to add an ifdef there, also it seems there may be some dll and runtime issues on windows for Prometheus in general since I haven't had to use it on windows in such a long time. Oh, and to top it off, my SVN has found that its .svn folders are corrupt so yay...

      Lots of work for today, but since I pride myself in cross platform code, I will be fixing all that in the next few hours.
    1. Andru's Avatar
      Andru -
      So, I have tested your code under my ArchLinux x86_64. The code for calculation FPS must be next:
      Code:
      program demo;
      uses
          sdl,
          Prometheus_Vid;
      
      var
          Mp: Map;
          CycleStartTime: Int64 = 0;
          CycleFPSTime: Int64 = 0;
          FPSCount : Integer;
          FpsFont: Font;
          CycleString: String;
      
      {$R *.res}
      
      begin
          PrometheusVid_Start();
          CreateWindow(640, 480, 32);
          UpdateWindow();
          UpdateCanvas();
      
          FpsFont.Load('FpsFont.ttf', 14);
      
          Mp.LoadFromTMX('./', 'map_csv.tmx'); // here must be './', because without it application will crash
          repeat
              CycleStartTime := Sdl_GetTicks;
              ClearCanvas();
              Mp.Draw(0,0);
      
      
              FpsFont.Draw(10, 10, 'Cycle time: ' + CycleString + ' ms', QuickColour(255, 255, 255, 255));
              UpdateCanvas();
              INC( CycleFPSTime, ( Sdl_GetTicks - CycleStartTime ) );
              INC( FPSCount );
      
              if CycleFPSTime >= 1000 Then
                begin
                  Str(FPSCount, CycleString);
                  FPSCount := 0;
                  CycleFPSTime := 0;
                end;
              until 9-8=4; //WARNING: you have to killtask and cannot use the x button as I did not include the core unit to handle events...
      end.
      For test I have changed resolution to 640x480 and got ~1700 fps(without rendering the text - ~1900). ZenGL demo shows me(without VSync) ~2050 in WINE and 5200 with native code. So I have only two questions - what could I do wrong and do you use software rasterization by default?

      My PC: Phenom X4 965(@4Ghz), Radeon HD 5850 and 4Gb RAM
      Installed SDL packages:
      extra sdl 1.2.14-6
      extra sdl_image 1.2.10-2
      extra sdl_mixer 1.2.11-2
      extra sdl_net 1.2.7-3
      extra sdl_sound 1.0.3-2
      extra sdl_ttf 2.0.10-1
    1. code_glitch's Avatar
      code_glitch -
      First question: I have absolutely no idea to be honest, second question: what is software rasterization? I've actually never heard of it... Something to do with rasterization?

      I looked into the windows issue and all I can say is what the.... I get runtime errors left and right, all to do with reading stuff from files and in many cases completely randomly on windows 7, I mean literally randomly, sometimes it stops on line 135, sometimes on 32 and sometimes it works a few frames. Other times it runs THROUGH an 'access denied' error and stops 1 minute later !?! I mean haaaa?

      Anyway, those benchmark results sound like what I got, in this instance I believe WINE is a fair bit slower than native... The text will be quite slow indeed since I use Sdl_blended, because it looks nice. i think an older release of prometheus used solid because I did not have support for alpha and that was fast, but times have changed. Besides that, would you call 1900 frames/sec bad going? its far from Zengl on your computer, but I find it quite usable on my CULV chip @1.2ghz (the dual core penryn, no the intel core 2 solo rebrand grr) and HD4330 with 4gb ram.

      Oh, yea, 965, the BE edition judging from those speeds right? I so want one of those, but my next rig may settle for a nice little X3 which I oh so like...

      IMPORTANT UPDATE:
      The windows bug has been found, isolated and fixed, repeat: the windows bug is down. After some serious checking of every line involved with LoadLayerFromCSV and LoadFromTMX, the bug has been defeated, leaving pure cross platform goodness once again after a hardy 5 hours of labour the cause of the bug was the LayerCode variable being too large for Win32 platforms, but not linux for some reason. Thus it has been amended to 2000x2000 on 50 layers rather than 4000x4000 on 50 layers (thats in tiles not pixels ). All updates in r72 on the SVN repo.
    1. Andru's Avatar
      Andru -
      Quote Originally Posted by code_glitch View Post
      what is software rasterization?
      Oh, sorry, in English "software rendering" is more correct. But I have looked into Prometheus source code and found only OpenGL commands, so never mind

      Quote Originally Posted by code_glitch View Post
      Besides that, would you call 1900 frames/sec bad going?
      So simple scene is not a benchmark, so I can't say is it bad or not.
    1. code_glitch's Avatar
      code_glitch -
      Lol, I do speak French and english fluently, and I'm supposed to be learning German (school) but I don't speak rasterization and neither does Google, but hey thats OK lol; reminds me of when my french was as good as my english, man those were the good times when people just smiled at the ambiguous meanings...

      And I have to admit, I am inclined to agree on the simplicity of the scene and it not being a true benchmark. And yes, most of it is gl with a few scarce remnants of sdl for events, window handling and resource loading. But don't fret, soon they to shall be overwritten wahaha.
    1. Andru's Avatar
      Andru -
      I don't speak rasterization and neither does Google
      This word is exists, but in another meaning than rendering(videocards have blocks of rasterization, also there is an "font rasterization" in wiki and so on)