Sunday, 9 March 2014

Minimaps

This weekend was like any other. I spent it doing some programming. Along with fixing a plethora of little bugs in my map editor I decided to create a minimap for it. As you can see here in the picture below, we have a minimap (and a very nice Martian landscape):


To get a minimap to work you have to translate the mini coordinates into big coordinates. That way you can scroll to where the user clicks. The method I used is this:

real_map_coord = mini_map_coord * ( real_map_size / mini_map_size)

Works perfectly. I do this twice; once for X and once for Y.



Saturday, 1 March 2014

Map Editor & Thoughts on Xojo

Hobby game programming is difficult because it requires a lot of energy and time but also because it requires the right amount of motivation and the right mind-set. There's always a multitude of technical complications to overcome and you have to overcome these mostly on your own. This isn't helped by the fact that you're also learning along the way - mostly at the end of the day after you've already been burnt out by work. Progress is slow. It's also not uncommon to be halfway through making something and then you feel like making something else. Fortunately with all of your efforts you can always walk away from an unfinished project and be able to say that you've learned something from it.

My life has been turned upside down in the past two years and after a really bad patch it's finally come back together again. Due to the circumstances I was forced to take a break from regular programming and all my creative desires had to be suspended for almost a year. Fortunately, I've come back to programming with renewed vigour. After moving from Australia to Germany to live with my girlfriend I found a new job which introduced me to a new language: Xojo.

Xojo is a surprisingly powerful tool but also a relatively unknown one. At first my expectations for it weren't very high. I'd used VB before and was never very enthusiastic about VB, but Xojo surprised me. While programming at work with it everyday I started to like it a lot. With Xojo it is extremely easy to develop a good looking, stable and quite powerful program in a very small amount of time.

After settling into my new home my creativity crawled  its way slowly back to me. Naturally, I was keen to test Xojo's performance in my favourite area: games development. So I went ahead and created a functional 2D Map Editor for my C++ games.

The development process lasted three weeks, working only in afternoons and on weekends. This is a testament to Xojo's ease of use and potential for rapid development. The end result is very impressive for the amount of time put in and for the amount of problems I encountered during development (none). Due to Xojo's cross platform nature, this will also compile and run with no problems and no modifications for Windows, Mac OSX and Linux.

You may be wondering why I decided to make a map editor instead of a game in Xojo. While it's certainly possible to create a game in Xojo it's not necessarily the best choice for a game developer in its current state... especially for 3D. Here's why:

1. No .net for Windows

On Windows Xojo still uses the Win32 API. Flickering can be a problem. Although there are ways to help fix this, you're still working with old technology. Even for people developing normal programs in Xojo, without a primary focus on graphics, they have encountered difficulties. If you wanted to make a very slick, modern-looking game in Xojo you might have a hard time of it.

The good news is that the Xojo team have just finished upgrading the Mac side of Xojo from Carbon to Cocoa - and Windows is planned for the future.

2. Raw OpenGL / Less libaries

As a less known and used language Xojo has less people to write libraries for it. Considering its beginner orientation and toy-like feel, perhaps it also doesn't do so well at attracting the kind of hardcore users who would create these types of things for it. Which is a shame, because it's really not a tool exclusively for beginners. 3D is possible in Xojo but requires the use of raw OpenGL. There aren't helpful libraries like Irrlicht, Ogre3D, or even Glut, to make it easier for you.

Honestly, it's easier to go and get yourself Irrlicht for 3D than trying to do it with Xojo at the moment. However a good man named Alwyn Bester is working on some kind of 3D library for Xojo to address this issue.

With that said if you're interested in making a simple 2D, crossplatform game with barely any hassle then you can't go wrong with Xojo. It lifts all the complexity off the programmer and lets him/her get straight to the fun parts. Its made a brilliant compromise between power, performance, ease of use and development speed. In fact, for a lightweight programming tool, it doesn't really get much better than Xojo.

Programming languages are tools in the belt of a programmer, and Xojo's earned a place on my belt. While I will continue to use C and C++ for the bulk of my game design efforts, all the tools and utilities I create to support my games will be in Xojo. I'm extremely impressed with how easily I've been able to develop this map editor. If I'd have done it in C++ it would still only be 25% complete by now.

The Map Editor

Anyway, I'll tell you and show you a little bit more about the map editor I've made.

My map editor allows you to create, save and load 2D maps. It creates a text file which saves the location of the tiles and their corresponding TileID. For demonstration purposes I've created this map called Tranquil Forest and have uploaded its map file here so you can look at it:


 Writing in plain text at the top of the file is also ok. Here you can write whatever more you want to say however it
will not be loaded into the game.
Please be mindful of the format. The game will only read lines that end in a semi colon (;) so don't use them in
your comments.


