Tile Map like Ultima Online's

Advanced game related topics
..::Origin::..
Enthusiast
Enthusiast
Posts: 125
Joined: Sat Jun 17, 2006 3:15 pm

Tile Map like Ultima Online's

Post by ..::Origin::.. »

It's been my objective for awhile to write an isometric map engine, like ultima onlines. Not exactly the way it loads it from files etc, but at least a fast engine with little CPU and memory usage, with high FPS results.

On my computer, The ultima online client seems to use 10 CPU and no more then 20,000K memory. (60 FPS)

Where as, mine uses no more then 6,000K memory, and 50 CPU +. I'm looking for a faster way to draw my tile by tile map, so it wont be needing as much CPU, and has high FPS results. (55 FPS)

Here are parts of my code you should be interested in looking at...
Start-up variables:

Code: Select all

  Global MapWidth = 1000
  Global MapHeight = 1000

  Global ScreenWidth = 1024
  Global ScreenHeight = 768

  Structure tile
    x.l
    y.l
    z.l
    type.l
  EndStructure 

  Global Dim Map.tile(MapWidth,MapHeight)
  For i=1 To MapWidth
    For b=1 To MapHeight
      Map(i,b)\x=i
      Map(i,b)\y=b
      ;Map(i,b)\type=
    Next
  Next
Render the map:

Code: Select all

  Procedure RenderMap()
	  BottomRightX = ((ScreenWidth-1 + ScreenPosX) / TileWidth) - 1
	  BottomRightY = ((ScreenHeight-1 + ScreenPosY) / TileHeight ) * 2

	  If BottomRightX > MapWidth 
		  BottomRightX = MapWidth
	  EndIf
	  
	  If BottomRightY > MapHeight 
		  BottomRightY = MapHeight
		EndIf
		
	  If BottomRightX < MapWidth 	
		  BottomRightX = BottomRightX + 1
	  EndIf
	  
	  If BottomRightY < MapHeight 
		  BottomRightY = BottomRightY + 1
	  EndIf

	  TopLeftX = ScreenPosX / TileWidth
	  TopLeftY = (ScreenPosY / TileHeight) * 2

	  For y = TopLeftY To BottomRightY  
		  For x = TopRightX To BottomRightX
			  IsoX = x * (TileWidth + (y & 1) * (TileWidth / 2)) - ScreenPosX
		    IsoY = y * (TileHeight / 2) - ScreenPosY       
        Select Map(x,y)\type
          Case 0
            DisplayTransparentSprite(floor1,IsoX,IsoY)
          Case floor1
            DisplayTransparentSprite(floor2,IsoX,IsoY)
        EndSelect              
		  Next
	  Next
  EndProcedure
Thanks for reading, Hope you can help!
..::Origin::..
X
Enthusiast
Enthusiast
Posts: 311
Joined: Tue Apr 04, 2006 6:27 am

Post by X »

The first thing that comes to mind is calculations. If you are able to keep the calculations out of the rendering loop. And only use them whenever the map view moves (scrolls), it should be much faster.
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

Prerender the ground onto a large surface so you aren't constantly looping through tiles drawing them.

Also, is Ultima 32bit coloring and texturing?

That might make a difference in this case, but I'm not sure.
..::Origin::..
Enthusiast
Enthusiast
Posts: 125
Joined: Sat Jun 17, 2006 3:15 pm

Post by ..::Origin::.. »

Sprites are in 24-bit BMP.

It seems that simply commenting out the 'drawtransparentsprite' completely lowers the CPU usage to 0. It is graphical related somewhere.
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

I need to see enough code ot see the frequency and circumstances under which you render the map.
..::Origin::..
Enthusiast
Enthusiast
Posts: 125
Joined: Sat Jun 17, 2006 3:15 pm

Post by ..::Origin::.. »

I havent even changed any graphical settings. Just a windowed 800x600 screen. Sprites are loaded into the buffer without any flags etc.

