Need to know how to make a tile editor / graphics editor

Discussion in 'Technical Discussion' started by Elektro-Omega, Sep 10, 2012.

  1. Elektro-Omega

    Elektro-Omega

    Mushroom Hill'in Member
    400
    0
    0
    UK
    -
    Hey Retro,

    I am looking to program a basic tile viewer / editor which allows the user to view tiles from a rom file, export the full images and import custom images.

    This sounds like a very ambitious project and to be honest, it is, but I'm not entirely clueless.

    I know the offset of each graphic that I need.

    I'm just having trouble figuring out how to actually program it, I know I would need to read in the data, display it to the screen by re-arranging it and then allow for importing and overwriting and exporting of sprites, I am just completely clueless about it. I program mainly in python due to it's flexibility and ease of syntax, if that helps.

    I hope someone can enlighten me as google provides very little help.
     
  2. Shoemanbundy

    Shoemanbundy

    Researcher
    1,071
    14
    18
    Chicago, Illinois
    selling shoes
    This will come off as obvious, but are the graphics compressed? Because if not, you can just use Tile Molester and edit them, eliminating the need of a whole custom program for the one game..
     
  3. Elektro-Omega

    Elektro-Omega

    Mushroom Hill'in Member
    400
    0
    0
    UK
    -
    The graphics are uncompressed and Tile Molester / Tile Layer Pro can view them (and can load in the palette correctly by loading an external.pal file).

    The only reason I wanted to develop a tile editor, importer and exporter was purely for convenience. I was only planning on hacking one particular game and thought it would be very convenient to have the image correctly displayed, export it to say a .bmp or similar format, edit it and then re-import it and have the program configure the layout of the tiles. I'm still completely stuck as to how to read in and display the sprite data correctly as well as exporting / importing and slicing the bitmap into the tiles and placing them back in the correct order.

    I'm basically stuck with the whole process, but I'm not looking for someone to completely do it for me, just some guidance.

    Edit: Done some research and google is literally drawing blanks. I already know how to load a rom into python, select for it to read from a certain offset and up to a certain offset but I'm not sure how to display the data into the tiles and then arrange these onto a larger grid to form the sprite.
     
  4. Elektro-Omega

    Elektro-Omega

    Mushroom Hill'in Member
    400
    0
    0
    UK
    -
    I hope nobody frowns on me for this double post but I felt it was deserved as it has a little more knowledge.

    So I have researched into python and pygame and found the function to draw a pixel. I figured that if I specified the palette of the game into each seperate file, created an array of 8x8 for each tile and then drew a pixel in each slot, it would form the correctly coloured tile. I would then create a separate array to combine the tiles to the full sprite.

    I havn't attempted this as it seems like it would be far from the correct way. Making the program read the offsets from the file, creating an array for each tile and then making an array of tile arrays for a sprite not only seems incredibly long winded but also incredibly inefficient on the program itself.

    Is there any help out there from someone who has more knowledge on this subject?
     
  5. Dr. Kylstein

    Dr. Kylstein

    Member
    86
    0
    6
    What I would do is load all of the tiles sequentially into a Surface object, then use an array of tile offsets to blit sections from that Surface into a new one representing the full graphic. You can then blit that onto the screen Surface however you like. If you already know how to manipulate strings of data in Python, you can convert the 4-bit pixels into 8-bit pixels and use pygame.image.fromstring() to load the tiles. If that's Greek to you, you could still use the pixel plotting routines at that step. Once you have a strip of tiles you can create 8x8 Rects at the appropriate positions and pass those as the area argument of Surface.blit() to copy specific tiles into areas of the full graphic.
     
  6. Elektro-Omega

    Elektro-Omega

    Mushroom Hill'in Member
    400
    0
    0
    UK
    -
    That is some fantastic information and has cleared up some issues I have.

    I am still unsure how to actually sequentially load the tiles, do you mean literally load the entire start of the offset of the graphics to the end of the offset of the graphics into a single surface and then merely take select data out from the surface, or did you mean the data for each tile into a surface?

    I feel that I am capable of this but I can't help but feel I literally need a step by step guide. I'm going to try to understand the help given and will keep you all updated.
     
  7. Dr. Kylstein

    Dr. Kylstein

    Member
    86
    0
    6
    Glad to be of help.
    I think it is less overhead to have all the tiles in one Surface, and computing rectangles for blitting is trivial.

    If I recall, the Megadrive/Genesis VDP tile format is one nybble per pixel, specifying the pixels from left to right, top to bottom for each tile in sequence. Given that, I'd load the byte-expanded pixels into an 8 by 8*number_of_tiles Surface. fromstring() will give a column of tiles automatically, but even plotting pixels this way is easier since you can ignore tile boundaries when you initially load the data. Then index*8 is the top of the Rect of any given tile index.
     
  8. Elektro-Omega

    Elektro-Omega

    Mushroom Hill'in Member
    400
    0
    0
    UK
    -
    Ok so I have been looking around in a hex editor at the tiles. Since the tiles are 4 bbp it means that it is 32 bytes per tile stored as little endian. This has also enabled me (with the use of a palette saved from an emulator) to figure out the correct colour values per colour bit.

    I think when I program this little application, I may not allow the users to see the tiles, just the graphics as a whole, but that is just personal preference.

    Thank you for your help Dr. Kylstein, just another quick question. If I wanted to go the other way and allow users to load in a bitmap which would overwrite the default tileset would I simply load the file, strip the unnecessary information, perform the necessary transformations to the data (endian shifts and parsing) and then overwrite the default tile values?

    Thanks again.

    Quick Edit: Would this entire process be made incredibly harder with the exclusion of pygame. I cannot seem to make a fairy good gui for it and I am more accustomed to working with Tkinter. If the process becomes very longwinded and difficult without it, I will stick with pygame, I was just hoping to create a kind of native button feel to the application.
     
  9. Dr. Kylstein

    Dr. Kylstein

    Member
    86
    0
    6
    Once you have a Surface with the new tiles stacked top to bottom, everything proceeds logically in reverse.
    I haven't used Tkinter before, but it looks like the Python Imaging Library has integration for it. I can't help much with either of those, but it should be possible to do things in a similar way in PIL. Worst case, you may be able to pass the contents of a pygame Surface into PIL as a string.

    Edit: I just want to note that I've always used Qt (with Pyside) for GUIs, and it can do everything. It may be much more complicated than Tkinter though.