Game=Alpha;
GameVersion=1.0.0;
MapName=TranquilForest;
MapDescription=A nice forest with a road going through it.;
MapVersion=1.0.0;
Author=Joshua Woods;
AuthorInfo=someone@gmail.com;
License=PublicDomain;
Resolution=2048x2048;
TileSize=32;
0,0=5;
0,1=5;
0,2=1;
0,3=1;
0,4=2;
0,5=1;
0,6=1;
0,7=5;
0,8=5;
0,9=5;
0,10=1;
0,11=1;
0,12=1;
0,13=1;
0,14=1;
0,15=1;
0,16=1;
0,17=1;
0,18=1;
0,19=1;
0,20=1;
0,21=1;
0,22=1;
0,23=1;
0,24=1;
0,25=1;
0,26=1;
0,27=1;
0,28=1;
0,29=1;
0,30=1;
0,31=1;
0,32=1;
0,33=1;
0,34=1;
0,35=1;
0,36=1;
0,37=1;
0,38=1;
0,39=1;
0,40=1;
0,41=1;
0,42=1;
0,43=1;
0,44=3;
0,45=4;
0,46=4;
0,47=4;
0,48=4;
0,49=4;
0,50=4;
0,51=4;
0,52=4;
0,53=4;
0,54=4;
0,55=4;
0,56=4;
0,57=4;
0,58=4;
0,59=4;
0,60=4;
0,61=4;
0,62=4;
0,63=4;
1,0=5;
1,1=5;
1,2=1;
1,3=1;
1,4=2;
1,5=1;
1,6=1;
1,7=5;
1,8=5;
1,9=5;
1,10=1;
1,11=1;
1,12=1;
1,13=1;
1,14=1;
1,15=1;
1,16=1;
1,17=1;
1,18=1;
1,19=1;
1,20=1;
1,21=1;
1,22=1;
1,23=5;
1,24=5;
1,25=5;
1,26=1;
1,27=5;
1,28=5;
1,29=5;
1,30=1;
1,31=1;
1,32=1;
1,33=1;
1,34=1;
1,35=1;
1,36=1;
1,37=1;
1,38=1;
1,39=1;
1,40=1;
1,41=1;
1,42=1;
1,43=1;
1,44=3;
1,45=4;
1,46=4;
1,47=4;
1,48=4;
1,49=4;
1,50=4;
1,51=4;
1,52=4;
1,53=4;
1,54=4;
1,55=4;
1,56=4;
1,57=4;
1,58=4;
1,59=4;
1,60=4;
1,61=4;
1,62=4;
1,63=4;
2,0=5;
2,1=5;
2,2=1;
2,3=1;
2,4=2;
2,5=1;
2,6=1;
2,7=5;
2,8=5;
2,9=5;
2,10=1;
2,11=1;
2,12=1;
2,13=1;
2,14=3;
2,15=1;
2,16=1;
2,17=1;
2,18=1;
2,19=1;
2,20=1;
2,21=1;
2,22=5;
2,23=5;
2,24=5;
2,25=5;
2,26=5;
2,27=5;
2,28=5;
2,29=5;
2,30=1;
2,31=1;
2,32=1;
2,33=1;
2,34=1;
2,35=1;
2,36=1;
2,37=1;
2,38=1;
2,39=1;
2,40=1;
2,41=1;
2,42=1;
2,43=1;
2,44=3;
2,45=4;
2,46=4;
2,47=4;
2,48=4;
2,49=4;
2,50=4;
2,51=4;
2,52=4;
2,53=4;
2,54=4;
2,55=4;
2,56=4;
2,57=4;
2,58=4;
2,59=4;
2,60=4;
2,61=4;
2,62=4;
2,63=4;
3,0=5;
3,1=5;
3,2=1;
3,3=1;
3,4=2;
3,5=1;
3,6=1;
3,7=5;
3,8=5;
3,9=5;
3,10=1;
3,11=1;
3,12=3;
3,13=3;
3,14=3;
3,15=3;
3,16=3;
3,17=3;
3,18=1;
3,19=1;
3,20=1;
3,21=1;
3,22=1;
3,23=5;
3,24=5;
3,25=5;
3,26=5;
3,27=5;
3,28=5;
3,29=5;
3,30=5;
3,31=5;
3,32=5;
3,33=1;
3,34=1;
3,35=1;
3,36=1;
3,37=1;
3,38=1;
3,39=1;
3,40=1;
3,41=1;
3,42=1;
3,43=1;
3,44=3;
3,45=4;
3,46=4;
3,47=4;
3,48=4;
3,49=4;
3,50=4;
3,51=4;
3,52=4;
3,53=4;
3,54=4;
3,55=4;
3,56=4;
3,57=4;
3,58=4;
3,59=4;
3,60=4;
3,61=4;
3,62=4;
3,63=4;
4,0=5;
4,1=5;
4,2=5;
4,3=1;
4,4=2;
4,5=2;
4,6=1;
4,7=1;
4,8=5;
4,9=5;
4,10=1;
4,11=1;
4,12=3;
4,13=4;
4,14=4;
4,15=4;
4,16=4;
4,17=3;
4,18=3;
4,19=1;
4,20=1;
4,21=1;
4,22=1;
4,23=1;
4,24=5;
4,25=5;
4,26=5;
4,27=5;
4,28=5;
4,29=5;
4,30=5;
4,31=5;
4,32=5;
4,33=1;
4,34=1;
4,35=1;
4,36=1;
4,37=1;
4,38=1;
4,39=1;
4,40=1;
4,41=1;
4,42=1;
4,43=1;
4,44=3;
4,45=4;
4,46=4;
4,47=4;
4,48=4;
4,49=4;
4,50=4;
4,51=4;
4,52=4;
4,53=4;
4,54=4;
4,55=4;
4,56=4;
4,57=4;
4,58=4;
4,59=4;
4,60=4;
4,61=4;
4,62=4;
4,63=4;
5,0=5;
5,1=5;
5,2=5;
5,3=1;
5,4=1;
5,5=2;
5,6=1;
5,7=1;
5,8=5;
5,9=5;
5,10=1;
5,11=1;
5,12=3;
5,13=4;
5,14=4;
5,15=4;
5,16=4;
5,17=4;
5,18=3;
5,19=3;
5,20=1;
5,21=1;
5,22=1;
5,23=1;
5,24=5;
5,25=5;
5,26=5;
5,27=5;
5,28=5;
5,29=5;
5,30=5;
5,31=5;
5,32=1;
5,33=5;
5,34=1;
5,35=1;
5,36=1;
5,37=1;
5,38=1;
5,39=1;
5,40=1;
5,41=1;
5,42=1;
5,43=1;
5,44=3;
5,45=4;
5,46=4;
5,47=4;
5,48=4;
5,49=4;
5,50=4;
5,51=4;
5,52=4;
5,53=4;
5,54=4;
5,55=4;
5,56=4;
5,57=4;
5,58=4;
5,59=4;
5,60=4;
5,61=4;
5,62=4;
5,63=4;
6,0=5;
6,1=5;
6,2=5;
6,3=1;
6,4=1;
6,5=2;
6,6=2;
6,7=1;
6,8=5;
6,9=5;
6,10=1;
6,11=3;
6,12=3;
6,13=4;
6,14=4;
6,15=4;
6,16=4;
6,17=4;
6,18=4;
6,19=3;
6,20=3;
6,21=1;
6,22=1;
6,23=1;
6,24=5;
6,25=5;
6,26=5;
6,27=1;
6,28=5;
6,29=5;
6,30=5;
6,31=5;
6,32=5;
6,33=5;
6,34=5;
6,35=1;
6,36=1;
6,37=1;
6,38=1;
6,39=1;
6,40=1;
6,41=1;
6,42=1;
6,43=1;
6,44=3;
6,45=3;
6,46=4;
6,47=4;
6,48=4;
6,49=4;
6,50=4;
6,51=4;
6,52=4;
6,53=4;
6,54=4;
6,55=4;
6,56=4;
6,57=4;
6,58=4;
6,59=4;
6,60=4;
6,61=4;
6,62=4;
6,63=4;
7,0=5;
7,1=5;
7,2=5;
7,3=1;
7,4=1;
7,5=1;
7,6=2;
7,7=1;
7,8=5;
7,9=5;
7,10=1;
7,11=3;
7,12=4;
7,13=4;
7,14=4;
7,15=4;
7,16=4;
7,17=4;
7,18=4;
7,19=4;
7,20=3;
7,21=1;
7,22=1;
7,23=1;
7,24=1;
7,25=5;
7,26=5;
7,27=5;
7,28=5;
7,29=5;
7,30=5;
7,31=5;
7,32=5;
7,33=5;
7,34=5;
7,35=1;
7,36=1;
7,37=1;
7,38=1;
7,39=1;
7,40=1;
7,41=1;
7,42=1;
7,43=1;
7,44=1;
7,45=3;
7,46=4;
7,47=4;
7,48=4;
7,49=4;
7,50=4;
7,51=4;
7,52=4;
7,53=4;
7,54=4;
7,55=4;
7,56=4;
7,57=4;
7,58=4;
7,59=4;
7,60=4;
7,61=4;
7,62=4;
7,63=4;
8,0=5;
8,1=5;
8,2=5;
8,3=5;
8,4=1;
8,5=1;
8,6=2;
8,7=1;
8,8=5;
8,9=5;
8,10=1;
8,11=3;
8,12=4;
8,13=4;
8,14=4;
8,15=4;
8,16=4;
8,17=4;
8,18=4;
8,19=4;
8,20=3;
8,21=1;
8,22=1;
8,23=1;
8,24=1;
8,25=5;
8,26=5;
8,27=5;
8,28=5;
8,29=5;
8,30=5;
8,31=5;
8,32=5;
8,33=5;
8,34=5;
8,35=1;
8,36=1;
8,37=1;
8,38=1;
8,39=1;
8,40=1;
8,41=1;
8,42=1;
8,43=1;
8,44=1;
8,45=3;
8,46=3;
8,47=4;
8,48=4;
8,49=4;
8,50=4;
8,51=4;
8,52=4;
8,53=4;
8,54=4;
8,55=4;
8,56=4;
8,57=4;
8,58=4;
8,59=4;
8,60=4;
8,61=4;
8,62=4;
8,63=4;
9,0=5;
9,1=5;
9,2=5;
9,3=5;
9,4=1;
9,5=1;
9,6=2;
9,7=1;
9,8=5;
9,9=5;
9,10=1;
9,11=3;
9,12=3;
9,13=4;
9,14=4;
9,15=4;
9,16=4;
9,17=4;
9,18=4;
9,19=4;
9,20=3;
9,21=1;
9,22=1;
9,23=1;
9,24=5;
9,25=5;
9,26=5;
9,27=5;
9,28=5;
9,29=5;
9,30=5;
9,31=5;
9,32=5;
9,33=5;
9,34=1;
9,35=1;
9,36=1;
9,37=1;
9,38=1;
9,39=1;
9,40=1;
9,41=1;
9,42=1;
9,43=1;
9,44=1;
9,45=3;
9,46=4;
9,47=4;
9,48=4;
9,49=4;
9,50=4;
9,51=4;
9,52=4;
9,53=4;
9,54=4;
9,55=4;
9,56=4;
9,57=4;
9,58=4;
9,59=4;
9,60=4;
9,61=4;
9,62=4;
9,63=4;
10,0=5;
10,1=5;
10,2=5;
10,3=5;
10,4=1;
10,5=2;
10,6=2;
10,7=1;
10,8=5;
10,9=5;
10,10=1;
10,11=1;
10,12=3;
10,13=3;
10,14=4;
10,15=4;
10,16=4;
10,17=4;
10,18=4;
10,19=4;
10,20=3;
10,21=1;
10,22=1;
10,23=1;
10,24=1;
10,25=5;
10,26=5;
10,27=5;
10,28=5;
10,29=5;
10,30=5;
10,31=5;
10,32=5;
10,33=5;
10,34=5;
10,35=1;
10,36=1;
10,37=1;
10,38=1;
10,39=1;
10,40=1;
10,41=1;
10,42=1;
10,43=1;
10,44=1;
10,45=3;
10,46=4;
10,47=4;
10,48=4;
10,49=4;
10,50=4;
10,51=4;
10,52=4;
10,53=4;
10,54=4;
10,55=4;
10,56=4;
10,57=4;
10,58=4;
10,59=4;
10,60=4;
10,61=4;
10,62=4;
10,63=4;
11,0=5;
11,1=5;
11,2=5;
11,3=5;
11,4=1;
11,5=2;
11,6=1;
11,7=1;
11,8=5;
11,9=5;
11,10=1;
11,11=1;
11,12=1;
11,13=3;
11,14=3;
11,15=3;
11,16=4;
11,17=4;
11,18=3;
11,19=3;
11,20=3;
11,21=1;
11,22=1;
11,23=1;
11,24=1;
11,25=5;
11,26=5;
11,27=5;
11,28=5;
11,29=5;
11,30=5;
11,31=5;
11,32=5;
11,33=5;
11,34=5;
11,35=1;
11,36=1;
11,37=1;
11,38=1;
11,39=1;
11,40=1;
11,41=1;
11,42=1;
11,43=1;
11,44=3;
11,45=3;
11,46=4;
11,47=4;
11,48=4;
11,49=4;
11,50=4;
11,51=4;
11,52=4;
11,53=4;
11,54=4;
11,55=4;
11,56=4;
11,57=4;
11,58=4;
11,59=4;
11,60=4;
11,61=4;
11,62=4;
11,63=4;
12,0=5;
12,1=5;
12,2=5;
12,3=5;
12,4=1;
12,5=2;
12,6=1;
12,7=1;
12,8=1;
12,9=1;
12,10=1;
12,11=1;
12,12=1;
12,13=1;
12,14=1;
12,15=3;
12,16=3;
12,17=3;
12,18=3;
12,19=1;
12,20=1;
12,21=1;
12,22=1;
12,23=1;
12,24=1;
12,25=5;
12,26=5;
12,27=5;
12,28=5;
12,29=5;
12,30=5;
12,31=5;
12,32=5;
12,33=5;
12,34=5;
12,35=1;
12,36=1;
12,37=1;
12,38=1;
12,39=1;
12,40=1;
12,41=1;
12,42=1;
12,43=3;
12,44=3;
12,45=4;
12,46=4;
12,47=4;
12,48=4;
12,49=4;
12,50=4;
12,51=4;
12,52=4;
12,53=4;
12,54=4;
12,55=4;
12,56=4;
12,57=4;
12,58=4;
12,59=4;
12,60=4;
12,61=4;
12,62=4;
12,63=4;
13,0=5;
13,1=5;
13,2=5;
13,3=5;
13,4=1;
13,5=2;
13,6=2;
13,7=2;
13,8=2;
13,9=2;
13,10=1;
13,11=5;
13,12=5;
13,13=5;
13,14=1;
13,15=1;
13,16=1;
13,17=1;
13,18=1;
13,19=1;
13,20=1;
13,21=1;
13,22=1;
13,23=1;
13,24=1;
13,25=5;
13,26=5;
13,27=5;
13,28=5;
13,29=5;
13,30=5;
13,31=5;
13,32=5;
13,33=5;
13,34=5;
13,35=1;
13,36=1;
13,37=1;
13,38=1;
13,39=1;
13,40=1;
13,41=1;
13,42=3;
13,43=3;
13,44=4;
13,45=4;
13,46=4;
13,47=4;
13,48=4;
13,49=4;
13,50=4;
13,51=4;
13,52=4;
13,53=4;
13,54=4;
13,55=4;
13,56=4;
13,57=4;
13,58=4;
13,59=4;
13,60=4;
13,61=4;
13,62=4;
13,63=4;
14,0=5;
14,1=5;
14,2=5;
14,3=1;
14,4=1;
14,5=1;
14,6=1;
14,7=1;
14,8=1;
14,9=2;
14,10=1;
14,11=5;
14,12=5;
14,13=5;
14,14=5;
14,15=5;
14,16=5;
14,17=5;
14,18=5;
14,19=5;
14,20=5;
14,21=5;
14,22=1;
14,23=1;
14,24=1;
14,25=1;
14,26=1;
14,27=1;
14,28=5;
14,29=5;
14,30=5;
14,31=5;
14,32=5;
14,33=5;
14,34=5;
14,35=1;
14,36=1;
14,37=1;
14,38=1;
14,39=1;
14,40=1;
14,41=1;
14,42=3;
14,43=4;
14,44=4;
14,45=4;
14,46=4;
14,47=4;
14,48=4;
14,49=4;
14,50=4;
14,51=4;
14,52=4;
14,53=4;
14,54=4;
14,55=4;
14,56=4;
14,57=4;
14,58=4;
14,59=4;
14,60=4;
14,61=4;
14,62=4;
14,63=4;
15,0=5;
15,1=5;
15,2=5;
15,3=5;
15,4=5;
15,5=5;
15,6=5;
15,7=5;
15,8=1;
15,9=2;
15,10=1;
15,11=5;
15,12=5;
15,13=5;
15,14=5;
15,15=5;
15,16=5;
15,17=5;
15,18=5;
15,19=5;
15,20=5;
15,21=5;
15,22=1;
15,23=1;
15,24=1;
15,25=1;
15,26=1;
15,27=1;
15,28=1;
15,29=1;
15,30=1;
15,31=1;
15,32=1;
15,33=1;
15,34=5;
15,35=1;
15,36=1;
15,37=1;
15,38=1;
15,39=1;
15,40=3;
15,41=3;
15,42=3;
15,43=4;
15,44=4;
15,45=4;
15,46=4;
15,47=4;
15,48=4;
15,49=4;
15,50=4;
15,51=4;
15,52=4;
15,53=4;
15,54=4;
15,55=3;
15,56=3;
15,57=3;
15,58=3;
15,59=3;
15,60=3;
15,61=3;
15,62=3;
15,63=3;
16,0=5;
16,1=5;
16,2=5;
16,3=5;
16,4=5;
16,5=1;
16,6=1;
16,7=1;
16,8=1;
16,9=2;
16,10=1;
16,11=1;
16,12=1;
16,13=1;
16,14=1;
16,15=1;
16,16=1;
16,17=1;
16,18=1;
16,19=1;
16,20=1;
16,21=1;
16,22=1;
16,23=1;
16,24=1;
16,25=1;
16,26=1;
16,27=1;
16,28=1;
16,29=1;
16,30=1;
16,31=1;
16,32=1;
16,33=1;
16,34=1;
16,35=1;
16,36=1;
16,37=1;
16,38=1;
16,39=1;
16,40=3;
16,41=4;
16,42=4;
16,43=4;
16,44=4;
16,45=4;
16,46=4;
16,47=4;
16,48=4;
16,49=4;
16,50=4;
16,51=4;
16,52=4;
16,53=4;
16,54=3;
16,55=3;
16,56=1;
16,57=1;
16,58=1;
16,59=1;
16,60=1;
16,61=1;
16,62=1;
16,63=1;
17,0=5;
17,1=5;
17,2=5;
17,3=5;
17,4=5;
17,5=5;
17,6=1;
17,7=1;
17,8=1;
17,9=2;
17,10=1;
17,11=1;
17,12=1;
17,13=1;
17,14=1;
17,15=1;
17,16=1;
17,17=1;
17,18=1;
17,19=1;
17,20=1;
17,21=1;
17,22=1;
17,23=1;
17,24=5;
17,25=5;
17,26=5;
17,27=5;
17,28=1;
17,29=1;
17,30=1;
17,31=1;
17,32=1;
17,33=1;
17,34=1;
17,35=1;
17,36=1;
17,37=1;
17,38=1;
17,39=3;
17,40=3;
17,41=4;
17,42=4;
17,43=4;
17,44=4;
17,45=4;
17,46=4;
17,47=4;
17,48=4;
17,49=4;
17,50=4;
17,51=4;
17,52=4;
17,53=4;
17,54=3;
17,55=1;
17,56=1;
17,57=1;
17,58=1;
17,59=1;
17,60=1;
17,61=1;
17,62=1;
17,63=1;
18,0=5;
18,1=5;
18,2=5;
18,3=5;
18,4=5;
18,5=5;
18,6=1;
18,7=1;
18,8=1;
18,9=2;
18,10=1;
18,11=1;
18,12=1;
18,13=1;
18,14=1;
18,15=1;
18,16=1;
18,17=1;
18,18=1;
18,19=1;
18,20=1;
18,21=1;
18,22=1;
18,23=5;
18,24=5;
18,25=5;
18,26=5;
18,27=5;
18,28=5;
18,29=5;
18,30=5;
18,31=5;
18,32=1;
18,33=1;
18,34=1;
18,35=1;
18,36=1;
18,37=1;
18,38=3;
18,39=3;
18,40=4;
18,41=4;
18,42=4;
18,43=4;
18,44=4;
18,45=4;
18,46=4;
18,47=4;
18,48=4;
18,49=4;
18,50=4;
18,51=4;
18,52=4;
18,53=3;
18,54=3;
18,55=1;
18,56=1;
18,57=1;
18,58=1;
18,59=1;
18,60=1;
18,61=1;
18,62=1;
18,63=1;
19,0=5;
19,1=1;
19,2=5;
19,3=5;
19,4=5;
19,5=5;
19,6=1;
19,7=1;
19,8=1;
19,9=2;
19,10=2;
19,11=1;
19,12=1;
19,13=1;
19,14=1;
19,15=1;
19,16=1;
19,17=1;
19,18=1;
19,19=1;
19,20=1;
19,21=1;
19,22=1;
19,23=5;
19,24=5;
19,25=5;
19,26=5;
19,27=5;
19,28=5;
19,29=5;
19,30=5;
19,31=5;
19,32=5;
19,33=1;
19,34=1;
19,35=1;
19,36=1;
19,37=1;
19,38=3;
19,39=4;
19,40=4;
19,41=4;
19,42=4;
19,43=4;
19,44=4;
19,45=4;
19,46=4;
19,47=4;
19,48=4;
19,49=4;
19,50=4;
19,51=3;
19,52=3;
19,53=3;
19,54=1;
19,55=1;
19,56=1;
19,57=1;
19,58=1;
19,59=1;
19,60=1;
19,61=1;
19,62=1;
19,63=1;
20,0=1;
20,1=5;
20,2=1;
20,3=5;
20,4=5;
20,5=5;
20,6=5;
20,7=1;
20,8=1;
20,9=1;
20,10=2;
20,11=2;
20,12=1;
20,13=1;
20,14=1;
20,15=1;
20,16=1;
20,17=1;
20,18=1;
20,19=1;
20,20=1;
20,21=1;
20,22=1;
20,23=5;
20,24=5;
20,25=5;
20,26=5;
20,27=5;
20,28=5;
20,29=5;
20,30=5;
20,31=5;
20,32=5;
20,33=1;
20,34=1;
20,35=1;
20,36=1;
20,37=1;
20,38=3;
20,39=4;
20,40=4;
20,41=4;
20,42=4;
20,43=4;
20,44=4;
20,45=4;
20,46=4;
20,47=4;
20,48=4;
20,49=4;
20,50=3;
20,51=3;
20,52=1;
20,53=1;
20,54=1;
20,55=1;
20,56=1;
20,57=1;
20,58=1;
20,59=1;
20,60=1;
20,61=1;
20,62=1;
20,63=1;
21,0=1;
21,1=5;
21,2=5;
21,3=5;
21,4=5;
21,5=5;
21,6=1;
21,7=1;
21,8=1;
21,9=1;
21,10=2;
21,11=2;
21,12=1;
21,13=1;
21,14=1;
21,15=1;
21,16=1;
21,17=1;
21,18=1;
21,19=1;
21,20=1;
21,21=1;
21,22=5;
21,23=5;
21,24=5;
21,25=5;
21,26=5;
21,27=5;
21,28=5;
21,29=5;
21,30=5;
21,31=5;
21,32=5;
21,33=5;
21,34=5;
21,35=1;
21,36=1;
21,37=1;
21,38=3;
21,39=4;
21,40=4;
21,41=4;
21,42=4;
21,43=4;
21,44=4;
21,45=4;
21,46=4;
21,47=4;
21,48=4;
21,49=3;
21,50=3;
21,51=1;
21,52=1;
21,53=1;
21,54=1;
21,55=1;
21,56=1;
21,57=1;
21,58=1;
21,59=1;
21,60=1;
21,61=1;
21,62=1;
21,63=1;
22,0=1;
22,1=5;
22,2=5;
22,3=5;
22,4=5;
22,5=5;
22,6=5;
22,7=5;
22,8=1;
22,9=1;
22,10=1;
22,11=2;
22,12=2;
22,13=2;
22,14=1;
22,15=1;
22,16=1;
22,17=1;
22,18=1;
22,19=1;
22,20=1;
22,21=1;
22,22=1;
22,23=5;
22,24=5;
22,25=5;
22,26=5;
22,27=5;
22,28=5;
22,29=5;
22,30=5;
22,31=5;
22,32=5;
22,33=5;
22,34=5;
22,35=1;
22,36=1;
22,37=1;
22,38=3;
22,39=4;
22,40=4;
22,41=4;
22,42=4;
22,43=4;
22,44=4;
22,45=4;
22,46=4;
22,47=4;
22,48=3;
22,49=3;
22,50=1;
22,51=1;
22,52=1;
22,53=1;
22,54=1;
22,55=1;
22,56=1;
22,57=1;
22,58=1;
22,59=1;
22,60=1;
22,61=1;
22,62=1;
22,63=1;
23,0=5;
23,1=5;
23,2=5;
23,3=5;
23,4=5;
23,5=5;
23,6=5;
23,7=5;
23,8=1;
23,9=1;
23,10=1;
23,11=1;
23,12=1;
23,13=2;
23,14=2;
23,15=1;
23,16=1;
23,17=1;
23,18=1;
23,19=1;
23,20=1;
23,21=1;
23,22=1;
23,23=5;
23,24=5;
23,25=5;
23,26=5;
23,27=5;
23,28=5;
23,29=5;
23,30=5;
23,31=5;
23,32=5;
23,33=5;
23,34=5;
23,35=1;
23,36=1;
23,37=1;
23,38=3;
23,39=3;
23,40=3;
23,41=4;
23,42=4;
23,43=4;
23,44=4;
23,45=4;
23,46=3;
23,47=3;
23,48=3;
23,49=1;
23,50=1;
23,51=1;
23,52=1;
23,53=1;
23,54=1;
23,55=1;
23,56=5;
23,57=5;
23,58=5;
23,59=5;
23,60=1;
23,61=1;
23,62=1;
23,63=1;
24,0=5;
24,1=5;
24,2=5;
24,3=5;
24,4=5;
24,5=5;
24,6=5;
24,7=5;
24,8=5;
24,9=5;
24,10=1;
24,11=1;
24,12=1;
24,13=1;
24,14=2;
24,15=2;
24,16=2;
24,17=2;
24,18=2;
24,19=2;
24,20=1;
24,21=1;
24,22=1;
24,23=1;
24,24=5;
24,25=5;
24,26=5;
24,27=5;
24,28=5;
24,29=5;
24,30=5;
24,31=5;
24,32=5;
24,33=5;
24,34=5;
24,35=1;
24,36=1;
24,37=1;
24,38=1;
24,39=1;
24,40=3;
24,41=3;
24,42=3;
24,43=3;
24,44=3;
24,45=3;
24,46=3;
24,47=1;
24,48=1;
24,49=1;
24,50=1;
24,51=1;
24,52=1;
24,53=1;
24,54=5;
24,55=5;
24,56=1;
24,57=5;
24,58=5;
24,59=5;
24,60=5;
24,61=5;
24,62=5;
24,63=1;
25,0=1;
25,1=5;
25,2=5;
25,3=5;
25,4=5;
25,5=5;
25,6=5;
25,7=5;
25,8=5;
25,9=5;
25,10=5;
25,11=1;
25,12=1;
25,13=1;
25,14=1;
25,15=1;
25,16=1;
25,17=1;
25,18=1;
25,19=2;
25,20=1;
25,21=1;
25,22=1;
25,23=1;
25,24=1;
25,25=1;
25,26=1;
25,27=1;
25,28=5;
25,29=5;
25,30=5;
25,31=5;
25,32=5;
25,33=5;
25,34=1;
25,35=1;
25,36=1;
25,37=1;
25,38=1;
25,39=1;
25,40=1;
25,41=1;
25,42=1;
25,43=1;
25,44=1;
25,45=1;
25,46=1;
25,47=1;
25,48=1;
25,49=1;
25,50=1;
25,51=1;
25,52=1;
25,53=5;
25,54=5;
25,55=5;
25,56=5;
25,57=5;
25,58=5;
25,59=5;
25,60=5;
25,61=5;
25,62=5;
25,63=1;
26,0=5;
26,1=5;
26,2=5;
26,3=5;
26,4=5;
26,5=5;
26,6=5;
26,7=5;
26,8=5;
26,9=5;
26,10=5;
26,11=5;
26,12=5;
26,13=1;
26,14=1;
26,15=1;
26,16=1;
26,17=1;
26,18=1;
26,19=2;
26,20=2;
26,21=1;
26,22=1;
26,23=1;
26,24=1;
26,25=1;
26,26=1;
26,27=1;
26,28=1;
26,29=1;
26,30=1;
26,31=1;
26,32=1;
26,33=5;
26,34=1;
26,35=1;
26,36=1;
26,37=1;
26,38=1;
26,39=1;
26,40=1;
26,41=1;
26,42=1;
26,43=5;
26,44=5;
26,45=5;
26,46=5;
26,47=5;
26,48=1;
26,49=1;
26,50=1;
26,51=1;
26,52=5;
26,53=5;
26,54=5;
26,55=5;
26,56=1;
26,57=5;
26,58=1;
26,59=5;
26,60=5;
26,61=5;
26,62=5;
26,63=1;
27,0=1;
27,1=5;
27,2=5;
27,3=5;
27,4=5;
27,5=5;
27,6=5;
27,7=5;
27,8=5;
27,9=5;
27,10=5;
27,11=5;
27,12=5;
27,13=5;
27,14=1;
27,15=1;
27,16=1;
27,17=1;
27,18=1;
27,19=1;
27,20=2;
27,21=2;
27,22=1;
27,23=1;
27,24=1;
27,25=1;
27,26=1;
27,27=1;
27,28=1;
27,29=1;
27,30=1;
27,31=1;
27,32=1;
27,33=1;
27,34=1;
27,35=1;
27,36=1;
27,37=1;
27,38=1;
27,39=1;
27,40=1;
27,41=1;
27,42=5;
27,43=5;
27,44=5;
27,45=5;
27,46=5;
27,47=5;
27,48=1;
27,49=1;
27,50=1;
27,51=5;
27,52=5;
27,53=5;
27,54=5;
27,55=1;
27,56=5;
27,57=5;
27,58=5;
27,59=5;
27,60=5;
27,61=1;
27,62=5;
27,63=1;
28,0=1;
28,1=5;
28,2=5;
28,3=1;
28,4=5;
28,5=5;
28,6=1;
28,7=1;
28,8=5;
28,9=5;
28,10=5;
28,11=5;
28,12=5;
28,13=1;
28,14=1;
28,15=1;
28,16=1;
28,17=1;
28,18=1;
28,19=1;
28,20=1;
28,21=2;
28,22=2;
28,23=1;
28,24=1;
28,25=1;
28,26=1;
28,27=1;
28,28=1;
28,29=1;
28,30=1;
28,31=1;
28,32=1;
28,33=1;
28,34=1;
28,35=1;
28,36=1;
28,37=1;
28,38=1;
28,39=5;
28,40=5;
28,41=5;
28,42=1;
28,43=5;
28,44=5;
28,45=5;
28,46=5;
28,47=5;
28,48=1;
28,49=1;
28,50=1;
28,51=5;
28,52=5;
28,53=5;
28,54=5;
28,55=5;
28,56=5;
28,57=5;
28,58=5;
28,59=5;
28,60=1;
28,61=5;
28,62=5;
28,63=1;
29,0=1;
29,1=5;
29,2=1;
29,3=1;
29,4=1;
29,5=1;
29,6=1;
29,7=1;
29,8=1;
29,9=1;
29,10=1;
29,11=1;
29,12=1;
29,13=1;
29,14=1;
29,15=1;
29,16=1;
29,17=1;
29,18=1;
29,19=1;
29,20=1;
29,21=1;
29,22=2;
29,23=1;
29,24=1;
29,25=1;
29,26=1;
29,27=1;
29,28=1;
29,29=1;
29,30=1;
29,31=1;
29,32=1;
29,33=1;
29,34=1;
29,35=1;
29,36=1;
29,37=1;
29,38=5;
29,39=5;
29,40=1;
29,41=5;
29,42=5;
29,43=5;
29,44=5;
29,45=5;
29,46=5;
29,47=1;
29,48=1;
29,49=1;
29,50=1;
29,51=1;
29,52=1;
29,53=5;
29,54=1;
29,55=5;
29,56=5;
29,57=5;
29,58=5;
29,59=5;
29,60=5;
29,61=5;
29,62=1;
29,63=1;
30,0=1;
30,1=1;
30,2=1;
30,3=1;
30,4=1;
30,5=1;
30,6=1;
30,7=1;
30,8=1;
30,9=1;
30,10=1;
30,11=1;
30,12=1;
30,13=1;
30,14=1;
30,15=1;
30,16=1;
30,17=1;
30,18=1;
30,19=1;
30,20=1;
30,21=1;
30,22=2;
30,23=2;
30,24=1;
30,25=1;
30,26=1;
30,27=1;
30,28=1;
30,29=1;
30,30=1;
30,31=1;
30,32=1;
30,33=1;
30,34=1;
30,35=5;
30,36=5;
30,37=5;
30,38=5;
30,39=5;
30,40=5;
30,41=5;
30,42=5;
30,43=5;
30,44=5;
30,45=5;
30,46=5;
30,47=1;
30,48=1;
30,49=1;
30,50=1;
30,51=1;
30,52=1;
30,53=1;
30,54=1;
30,55=5;
30,56=1;
30,57=1;
30,58=1;
30,59=1;
30,60=1;
30,61=1;
30,62=1;
30,63=1;
31,0=1;
31,1=1;
31,2=1;
31,3=1;
31,4=1;
31,5=1;
31,6=3;
31,7=3;
31,8=3;
31,9=3;
31,10=3;
31,11=3;
31,12=3;
31,13=3;
31,14=3;
31,15=3;
31,16=1;
31,17=1;
31,18=1;
31,19=1;
31,20=1;
31,21=1;
31,22=1;
31,23=2;
31,24=2;
31,25=1;
31,26=1;
31,27=1;
31,28=1;
31,29=1;
31,30=1;
31,31=1;
31,32=1;
31,33=1;
31,34=1;
31,35=5;
31,36=1;
31,37=1;
31,38=5;
31,39=5;
31,40=5;
31,41=5;
31,42=1;
31,43=5;
31,44=5;
31,45=1;
31,46=1;
31,47=1;
31,48=1;
31,49=1;
31,50=1;
31,51=1;
31,52=1;
31,53=1;
31,54=1;
31,55=1;
31,56=1;
31,57=1;
31,58=1;
31,59=1;
31,60=1;
31,61=1;
31,62=1;
31,63=1;
32,0=1;
32,1=1;
32,2=1;
32,3=1;
32,4=3;
32,5=3;
32,6=3;
32,7=4;
32,8=4;
32,9=4;
32,10=4;
32,11=4;
32,12=4;
32,13=4;
32,14=4;
32,15=3;
32,16=3;
32,17=3;
32,18=1;
32,19=1;
32,20=1;
32,21=1;
32,22=1;
32,23=1;
32,24=2;
32,25=2;
32,26=1;
32,27=1;
32,28=1;
32,29=1;
32,30=1;
32,31=1;
32,32=1;
32,33=1;
32,34=1;
32,35=5;
32,36=5;
32,37=5;
32,38=1;
32,39=5;
32,40=5;
32,41=5;
32,42=5;
32,43=1;
32,44=1;
32,45=1;
32,46=1;
32,47=1;
32,48=1;
32,49=1;
32,50=1;
32,51=1;
32,52=2;
32,53=2;
32,54=2;
32,55=2;
32,56=2;
32,57=2;
32,58=2;
32,59=2;
32,60=2;
32,61=2;
32,62=2;
32,63=2;
33,0=1;
33,1=1;
33,2=1;
33,3=3;
33,4=3;
33,5=4;
33,6=4;
33,7=4;
33,8=4;
33,9=4;
33,10=4;
33,11=4;
33,12=4;
33,13=4;
33,14=4;
33,15=4;
33,16=4;
33,17=3;
33,18=1;
33,19=1;
33,20=1;
33,21=5;
33,22=1;
33,23=1;
33,24=1;
33,25=2;
33,26=2;
33,27=1;
33,28=1;
33,29=1;
33,30=1;
33,31=1;
33,32=1;
33,33=1;
33,34=1;
33,35=1;
33,36=1;
33,37=1;
33,38=5;
33,39=1;
33,40=1;
33,41=1;
33,42=1;
33,43=1;
33,44=1;
33,45=1;
33,46=1;
33,47=1;
33,48=2;
33,49=2;
33,50=2;
33,51=2;
33,52=2;
33,53=1;
33,54=1;
33,55=1;
33,56=1;
33,57=1;
33,58=1;
33,59=1;
33,60=1;
33,61=1;
33,62=1;
33,63=1;
34,0=1;
34,1=1;
34,2=3;
34,3=3;
34,4=4;
34,5=4;
34,6=4;
34,7=4;
34,8=4;
34,9=4;
34,10=4;
34,11=4;
34,12=4;
34,13=4;
34,14=4;
34,15=4;
34,16=4;
34,17=3;
34,18=1;
34,19=1;
34,20=1;
34,21=5;
34,22=5;
34,23=1;
34,24=1;
34,25=1;
34,26=2;
34,27=2;
34,28=2;
34,29=1;
34,30=1;
34,31=1;
34,32=1;
34,33=1;
34,34=1;
34,35=1;
34,36=1;
34,37=1;
34,38=1;
34,39=1;
34,40=1;
34,41=1;
34,42=1;
34,43=1;
34,44=2;
34,45=2;
34,46=2;
34,47=2;
34,48=2;
34,49=1;
34,50=1;
34,51=1;
34,52=1;
34,53=1;
34,54=1;
34,55=1;
34,56=1;
34,57=1;
34,58=1;
34,59=1;
34,60=1;
34,61=1;
34,62=1;
34,63=1;
35,0=1;
35,1=1;
35,2=3;
35,3=4;
35,4=4;
35,5=4;
35,6=4;
35,7=4;
35,8=4;
35,9=4;
35,10=4;
35,11=4;
35,12=4;
35,13=4;
35,14=4;
35,15=4;
35,16=4;
35,17=3;
35,18=3;
35,19=1;
35,20=1;
35,21=5;
35,22=5;
35,23=5;
35,24=1;
35,25=1;
35,26=1;
35,27=1;
35,28=2;
35,29=2;
35,30=2;
35,31=2;
35,32=2;
35,33=2;
35,34=1;
35,35=1;
35,36=1;
35,37=1;
35,38=1;
35,39=2;
35,40=2;
35,41=2;
35,42=2;
35,43=2;
35,44=2;
35,45=1;
35,46=1;
35,47=1;
35,48=1;
35,49=1;
35,50=1;
35,51=1;
35,52=1;
35,53=1;
35,54=5;
35,55=5;
35,56=5;
35,57=1;
35,58=1;
35,59=1;
35,60=1;
35,61=1;
35,62=1;
35,63=1;
36,0=1;
36,1=3;
36,2=3;
36,3=4;
36,4=4;
36,5=4;
36,6=4;
36,7=4;
36,8=4;
36,9=4;
36,10=4;
36,11=4;
36,12=4;
36,13=4;
36,14=4;
36,15=4;
36,16=4;
36,17=4;
36,18=3;
36,19=1;
36,20=5;
36,21=5;
36,22=5;
36,23=5;
36,24=1;
36,25=1;
36,26=1;
36,27=1;
36,28=1;
36,29=1;
36,30=1;
36,31=1;
36,32=1;
36,33=2;
36,34=2;
36,35=2;
36,36=2;
36,37=2;
36,38=2;
36,39=2;
36,40=1;
36,41=1;
36,42=1;
36,43=1;
36,44=1;
36,45=1;
36,46=1;
36,47=1;
36,48=1;
36,49=1;
36,50=1;
36,51=1;
36,52=1;
36,53=5;
36,54=5;
36,55=5;
36,56=5;
36,57=1;
36,58=1;
36,59=1;
36,60=1;
36,61=1;
36,62=1;
36,63=5;
37,0=1;
37,1=3;
37,2=3;
37,3=4;
37,4=4;
37,5=4;
37,6=4;
37,7=4;
37,8=4;
37,9=4;
37,10=4;
37,11=4;
37,12=4;
37,13=4;
37,14=4;
37,15=4;
37,16=4;
37,17=4;
37,18=3;
37,19=1;
37,20=5;
37,21=5;
37,22=5;
37,23=5;
37,24=1;
37,25=1;
37,26=1;
37,27=1;
37,28=1;
37,29=1;
37,30=1;
37,31=1;
37,32=1;
37,33=1;
37,34=1;
37,35=1;
37,36=2;
37,37=2;
37,38=1;
37,39=1;
37,40=1;
37,41=1;
37,42=1;
37,43=1;
37,44=1;
37,45=1;
37,46=1;
37,47=1;
37,48=1;
37,49=1;
37,50=1;
37,51=5;
37,52=5;
37,53=5;
37,54=5;
37,55=5;
37,56=5;
37,57=1;
37,58=1;
37,59=1;
37,60=1;
37,61=1;
37,62=5;
37,63=5;
38,0=1;
38,1=3;
38,2=3;
38,3=4;
38,4=4;
38,5=4;
38,6=4;
38,7=4;
38,8=4;
38,9=4;
38,10=4;
38,11=4;
38,12=4;
38,13=4;
38,14=4;
38,15=4;
38,16=4;
38,17=4;
38,18=3;
38,19=1;
38,20=5;
38,21=5;
38,22=1;
38,23=1;
38,24=1;
38,25=3;
38,26=3;
38,27=3;
38,28=3;
38,29=1;
38,30=1;
38,31=1;
38,32=1;
38,33=1;
38,34=1;
38,35=1;
38,36=1;
38,37=2;
38,38=1;
38,39=1;
38,40=1;
38,41=1;
38,42=1;
38,43=5;
38,44=5;
38,45=5;
38,46=5;
38,47=5;
38,48=5;
38,49=5;
38,50=5;
38,51=5;
38,52=5;
38,53=5;
38,54=5;
38,55=5;
38,56=5;
38,57=5;
38,58=1;
38,59=1;
38,60=1;
38,61=1;
38,62=5;
38,63=5;
39,0=1;
39,1=1;
39,2=3;
39,3=4;
39,4=4;
39,5=4;
39,6=4;
39,7=4;
39,8=4;
39,9=4;
39,10=4;
39,11=4;
39,12=4;
39,13=4;
39,14=4;
39,15=4;
39,16=4;
39,17=4;
39,18=3;
39,19=1;
39,20=1;
39,21=1;
39,22=1;
39,23=3;
39,24=3;
39,25=3;
39,26=4;
39,27=4;
39,28=3;
39,29=1;
39,30=1;
39,31=5;
39,32=5;
39,33=5;
39,34=1;
39,35=1;
39,36=1;
39,37=2;
39,38=2;
39,39=1;
39,40=1;
39,41=1;
39,42=5;
39,43=5;
39,44=5;
39,45=5;
39,46=5;
39,47=5;
39,48=5;
39,49=5;
39,50=5;
39,51=5;
39,52=5;
39,53=5;
39,54=5;
39,55=5;
39,56=1;
39,57=1;
39,58=1;
39,59=1;
39,60=1;
39,61=5;
39,62=5;
39,63=5;
40,0=1;
40,1=1;
40,2=3;
40,3=4;
40,4=4;
40,5=4;
40,6=4;
40,7=4;
40,8=4;
40,9=4;
40,10=4;
40,11=4;
40,12=4;
40,13=4;
40,14=4;
40,15=3;
40,16=3;
40,17=3;
40,18=3;
40,19=1;
40,20=1;
40,21=1;
40,22=3;
40,23=3;
40,24=4;
40,25=4;
40,26=4;
40,27=3;
40,28=3;
40,29=1;
40,30=1;
40,31=5;
40,32=5;
40,33=5;
40,34=5;
40,35=5;
40,36=1;
40,37=1;
40,38=2;
40,39=1;
40,40=1;
40,41=1;
40,42=5;
40,43=5;
40,44=5;
40,45=5;
40,46=5;
40,47=5;
40,48=5;
40,49=5;
40,50=5;
40,51=5;
40,52=5;
40,53=5;
40,54=5;
40,55=1;
40,56=1;
40,57=1;
40,58=1;
40,59=1;
40,60=5;
40,61=5;
40,62=5;
40,63=5;
41,0=1;
41,1=1;
41,2=3;
41,3=3;
41,4=4;
41,5=4;
41,6=4;
41,7=4;
41,8=4;
41,9=4;
41,10=4;
41,11=4;
41,12=4;
41,13=4;
41,14=4;
41,15=3;
41,16=1;
41,17=1;
41,18=1;
41,19=1;
41,20=1;
41,21=3;
41,22=3;
41,23=4;
41,24=4;
41,25=3;
41,26=3;
41,27=3;
41,28=1;
41,29=1;
41,30=5;
41,31=5;
41,32=5;
41,33=5;
41,34=5;
41,35=5;
41,36=1;
41,37=1;
41,38=2;
41,39=1;
41,40=1;
41,41=1;
41,42=1;
41,43=5;
41,44=5;
41,45=5;
41,46=5;
41,47=5;
41,48=5;
41,49=5;
41,50=5;
41,51=5;
41,52=5;
41,53=5;
41,54=1;
41,55=1;
41,56=1;
41,57=1;
41,58=1;
41,59=5;
41,60=5;
41,61=5;
41,62=5;
41,63=5;
42,0=5;
42,1=1;
42,2=1;
42,3=3;
42,4=4;
42,5=4;
42,6=4;
42,7=4;
42,8=4;
42,9=4;
42,10=4;
42,11=4;
42,12=4;
42,13=4;
42,14=4;
42,15=3;
42,16=1;
42,17=5;
42,18=5;
42,19=5;
42,20=1;
42,21=3;
42,22=4;
42,23=4;
42,24=3;
42,25=3;
42,26=1;
42,27=1;
42,28=1;
42,29=1;
42,30=5;
42,31=1;
42,32=1;
42,33=1;
42,34=1;
42,35=1;
42,36=1;
42,37=1;
42,38=2;
42,39=2;
42,40=1;
42,41=1;
42,42=1;
42,43=5;
42,44=5;
42,45=5;
42,46=5;
42,47=5;
42,48=5;
42,49=5;
42,50=5;
42,51=5;
42,52=5;
42,53=5;
42,54=1;
42,55=1;
42,56=1;
42,57=1;
42,58=1;
42,59=5;
42,60=5;
42,61=5;
42,62=5;
42,63=5;
43,0=5;
43,1=5;
43,2=1;
43,3=3;
43,4=3;
43,5=4;
43,6=4;
43,7=4;
43,8=4;
43,9=4;
43,10=4;
43,11=3;
43,12=3;
43,13=4;
43,14=4;
43,15=3;
43,16=1;
43,17=5;
43,18=5;
43,19=1;
43,20=1;
43,21=3;
43,22=4;
43,23=3;
43,24=3;
43,25=1;
43,26=1;
43,27=1;
43,28=1;
43,29=1;
43,30=1;
43,31=1;
43,32=1;
43,33=1;
43,34=1;
43,35=1;
43,36=1;
43,37=1;
43,38=1;
43,39=2;
43,40=2;
43,41=1;
43,42=1;
43,43=1;
43,44=5;
43,45=5;
43,46=5;
43,47=5;
43,48=5;
43,49=5;
43,50=5;
43,51=5;
43,52=5;
43,53=5;
43,54=1;
43,55=1;
43,56=1;
43,57=1;
43,58=1;
43,59=5;
43,60=5;
43,61=5;
43,62=5;
43,63=5;
44,0=1;
44,1=5;
44,2=1;
44,3=1;
44,4=3;
44,5=3;
44,6=4;
44,7=3;
44,8=3;
44,9=3;
44,10=3;
44,11=3;
44,12=3;
44,13=3;
44,14=4;
44,15=3;
44,16=3;
44,17=1;
44,18=1;
44,19=1;
44,20=3;
44,21=3;
44,22=4;
44,23=3;
44,24=3;
44,25=1;
44,26=1;
44,27=1;
44,28=1;
44,29=1;
44,30=3;
44,31=3;
44,32=3;
44,33=3;
44,34=3;
44,35=1;
44,36=1;
44,37=1;
44,38=1;
44,39=1;
44,40=2;
44,41=1;
44,42=1;
44,43=1;
44,44=5;
44,45=5;
44,46=5;
44,47=5;
44,48=5;
44,49=5;
44,50=5;
44,51=5;
44,52=5;
44,53=5;
44,54=1;
44,55=1;
44,56=1;
44,57=1;
44,58=1;
44,59=5;
44,60=5;
44,61=5;
44,62=5;
44,63=5;
45,0=1;
45,1=5;
45,2=1;
45,3=1;
45,4=3;
45,5=3;
45,6=3;
45,7=3;
45,8=1;
45,9=1;
45,10=1;
45,11=1;
45,12=1;
45,13=3;
45,14=4;
45,15=4;
45,16=3;
45,17=3;
45,18=3;
45,19=3;
45,20=3;
45,21=4;
45,22=4;
45,23=4;
45,24=3;
45,25=3;
45,26=3;
45,27=3;
45,28=3;
45,29=3;
45,30=3;
45,31=4;
45,32=4;
45,33=4;
45,34=3;
45,35=1;
45,36=1;
45,37=1;
45,38=1;
45,39=1;
45,40=2;
45,41=1;
45,42=1;
45,43=5;
45,44=5;
45,45=5;
45,46=5;
45,47=5;
45,48=5;
45,49=5;
45,50=5;
45,51=5;
45,52=1;
45,53=1;
45,54=1;
45,55=1;
45,56=1;
45,57=1;
45,58=5;
45,59=5;
45,60=5;
45,61=5;
45,62=5;
45,63=5;
46,0=1;
46,1=1;
46,2=1;
46,3=1;
46,4=1;
46,5=1;
46,6=1;
46,7=1;
46,8=1;
46,9=1;
46,10=5;
46,11=5;
46,12=1;
46,13=3;
46,14=3;
46,15=4;
46,16=4;
46,17=3;
46,18=3;
46,19=4;
46,20=4;
46,21=4;
46,22=3;
46,23=4;
46,24=4;
46,25=4;
46,26=4;
46,27=4;
46,28=4;
46,29=4;
46,30=4;
46,31=4;
46,32=3;
46,33=3;
46,34=3;
46,35=1;
46,36=1;
46,37=1;
46,38=1;
46,39=1;
46,40=2;
46,41=1;
46,42=1;
46,43=5;
46,44=5;
46,45=5;
46,46=5;
46,47=5;
46,48=5;
46,49=5;
46,50=1;
46,51=5;
46,52=1;
46,53=1;
46,54=1;
46,55=1;
46,56=1;
46,57=1;
46,58=5;
46,59=5;
46,60=5;
46,61=5;
46,62=5;
46,63=5;
47,0=1;
47,1=5;
47,2=1;
47,3=1;
47,4=5;
47,5=5;
47,6=1;
47,7=5;
47,8=5;
47,9=5;
47,10=5;
47,11=5;
47,12=1;
47,13=1;
47,14=3;
47,15=3;
47,16=4;
47,17=4;
47,18=4;
47,19=4;
47,20=3;
47,21=3;
47,22=3;
47,23=3;
47,24=3;
47,25=3;
47,26=3;
47,27=3;
47,28=3;
47,29=3;
47,30=3;
47,31=3;
47,32=3;
47,33=1;
47,34=1;
47,35=1;
47,36=1;
47,37=1;
47,38=1;
47,39=1;
47,40=2;
47,41=1;
47,42=1;
47,43=1;
47,44=1;
47,45=5;
47,46=5;
47,47=5;
47,48=1;
47,49=1;
47,50=1;
47,51=5;
47,52=1;
47,53=1;
47,54=1;
47,55=1;
47,56=1;
47,57=1;
47,58=5;
47,59=5;
47,60=5;
47,61=5;
47,62=5;
47,63=5;
48,0=1;
48,1=5;
48,2=5;
48,3=5;
48,4=5;
48,5=5;
48,6=5;
48,7=5;
48,8=5;
48,9=5;
48,10=5;
48,11=5;
48,12=5;
48,13=1;
48,14=3;
48,15=3;
48,16=3;
48,17=4;
48,18=4;
48,19=3;
48,20=3;
48,21=1;
48,22=1;
48,23=1;
48,24=1;
48,25=1;
48,26=1;
48,27=1;
48,28=1;
48,29=1;
48,30=1;
48,31=1;
48,32=1;
48,33=1;
48,34=1;
48,35=1;
48,36=1;
48,37=1;
48,38=1;
48,39=1;
48,40=2;
48,41=1;
48,42=1;
48,43=1;
48,44=1;
48,45=1;
48,46=5;
48,47=1;
48,48=1;
48,49=1;
48,50=1;
48,51=1;
48,52=1;
48,53=1;
48,54=1;
48,55=1;
48,56=1;
48,57=1;
48,58=1;
48,59=5;
48,60=5;
48,61=5;
48,62=5;
48,63=5;
49,0=1;
49,1=1;
49,2=1;
49,3=5;
49,4=5;
49,5=5;
49,6=1;
49,7=1;
49,8=1;
49,9=1;
49,10=5;
49,11=5;
49,12=5;
49,13=1;
49,14=3;
49,15=3;
49,16=4;
49,17=4;
49,18=3;
49,19=3;
49,20=1;
49,21=1;
49,22=5;
49,23=5;
49,24=5;
49,25=5;
49,26=5;
49,27=5;
49,28=5;
49,29=5;
49,30=5;
49,31=5;
49,32=1;
49,33=1;
49,34=1;
49,35=1;
49,36=1;
49,37=1;
49,38=1;
49,39=1;
49,40=2;
49,41=1;
49,42=1;
49,43=1;
49,44=1;
49,45=1;
49,46=1;
49,47=1;
49,48=1;
49,49=1;
49,50=1;
49,51=1;
49,52=1;
49,53=1;
49,54=1;
49,55=1;
49,56=1;
49,57=1;
49,58=5;
49,59=5;
49,60=5;
49,61=5;
49,62=5;
49,63=5;
50,0=1;
50,1=1;
50,2=1;
50,3=1;
50,4=1;
50,5=1;
50,6=1;
50,7=1;
50,8=1;
50,9=1;
50,10=1;
50,11=1;
50,12=1;
50,13=3;
50,14=3;
50,15=4;
50,16=4;
50,17=3;
50,18=3;
50,19=1;
50,20=1;
50,21=5;
50,22=5;
50,23=5;
50,24=5;
50,25=5;
50,26=5;
50,27=5;
50,28=5;
50,29=5;
50,30=5;
50,31=5;
50,32=1;
50,33=1;
50,34=1;
50,35=1;
50,36=1;
50,37=1;
50,38=1;
50,39=1;
50,40=2;
50,41=1;
50,42=1;
50,43=1;
50,44=1;
50,45=1;
50,46=1;
50,47=1;
50,48=1;
50,49=1;
50,50=1;
50,51=1;
50,52=1;
50,53=1;
50,54=1;
50,55=1;
50,56=1;
50,57=1;
50,58=1;
50,59=1;
50,60=1;
50,61=5;
50,62=5;
50,63=5;
51,0=1;
51,1=1;
51,2=1;
51,3=3;
51,4=3;
51,5=3;
51,6=3;
51,7=3;
51,8=3;
51,9=3;
51,10=1;
51,11=1;
51,12=3;
51,13=3;
51,14=4;
51,15=4;
51,16=3;
51,17=3;
51,18=1;
51,19=1;
51,20=5;
51,21=5;
51,22=5;
51,23=5;
51,24=5;
51,25=5;
51,26=5;
51,27=5;
51,28=5;
51,29=5;
51,30=5;
51,31=5;
51,32=5;
51,33=5;
51,34=5;
51,35=5;
51,36=1;
51,37=1;
51,38=1;
51,39=1;
51,40=2;
51,41=1;
51,42=1;
51,43=1;
51,44=1;
51,45=1;
51,46=1;
51,47=5;
51,48=5;
51,49=5;
51,50=5;
51,51=5;
51,52=5;
51,53=5;
51,54=1;
51,55=1;
51,56=1;
51,57=1;
51,58=1;
51,59=1;
51,60=1;
51,61=1;
51,62=5;
51,63=5;
52,0=3;
52,1=3;
52,2=3;
52,3=3;
52,4=4;
52,5=4;
52,6=4;
52,7=4;
52,8=4;
52,9=3;
52,10=3;
52,11=3;
52,12=3;
52,13=4;
52,14=4;
52,15=3;
52,16=3;
52,17=1;
52,18=1;
52,19=1;
52,20=5;
52,21=5;
52,22=5;
52,23=5;
52,24=5;
52,25=5;
52,26=5;
52,27=5;
52,28=5;
52,29=5;
52,30=5;
52,31=5;
52,32=5;
52,33=1;
52,34=5;
52,35=5;
52,36=1;
52,37=1;
52,38=1;
52,39=1;
52,40=2;
52,41=1;
52,42=1;
52,43=1;
52,44=1;
52,45=1;
52,46=1;
52,47=1;
52,48=5;
52,49=5;
52,50=5;
52,51=5;
52,52=5;
52,53=5;
52,54=5;
52,55=1;
52,56=1;
52,57=1;
52,58=1;
52,59=1;
52,60=1;
52,61=1;
52,62=1;
52,63=1;
53,0=4;
53,1=4;
53,2=4;
53,3=4;
53,4=4;
53,5=4;
53,6=4;
53,7=4;
53,8=4;
53,9=4;
53,10=4;
53,11=4;
53,12=4;
53,13=4;
53,14=3;
53,15=3;
53,16=1;
53,17=1;
53,18=5;
53,19=5;
53,20=5;
53,21=5;
53,22=5;
53,23=5;
53,24=5;
53,25=5;
53,26=5;
53,27=5;
53,28=5;
53,29=5;
53,30=5;
53,31=1;
53,32=5;
53,33=5;
53,34=5;
53,35=1;
53,36=5;
53,37=1;
53,38=1;
53,39=1;
53,40=2;
53,41=1;
53,42=1;
53,43=1;
53,44=1;
53,45=1;
53,46=1;
53,47=1;
53,48=5;
53,49=5;
53,50=5;
53,51=5;
53,52=5;
53,53=5;
53,54=5;
53,55=5;
53,56=5;
53,57=5;
53,58=1;
53,59=1;
53,60=1;
53,61=1;
53,62=1;
53,63=1;
54,0=4;
54,1=4;
54,2=4;
54,3=4;
54,4=4;
54,5=4;
54,6=4;
54,7=4;
54,8=4;
54,9=4;
54,10=4;
54,11=4;
54,12=4;
54,13=4;
54,14=3;
54,15=1;
54,16=1;
54,17=1;
54,18=5;
54,19=5;
54,20=5;
54,21=5;
54,22=5;
54,23=5;
54,24=5;
54,25=5;
54,26=5;
54,27=5;
54,28=1;
54,29=5;
54,30=5;
54,31=5;
54,32=5;
54,33=5;
54,34=5;
54,35=1;
54,36=5;
54,37=1;
54,38=1;
54,39=1;
54,40=2;
54,41=2;
54,42=1;
54,43=1;
54,44=1;
54,45=1;
54,46=1;
54,47=1;
54,48=5;
54,49=5;
54,50=5;
54,51=5;
54,52=5;
54,53=5;
54,54=5;
54,55=5;
54,56=5;
54,57=5;
54,58=5;
54,59=1;
54,60=1;
54,61=1;
54,62=1;
54,63=1;
55,0=4;
55,1=4;
55,2=4;
55,3=4;
55,4=4;
55,5=4;
55,6=4;
55,7=4;
55,8=4;
55,9=4;
55,10=4;
55,11=4;
55,12=4;
55,13=4;
55,14=3;
55,15=3;
55,16=1;
55,17=1;
55,18=5;
55,19=5;
55,20=5;
55,21=5;
55,22=5;
55,23=5;
55,24=5;
55,25=5;
55,26=5;
55,27=5;
55,28=5;
55,29=1;
55,30=5;
55,31=1;
55,32=5;
55,33=5;
55,34=5;
55,35=5;
55,36=1;
55,37=1;
55,38=1;
55,39=1;
55,40=1;
55,41=2;
55,42=2;
55,43=1;
55,44=1;
55,45=1;
55,46=1;
55,47=1;
55,48=1;
55,49=5;
55,50=5;
55,51=5;
55,52=5;
55,53=5;
55,54=5;
55,55=5;
55,56=5;
55,57=5;
55,58=5;
55,59=5;
55,60=1;
55,61=1;
55,62=1;
55,63=1;
56,0=4;
56,1=4;
56,2=3;
56,3=3;
56,4=3;
56,5=3;
56,6=3;
56,7=4;
56,8=4;
56,9=4;
56,10=4;
56,11=4;
56,12=4;
56,13=4;
56,14=4;
56,15=3;
56,16=3;
56,17=1;
56,18=1;
56,19=1;
56,20=5;
56,21=5;
56,22=5;
56,23=5;
56,24=5;
56,25=5;
56,26=1;
56,27=5;
56,28=5;
56,29=5;
56,30=5;
56,31=5;
56,32=5;
56,33=1;
56,34=5;
56,35=5;
56,36=5;
56,37=1;
56,38=1;
56,39=1;
56,40=1;
56,41=1;
56,42=2;
56,43=2;
56,44=1;
56,45=1;
56,46=1;
56,47=1;
56,48=1;
56,49=5;
56,50=5;
56,51=5;
56,52=5;
56,53=5;
56,54=5;
56,55=5;
56,56=5;
56,57=5;
56,58=5;
56,59=5;
56,60=1;
56,61=1;
56,62=1;
56,63=1;
57,0=3;
57,1=3;
57,2=3;
57,3=1;
57,4=1;
57,5=1;
57,6=3;
57,7=3;
57,8=3;
57,9=3;
57,10=4;
57,11=4;
57,12=4;
57,13=4;
57,14=4;
57,15=4;
57,16=3;
57,17=3;
57,18=1;
57,19=1;
57,20=5;
57,21=5;
57,22=1;
57,23=5;
57,24=5;
57,25=1;
57,26=5;
57,27=5;
57,28=5;
57,29=5;
57,30=1;
57,31=5;
57,32=5;
57,33=5;
57,34=1;
57,35=5;
57,36=5;
57,37=5;
57,38=1;
57,39=1;
57,40=1;
57,41=1;
57,42=1;
57,43=2;
57,44=1;
57,45=1;
57,46=1;
57,47=1;
57,48=1;
57,49=1;
57,50=5;
57,51=5;
57,52=5;
57,53=5;
57,54=5;
57,55=5;
57,56=5;
57,57=5;
57,58=5;
57,59=5;
57,60=5;
57,61=1;
57,62=1;
57,63=1;
58,0=1;
58,1=1;
58,2=1;
58,3=1;
58,4=1;
58,5=1;
58,6=1;
58,7=1;
58,8=1;
58,9=3;
58,10=3;
58,11=3;
58,12=4;
58,13=4;
58,14=4;
58,15=4;
58,16=4;
58,17=3;
58,18=1;
58,19=1;
58,20=1;
58,21=5;
58,22=5;
58,23=5;
58,24=5;
58,25=5;
58,26=5;
58,27=1;
58,28=5;
58,29=1;
58,30=5;
58,31=5;
58,32=5;
58,33=1;
58,34=1;
58,35=1;
58,36=5;
58,37=5;
58,38=1;
58,39=1;
58,40=1;
58,41=1;
58,42=1;
58,43=2;
58,44=1;
58,45=1;
58,46=1;
58,47=1;
58,48=1;
58,49=1;
58,50=1;
58,51=5;
58,52=5;
58,53=5;
58,54=5;
58,55=5;
58,56=5;
58,57=5;
58,58=5;
58,59=5;
58,60=5;
58,61=5;
58,62=1;
58,63=1;
59,0=1;
59,1=1;
59,2=5;
59,3=5;
59,4=5;
59,5=5;
59,6=5;
59,7=1;
59,8=1;
59,9=1;
59,10=1;
59,11=3;
59,12=3;
59,13=3;
59,14=4;
59,15=4;
59,16=4;
59,17=3;
59,18=3;
59,19=1;
59,20=1;
59,21=1;
59,22=1;
59,23=1;
59,24=1;
59,25=1;
59,26=1;
59,27=1;
59,28=5;
59,29=5;
59,30=5;
59,31=1;
59,32=5;
59,33=5;
59,34=5;
59,35=1;
59,36=5;
59,37=5;
59,38=1;
59,39=1;
59,40=1;
59,41=1;
59,42=1;
59,43=2;
59,44=1;
59,45=1;
59,46=1;
59,47=1;
59,48=1;
59,49=1;
59,50=1;
59,51=1;
59,52=1;
59,53=5;
59,54=5;
59,55=5;
59,56=5;
59,57=5;
59,58=5;
59,59=5;
59,60=5;
59,61=5;
59,62=1;
59,63=1;
60,0=1;
60,1=1;
60,2=5;
60,3=5;
60,4=5;
60,5=5;
60,6=5;
60,7=5;
60,8=5;
60,9=5;
60,10=1;
60,11=1;
60,12=1;
60,13=3;
60,14=3;
60,15=4;
60,16=4;
60,17=4;
60,18=3;
60,19=3;
60,20=1;
60,21=1;
60,22=1;
60,23=5;
60,24=5;
60,25=5;
60,26=5;
60,27=5;
60,28=5;
60,29=1;
60,30=5;
60,31=5;
60,32=5;
60,33=5;
60,34=5;
60,35=5;
60,36=1;
60,37=5;
60,38=1;
60,39=1;
60,40=1;
60,41=1;
60,42=1;
60,43=2;
60,44=1;
60,45=1;
60,46=1;
60,47=1;
60,48=1;
60,49=1;
60,50=1;
60,51=1;
60,52=1;
60,53=1;
60,54=1;
60,55=5;
60,56=5;
60,57=5;
60,58=5;
60,59=5;
60,60=5;
60,61=5;
60,62=1;
60,63=1;
61,0=1;
61,1=5;
61,2=5;
61,3=5;
61,4=5;
61,5=5;
61,6=5;
61,7=5;
61,8=5;
61,9=5;
61,10=5;
61,11=5;
61,12=1;
61,13=1;
61,14=3;
61,15=3;
61,16=4;
61,17=4;
61,18=4;
61,19=3;
61,20=3;
61,21=1;
61,22=1;
61,23=1;
61,24=5;
61,25=5;
61,26=1;
61,27=5;
61,28=5;
61,29=5;
61,30=1;
61,31=1;
61,32=5;
61,33=5;
61,34=1;
61,35=1;
61,36=1;
61,37=5;
61,38=1;
61,39=1;
61,40=1;
61,41=1;
61,42=1;
61,43=2;
61,44=1;
61,45=1;
61,46=1;
61,47=1;
61,48=1;
61,49=1;
61,50=1;
61,51=1;
61,52=1;
61,53=1;
61,54=1;
61,55=1;
61,56=1;
61,57=1;
61,58=1;
61,59=5;
61,60=5;
61,61=5;
61,62=1;
61,63=1;
62,0=1;
62,1=5;
62,2=5;
62,3=5;
62,4=5;
62,5=5;
62,6=5;
62,7=5;
62,8=5;
62,9=5;
62,10=5;
62,11=5;
62,12=1;
62,13=1;
62,14=1;
62,15=3;
62,16=4;
62,17=4;
62,18=4;
62,19=4;
62,20=3;
62,21=1;
62,22=1;
62,23=1;
62,24=1;
62,25=1;
62,26=1;
62,27=1;
62,28=5;
62,29=5;
62,30=1;
62,31=5;
62,32=1;
62,33=1;
62,34=1;
62,35=1;
62,36=1;
62,37=1;
62,38=1;
62,39=1;
62,40=1;
62,41=1;
62,42=1;
62,43=2;
62,44=2;
62,45=1;
62,46=1;
62,47=1;
62,48=1;
62,49=1;
62,50=1;
62,51=1;
62,52=1;
62,53=1;
62,54=1;
62,55=1;
62,56=1;
62,57=1;
62,58=1;
62,59=1;
62,60=1;
62,61=1;
62,62=1;
62,63=1;
63,0=1;
63,1=1;
63,2=1;
63,3=1;
63,4=1;
63,5=1;
63,6=1;
63,7=5;
63,8=5;
63,9=5;
63,10=5;
63,11=1;
63,12=1;
63,13=1;
63,14=1;
63,15=3;
63,16=3;
63,17=4;
63,18=4;
63,19=4;
63,20=3;
63,21=1;
63,22=1;
63,23=1;
63,24=1;
63,25=1;
63,26=1;
63,27=1;
63,28=1;
63,29=1;
63,30=1;
63,31=1;
63,32=1;
63,33=1;
63,34=1;
63,35=1;
63,36=1;
63,37=1;
63,38=1;
63,39=1;
63,40=1;
63,41=1;
63,42=1;
63,43=1;
63,44=2;
63,45=1;
63,46=1;
63,47=1;
63,48=1;
63,49=1;
63,50=1;
63,51=1;
63,52=1;
63,53=1;
63,54=1;
63,55=1;
63,56=1;
63,57=1;
63,58=1;
63,59=1;
63,60=1;
63,61=1;
63,62=1;
63,63=1;