Default settings.

Only thing that is changed would be the framerate, which is at 60.
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

I really need to see the main loop where you are calling this render function. If you don't want to show it then fine but it'll be harder to help you. Its not like you're coding anything top secret that someone else here couldn't do.

I recommend you try using Delay(fpsDelay) in your main loop where fpsDelay = 1000/fps and fps=60

SetFrameRate may not work in windowed mode.

Thats all I can and will say until you give more information.
..::Origin::..
Enthusiast
Enthusiast
Posts: 125
Joined: Sat Jun 17, 2006 3:15 pm

Post by ..::Origin::.. »

Code: Select all

  Repeat
    ClearScreen(0)
	  PlayerInput()
	  RenderMap()

    DisplayTransparentSprite(cursor,DesktopMouseX()-WindowX(0)-5,DesktopMouseY()-WindowY(0)-30)
    FlipBuffers()
    event = WindowEvent()

    Delay(1)
  Until KeyboardPushed(#PB_Key_Escape) Or event=#PB_Event_CloseWindow

PlayerInput just determines if certain keys are pressed.
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

Try disabling the cursor drawing and see what happens
..::Origin::..
Enthusiast
Enthusiast
Posts: 125
Joined: Sat Jun 17, 2006 3:15 pm

Post by ..::Origin::.. »

Makes little to no difference. Same with disabling the player input script.

Doing more investigation, it seems that 'FlipBuffers' is also using ALOT of the CPU usage. If i commented out everything else and just had that, the CPU is about 80, yet if i comment that and uncomment everything else, its about 50-60, then if i comment out 'RenderMap' as well, The CPU drops down to 0.
coma
Enthusiast
Enthusiast
Posts: 164
Joined: Fri Aug 15, 2003 3:46 am
Location: Canada

Post by coma »

and with delay(2), how much cpu and fps do you have ?...
..::Origin::..
Enthusiast
Enthusiast
Posts: 125
Joined: Sat Jun 17, 2006 3:15 pm

Post by ..::Origin::.. »

Slighty 1-2 less CPU, 60 fps.
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

First, just so you know theres really no point in delaying less than 16. 1000/16 ~ 60fps

Delaying 2 means your program is technically trying to draw at 500 fps.

Anything above 60 is essentially pointless.

Another thing I guess is what are your system specs?
..::Origin::..
Enthusiast
Enthusiast
Posts: 125
Joined: Sat Jun 17, 2006 3:15 pm

Post by ..::Origin::.. »

1GB DDR400 Ram,
200 WD HD
Dual Core 64bit Proccessor 2.21 GHZ (running windows XP 32bit sp2)
gfxcard:http://www.gigabyte.com.au/Support/VGA/ ... uctID=1280

All the motherboard drivers and all the gfx drivers are installed..
dx9c..

It's a rediculously fast pc, so i don't see how it is hardware related. I've tested it on a couple of other pc's and the CPU is often 30-40 higher.
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

That would make sense since yours is a dual core. Don't really knwo waht to tell you. I tile a huge map repeatedly for 8 layers and i barely break 3 or 4 CPU on my games...

Code: Select all

OpenWindow(0,0,0,800,600,"")
InitKeyboard()
tilewidth=50
tileheight=50
screenposx=55
screenposx=322

Repeat 

For x=0 To 1280
For y = 0 To 1024
IsoX = x * (TileWidth + (y & 1) * (TileWidth / 2)) - ScreenPosX
IsoY = y * (TileHeight / 2) - ScreenPosY
Next
Next 

ExamineKeyboard()
If KeyboardReleased(#PB_Key_Escape)
End
EndIf 

Delay(1)

ForEver
I don't know if thats an accurate representation of what your values would look like. But those equations are pretty intense. Lotsof mults and divs. I'd precalculate into a table as much as you can.

I have a 3.4ghz p4 here and this sucks 33% cpu
Post Reply