I've also included here a picture of the complete map picture:


So how this works is I have a custom-made tileset and I give each tile a value. 1 is grass, 4 is water, and so on. Then these tile values (TileIDs or TileTypes) are saved along with their simplified tile position. To get the real x and y coordinates for the tiles you need to multiply the coordinates with the size of each individual tile. All the information necessary to convert map data into a real picture is provided in the map file.

Here's a picture of the map editor in action:

A red grid is drawn over the map but it is overwritten when you draw on it. Map sizes are specified by you. So a map can be as small as 128x128 pixels (or smaller) or as large as 2048x2048 pixels (or larger). Tilesizes are also specified by you. So you can have big fat tiles of 64 pixels (8x8) or something smaller like 16 (4x4). Personally I like a size of 32. That's what's also depicted above.

But the customisation would be a bit ordinary if you were stuck using the same tile art. Fortunately, you aren't. You're able to write your own tileset with which you can specify the ID for a tile, its name and its image file. A tileset file looks like this:

 template: name,id,filename

grass,1,grass.png;
dirt,2,dirt.png;
sand,3,sand.png;
water,4,water.png;
tree,5,tree.png;

Theoretically you can create as many tile types as you want. The image sizes don't matter; the editor attempts to scale them to the tile size specified for your map. Once your tileset file is complete it can be loaded into the editor. Below are a few screenshots of different tilesets I've created myself.


The artwork was made by nicubuno over at opengameart.org - a fantastic resource for hobby game developers. The art I chose to use from him is licensed under Public Domain. However the grass and water tiles were made by me. I also made a mars tileset for myself:

This is because my next big project is to create a Sci-Fi RTS game with a setting on Mars.

So there's the editor. It's extremely flexible because I made it with many different types of games in mind. I want to make an RTS with this and also an RPG at some point. I might change it at some point to allow for isometric maps, but this isn't a priority for me at the moment.

Monday, 26 March 2012

Been a while

It's been a while since I last made an update. This isn't because I've been slacking though; I've just been working on technical things like loading files, detecting when windows are opened and closed, etc. Nothing really cool that I can show you. However, I did create this Python script for generating an ITEM file (.item). The game itself has a C++ version, but since I haven't gotten around to getting a Windows compile together yet no one can really use it.

 ## Python ITEM writer script for Tyran  
 ## Version: 1.0  
 ## 19/3/2012  
 ## ITEMcreator.py  
 ################################  
 # This script is a little sloppy. It gets the job done though.  
 #  
 # Copyright (c) 2012 Joshua Woods  
 #  
 # This software is provided 'as-is', without any express or implied warranty.  
 # In no event will the authors be held liable for any damages arising from  
 # the use of this software.  
 #  
 # Permission is granted to anyone to use this software for any purpose,  
 # including commercial applications, and to alter it and redistribute it freely,  
 # subject to the following restrictions:  
 #  
 # 1. The origin of this software must not be misrepresented; you must not  
 # claim that you wrote the original software. If you use this software in a  
 # product, an acknowledgment in the product documentation would be  
 # appreciated but is not required.  
 #  
 # 2. Altered source versions must be plainly marked as such, and must not  
 # be misrepresented as being the original software.  
 #  
 # 3. This notice may not be removed or altered from any source distribution.  
 ################################  
 ## Updated: 24/3/2012  
 ################################  
   
 itemVersion = 0x0002 # please do not change  
 magic = 'ITEM\0' # please do not change  
   
 ################################  
 ## These classes are currently not used. But may be used in the future.  
 ################################  
 class itemType:  
      NONE, WEAPON, ARMOUR, CONSUMABLE, INGREDIENT, MATERIAL = range(6)  
   
 class itemQuality:  
      NONE, CRUDE, PETTY, COMMON, SUPRERIOR = range(5)  
   
 class itemEffect:  
      NONE, HEALTHHEAL, HEALTHHARM, MANAHEAL, MANAHARM, FATIGUEHEAL, FATIGUEHARM, HUNGERHEAL, HUNGERHARM, SLOW, HASTE,FORTSTR,FORTAGI,FORTPER,FORTINT,FORTCON,FORTWIS,FORTSPD,WEAKSTR,WEAKAGI,WEAKPER,WEAKINT,WEAKCON,WEAKWIS,WEAKSPD,RESISTPOISON, VULNURPOISON,RESISTDISEASE,VULNURDISEASE,RESISTMAGIC,VULNURMAGIC,RESISTPARALYSIS,VULNURPARALYSIS,CUREPOISON, CUREDISEASE,INVISIBILITY,DIZZY,INSANITY,FEAR,KILL = range(40)  
        
   
 ################################  
 ## Default values  
 ##  
 ## Don't alter these without knowing exactly what  
 ## you're doing. Some values like -666 are important  
 ## to the way Tyran determines ITEM versions.  
 ################################  
   
 fileName = 'newitem.item'  
 fileNameSub = fileName.split('.')  
 weight = 0  
 type = 0  
  # f 0, it is indestructible  
 durability = 0  
 #maximum durability  
 maxdur = 0  
 # higher the quality, the less chance of durability being decreased. 1 is to lose 1 durability per use.  
 quality = 0  
 equipable = 0  
 placeable = 0  
 description = 'item description (max 256 chars)\0'  
 name = 'item name (max 64 chars)\0'  
 # type of effect if consumable (eg. Healing) and the magnitude of the effect(eg. 20 would heal 20 points)  
 effect1 = 0  
 effect2 = 0  
 effect3 = 0  
 magnitude1 = 0  
 magnitude2 = 0  
 magnitude3 = 0  
   
 meshpath = "Models/Plane.obj\0"  
 texturepath = "Textures/texture_basecube.bmp\0"  
   
 armour = -666  
   
 ################################  
 welcomeMessage = '\nWelcome :) Change the values below and when you\'re done hit the Export button. Things to be aware of:\n\nDurability, maxdur, weight and armour only take integers.\nItem description takes a maximum of 256 characters\nItem name, mesh path and texture path take a maximum of 64 characters.\n\nIf you don\'t follow these rules, Tyran will crash when it tries to load the ITEM file.\n\nITEM versions supported: %d, %d' % (0x0001, itemVersion)  
 ################################  
   
 import os.path, tkMessageBox, sys, struct  
 import Tkinter as tk  
 from Tkinter import *  
 from string import rstrip, split  
   
 ################################  
 ## Check fileName already exists as a file. If it does, rename  
 ## fileName.  
 ################################  
 def ifFileExistsRenameIt():  
      global fileName  
      global fileNameSub  
      if os.path.isfile(fileName):  
           # Check if file is already there  
           if os.path.isfile(fileName):  
                # File does exist, rename our new file  
                temp = fileName.split('.')  
                print temp  
                i = 0  
                print temp[0] + repr(i)  
                while i != 100: # you can't possibly have more than 100 unnamed ITEM files, can you?  
                     while 1:  
                          if temp[0] == fileName + repr(i):  
                               i += 1  
                            
                          final = fileNameSub[0] + repr(i) + '.' + fileNameSub[1]  
                            
                          print 'Final: %s' % final  
                          fileName = final  
                          if os.path.isfile(fileName) != True:  
                               break  
                          i += 1  
                                 
                     break  
   
 ################################  
   
 ################################  
   
 def settings():  
      tkMessageBox.showinfo('Sorry','This feature isn\'t available yet.')  
   
 def quit():  
      sys.exit(0)  
   
 def about():  
      abo.deiconify()  
      abo.mainloop()  
   
 def hideabout():  
      abo.withdraw()  
   
 class About:  
      def __init__(self,master):  
           frame = Frame(master)  
           frame.pack()  
           # Label  
           lbl = Label(master, text='ITEM Creator v1.0\n\n19/3/2012\nJoshua Woods\n\ntyrangame.blogspot.com.au')  
           lbl.config(font=("arial", 12, 'bold'), justify=LEFT, fg='royalblue',bg='black')  
           lbl.pack()  
   
 class Help:  
      def __init__(self, master):  
           frame = Frame(master)  
           frame.pack()  
             
           lbl = Label(master, text='contact me for help on this format.')  
           lbl.config(font=("arial", 12, 'bold'), justify=LEFT, fg='royalblue',bg='black')  
           lbl.pack()  
   
 class Program:  
      def __init__(self, master):  
           frame = Frame(master)  
           frame.pack()  
             
           scrollbar = Scrollbar(master)  
           scrollbar.pack(side=RIGHT, fill=Y)  
             
           #self.canvas = tk.Canvas(frame, bg='black', bd=3, relief='sunken')  
             
           self.cmbDataItemType = StringVar(master)  
           self.cmbDataItemType.set("Item type: None") # default value  
   
           self.w = OptionMenu(master, self.cmbDataItemType, "Item type: None", 'weapon', 'armour', 'consumable', 'ingredient', 'material')  
             
           self.cmbDataItemQual = StringVar(master)  
           self.cmbDataItemQual.set("Item quality: None") # default value  
             
           self.w2 = OptionMenu(master, self.cmbDataItemQual, "Item quality: None", 'crude', 'petty', 'common', 'superior')  
             
           self.cmbDataPlaceable = StringVar(master)  
           self.cmbDataPlaceable.set("Placeable: False") # default value  
             
           self.w3 = OptionMenu(master, self.cmbDataPlaceable, "true")  
             
           self.cmbDataEquipable = StringVar(master)  
           self.cmbDataEquipable.set("Equipable: False") # default value  
             
           self.w4 = OptionMenu(master, self.cmbDataEquipable, "true")  
             
           self.txtIntro = Text(master, yscrollcommand=scrollbar.set,font=('arial', 13, 'normal'),fg='yellow',bg='black',width=40, height=6,insertbackground='yellow',wrap=WORD,borderwidth=4)  
             
             
             
           self.txtfilename = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)  
           self.txtitemname = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)  
           self.txtitemdesc = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=4,insertbackground='royalblue',wrap=WORD,borderwidth=4)  
           self.txtmeshpath = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)  
           self.txttexturepath = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)  
           self.txtdurability = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)  
           self.txtmaxdurability = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)  
           self.txtweight = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)  
           self.txtarmour = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)  
           self.btnexport = Button(master, text='Export', fg='royalblue', bg='black', command=self.btnexportcallback,font=('arial',13,'bold'))  
           # Packing:  
           self.txtIntro.pack(side=TOP, fill=BOTH)  
           scrollbar.config(command=self.txtIntro.yview)  
           self.btnexport.pack(side=TOP)  
           self.txtfilename.pack(side=TOP)  
           self.txtitemname.pack(side=TOP)  
           self.txtitemdesc.pack(side=TOP)  
           self.txtmeshpath.pack(side=TOP)  
           self.txttexturepath.pack(side=TOP)  
           self.txtdurability.pack(side=TOP)  
           self.txtmaxdurability.pack(side=TOP)  
           self.txtweight.pack(side=TOP)  
           self.txtarmour.pack(side=TOP)  
             
           #self.canvas.pack(side=RIGHT)  
           self.w.pack(side=LEFT)  
           self.w2.pack(side=LEFT)  
           self.w3.pack(side=LEFT)  
           self.w4.pack(side=LEFT)  
             
           #self.w.pack(side= RIGHT)  
           # Inject some data into new fields  
           self.txtIntro.insert(END, welcomeMessage)  
           self.txtfilename.insert(END, fileName)  
           self.txtitemname.insert(END,name)  
           self.txtitemdesc.insert(END,description)  
           self.txtmeshpath.insert(END, meshpath)  
           self.txttexturepath.insert(END, texturepath)  
           self.txtdurability.insert(END, "durability")  
           self.txtmaxdurability.insert(END, "maximum durability")  
           self.txtweight.insert(END, "weight")  
           self.txtarmour.insert(END, "armour")  
             
           #print drawWireframe(self.canvas, (200,200), meshpath)  
        
      def printValues(self):  
           #self.txtIntro.delete  
           self.txtIntro.insert(1.0, ("%s" % self.txtfilename.get(1.0, END)))  
           self.txtIntro.insert(1.0, ("%s" % self.txtitemname.get(1.0, END)))  
           self.txtIntro.insert(1.0, ("%s" % self.txtitemdesc.get(1.0, END)))  
           self.txtIntro.insert(1.0, ("%s" % self.txtmeshpath.get(1.0, END)))  
           self.txtIntro.insert(1.0, ("%s" % self.txttexturepath.get(1.0, END)))  
           self.txtIntro.insert(1.0, ("%s" % self.txtdurability.get(1.0, END)))  
           self.txtIntro.insert(1.0, ("%s" % self.txtmaxdurability.get(1.0, END)))  
           self.txtIntro.insert(1.0, ("%s" % self.txtweight.get(1.0, END)))  
           self.txtIntro.insert(1.0, ("\n%s" % self.txtarmour.get(1.0, END)))  
             
           self.txtIntro.insert(1.0, ("\n%s" % self.cmbDataItemType.get()))  
           self.txtIntro.insert(1.0, ("\n%s" % self.cmbDataItemQual.get()))  
           self.txtIntro.insert(1.0, ("\n%s" % self.cmbDataPlaceable.get()))  
           self.txtIntro.insert(1.0, ("\n%s" % self.cmbDataEquipable.get()))  
   
      def btnexportcallback(self):  
             
           # extract data from fields  
           fileName = (self.txtfilename.get(1.0, END)).strip()  
             
           weight = (self.txtweight.get(1.0, END)).strip()# + '\0'  
           if weight == 'weight':  
                weight = 0  
           else:  
                weight = int(weight)  
             
           durability = (self.txtdurability.get(1.0, END)).strip()# + '\0'  
           if durability == 'durability':  
                durability = 0  
           else:  
                durability = int(durability)  
             
           maxdur = (self.txtmaxdurability.get(1.0, END)).strip() #+ '\0'  
           if maxdur == 'maximum durability':  
                maxdur = 0  
           else:  
                maxdur = int(maxdur)  
             
           type = self.cmbDataItemType.get()  
           if type == "Item type: None":  
                type = 0  
           elif type == 'weapon':  
                type = 1  
           elif type == 'armour':  
                type = 2  
           elif type == 'consumable':  
                type = 3  
           elif type == 'ingredient':  
                type = 4  
           elif type == 'material':  
                type = 5  
             
           print type  
             
           quality = self.cmbDataItemQual.get()  
           if quality == "Item quality: None":  
                quality = 0  
           elif quality == 'crude':  
                quality = 1  
           elif quality == 'petty':  
                quality = 2  
           elif quality == 'common':  
                quality = 3  
           elif quality == 'superior':  
                quality = 4  
             
             
           equipable = self.cmbDataEquipable.get()  
           if equipable == "Equipable: False":  
                equipable = 0  
           else:  
                equipable = 1  
             
           placeable = self.cmbDataPlaceable.get()  
           if placeable == "Placeable: False":  
                placeable = 0  
           else:  
                placeable = 1  
             
           description = (self.txtitemdesc.get(1.0, END)).strip() + '\0'  
           name = (self.txtitemname.get(1.0, END)).strip() + '\0'  
             
           effect1 = 0  
           effect2 = 0  
           effect3 = 0  
           magnitude1 = 0  
           magnitude2 = 0  
           magnitude3 = 0  
   
           meshpath = (self.txtmeshpath.get(1.0, END)).strip() + '\0'  
           texturepath = (self.txttexturepath.get(1.0, END)).strip() + '\0'  
   
           armour = (self.txtarmour.get(1.0, END)).strip()# + '\0'  
           if armour != 'armour':  
                armour = int(armour)  
           else:  
                itemVersion = 0x0001  
             
           print weight  
           print equipable  
             
             
           ###############################  
           ifFileExistsRenameIt()  
           print 'Creating %s' % fileName  
           file = open(fileName, 'wb')  
           print 'Writing to file ...'  
           file.write(magic)  
             
           format = "h" # write short  
           data = struct.pack(format, itemVersion)  
           print '[' + repr(itemVersion) + ']'  
           file.write(data)  
           format = 'i' # write integers  
           data = struct.pack(format, weight)  
           print '[' + repr(weight) + ']'  
           file.write(data)  
           data = struct.pack(format, type)  
           print '[' +repr( type) + ']'  
           file.write(data)  
           data = struct.pack(format, durability)  
           print '[' + repr(durability) + ']'  
           file.write(data)  
           data = struct.pack(format, maxdur)  
           print '[' + repr(maxdur) + ']'  
           file.write(data)  
           data = struct.pack(format, quality)  
           print '[' + repr(quality) + ']'  
           file.write(data)  
           data = struct.pack(format, equipable)  
           print '[' + repr(equipable) + ']'  
           file.write(data)  
           data = struct.pack(format, placeable)  
           print '[' + repr(placeable) + ']'  
           file.write(data)  
           # effects and magnitude ignored for now  
           data = struct.pack(format, 0)  
           print '[' + repr(data) + ']'  
           file.write(data)  
           print '[' + repr(data) + ']'  
           file.write(data)  
           print '[' + repr(data) + ']'  
           file.write(data)  
           print '[' + repr(data) + ']'  
           file.write(data)  
           print '[' + repr(data) + ']'  
           file.write(data)  
           print '[' + repr(data) + ']'  
           file.write(data)  
             
           print '[' + name + ']'  
           file.write(name)  
           print '[' + description + ']'  
           file.write(description)  
           print '[' + meshpath + ']'  
           file.write(meshpath)  
           print '[' + texturepath + ']'  
           file.write(texturepath)  
           if itemVersion == 0x0002:  
                data = struct.pack(format, armour)  
                print '[' + repr(armour) + ']'  
                file.write(data)  
           print 'Finished... Closing...'  
           file.close()  
             
             
 ################################  
   
 #file = open(fileName, 'wb')  
   
 root = Tk()  
 root.title('ITEM Creator')  
   
 toplevel = tk.Toplevel(root)  
   
 toplevel.geometry('640x480')  
 toplevel.resizable(0,0)  
   
 toplevel.withdraw()  
   
 root.config(bg='black')  
 root.protocol("WM_DELETE_WINDOW", quit)  
   
 program = Program(root)  
   
 # Main Menu  
 menubar = Menu(root)  
 root.config(menu=menubar)  
 # Options Menu  
 optionsmenu = Menu(menubar, tearoff=0)  
 optionsmenu.add_command(label='Data to text field', command=program.printValues)  
 optionsmenu.add_separator()  
 optionsmenu.add_command(label='Quit', command=quit)  
 menubar.add_cascade(label='Options', menu=optionsmenu)  
 # Help Menu  
 helpmenu = Menu(menubar, tearoff=0)  
 helpmenu.add_command(label='About', command=about)  
 menubar.add_cascade(label='Help', menu=helpmenu)  
 # About  
 abo = Tk()  
 abo.title('About')  
 abo.config(bg='black')  
 abo.protocol('WM_DELETE_WINDOW', hideabout)  
 aviabo = About(abo)  
 hideabout()  
   
 root.mainloop()  

It's not optimised, just quick and dirty. But that's what I use Python for. I only bother polishing the stuff that matters: the C++ that runs the game.

Saturday, 17 March 2012

Ship in a bottle

Ever since I was a kid, I've had this little yacht in a bottle that I bought from a man at Sydney harbour. As a cool little bit of loot for the game, I decided to model it and put it in. It'll serve as exotic loot that will sell for a nice price, or decorate the player's home. Or maybe it will be a charm of some kind - granting the player a passive benefit.


I also completed my new low-poly musket model. A video is here, and an image below.


Wednesday, 14 March 2012

Bicorne models



Yesterday I did a lot of modelling. I created a model bicorne, then ruthlessly cut down the vertices to make it quite low-poly. I kept this as the simple version of the hat, then I proceeded to create a decorated bicorne which has a badge and flower. Within the game these decorated bicornes will be worn by officers, sergeants, etc of the various factions and will be of different colours and designs. Undecorated bicornes will be common attire for citizens and soldiers.

I loaded all the models into the inventory. See a video here.

Next on my list of things to create is a low-poly musket, then I may have a stab at a tricorne.

Thursday, 8 March 2012

New Models

I went on a bit of a modelling spree after successfully making and texturing a 3D pie. I went on to make an apple, a helmet and a musket. Although my creations reek of 'programmer art', they're all I have to go on right now. They're good place holders, and I'm quite proud of my pie. The rest I consider to be good first attempts.


They've served to fatten up my inventory a little already, and I will soon make more.

Tuesday, 6 March 2012

Inventory

The foundations of my inventory system are complete, and mostly working as I want them to. Here's a video. Thanks very much to the people over at www.opengameart.org for the 3D models.