@gundy, how do you create the tile maps? I see that you use Tiled files.
It’s a bit of an involved process at the moment…
I use GIMP to edit the texture - essentially just as a 128x128 image (which is split into 8x8 tiles):
That gets me the basic 2bpp (albeit grayscale) data to work with. I export that into a C header file from GIMP to use in the code, or I use the image directly in Tiled for editing the larger maps.
At this point things are still greyscale. Colouring the maps is a bit more of a hassle.
I export the data from tiled as a CSV file, convert the CSV into hex format using a little utility, and then kind of manually find the sections that I want to apply a different palette to and update the upper bits to chose the “sub-palette” to use.
The way the tile/colour data is stored in memory is as 12-bit values:
Where T7-0 represent the tile number (0…255, corresponding to the different tiles in the map above), and where P3-0 are a sub-palette selector.
There are 16 possible 4-colour sub-palettes, and each of the 4 colours for a given sub-palette comes from one of 16 global colours (which in turn can be any RRGGBB value).
It’s probably easiest to demonstrate with a picture. Here’s the gateroids sub-palette map:
So if I want to make a particular section of the tiled map greyscale, I simply set the sub-palette selector to “0” (the first group of 4 colours from the left in that map). In practice that means setting the upper nibble of the 12-bit value to 0.
If I wanted to make something purple, I’d apply a palette selector of “1”, and so on.
The same sub-palettes are also used for the sprites, which also use two-bits per pixel. For sprites, the bit pattern “00” always maps to a transparent pixel, but for background tiles it can be used as a normal colour.
As I mentioned above, all of the colours in the “sub palette” swatch come from a global palette of 16-colours, which have been selected from the 64 total available RRGGBB values. For gateroids, this palette looks like:
So yeah, the short version is that I use GIMP + Tiled, with a bit of finessing afterwards
ETA: I’m currently using more-or-less the same process to edit sprites too:
The other orientations of the ship are generated by X/Y flipping in hardware.
I have a project that generates code from Tiled files, maybe that could help.
I designed a new version of the PCB:
- Based on the actual screen, not the evaluation board
- Backlight is always on (1 more BX pin available)
- TinyFPGA-BX is now on the front and above the screen
- The board width is reduced by 1.4 cm (because the screen takes less place than the eval board)
- So far it is pin compatible with the previous rev
Let me know what you think.
I would like the SD card pins connected so that I can put all the games on an SD card and run them from that with my menu. If we are not using the development board, then presumably we lose the SD card reader so would have to add one.
You suggested in a private message that I open an issue on your repository for that. I can do that if you still want that.
On my FPGC, I soldered the SD card pins (32 - 35) to the direction button pins as my SD card menu does not use the direction buttons.
It makes a far better demo of the device if you can run all the games from a menu rather than having to load each one separately from a PC.
But creating a menu that stays in flash memory and runs the games from a different address in the flash memory requires setting up a new multiboot configuration, which isn’t trivial. It is quite easy to do but is risky if you don’t have some sort of SPI programmer. I used a second BX as a programmer.
I also quite like the idea of having a built-in speaker rather than having to use the headphone jack. That would require an amplifier.
It would be good to do a 3D printed case for the device. If we did that it might be best to have the USB connector at the edge of the board. Getting access to the reset button, power button, headphone jack, uart connector and SD card reader could also be difficult.
I was thinking this too. To help here it would be useful to have additional holes through the board that could be used for screwing two halves of a case together.
I do like the idea of having multiple games. The question is the balance between features and complexity of the design.
So far there is not enough pins available to connect an SD card.
Can you elaborate on that? Why can’t we aggregate the games and the menu app all in the SPI flash?
I like the raw PCB style myself, but I can make it easier to create a case (see below).
For the orientation of the USB connector, I am limited by fact that the BX board is a through hole part. So if I put it on the back like in rev-A, the pins stick out to the front and that means the screen cannot lay on the PCB. It also means that the BX is taller than the battery holder, so when you put the FPGC on a table it sits on the reset button.
There are two cases here.
- The games use the same hardware configuration.
In that case, you could have the different games in different areas of flash memory. You could then have multiple games in flash memory without using an SD card. Or you could load them from an SD card. This would need changes to PicoSoC to allow specifying the start address of a game and possibly returning to the menu when a game finishes.
However, having the same hardware configuration for each game (and the menu) is very restrictive.
- Different hardware configurations
If you have different hardware configurations, you need a way to configure the Ice40 to boot to them.
The bootloader uses a warm boot multiboot configuration to tell the Ice40 to use the configuration at 0x28000 (which tinyprog calls the user image). It uses SB_WARMBOOT to do that. SB_WARMBOOT allows you to boot to one of 4 different hardware configurations. The default BX multiboot configuration only uses two: one as the power-on configuration, which is the bootloader itself, and the other being the user_image.
If a menu program is the user image, it cannot boot to another hardware configuration without overwriting itself. My tiny-ram_soc/example/game_menu does that. It overwrites the user image with the game and boots to it. The problem with that is that it when the game finishes it is left in the user image slot in flash memory, so to play another game, you need to use tinyprog to flash it again.
My sticky_game_menu uses a different muli-boot configuration with warm boot slots at 0x28000, 0x50000 and 0x78000. To build that multiboot configuration you make a slight change to the Makefile at https://github.com/tinyfpga/TinyFPGA-Bootloader/tree/master/boards/TinyFPGA_BX. See https://github.com/lawrie/TinyFPGA-Bootloader/blob/master/boards/TinyFPGA_BX/Makefile.
The resulting configuration, fw.bin, can be used to overwrite the existing one by:
tinyprog -a 0 -p fw.bin
You have to ignore the warning that you will overwrite the existing bootloader and type “yes”. The problem is that if this fails, your BX is (temporarily) bricked and you need an SPI programmer to restore its original multiboot configuration (multiboot.bin).
With that configuration in place, my tiny_ram_soc/example/sticky_game_menu can boot to other configurations. It uses the one at 0x78000. So it writes the hardware.bin of the game to 0x78000 and the firmware.bin to 0x50000 and uses SB_WARMBOOT to boot to it.
When you finish the game, and press reset or turn the BX off and on it goes back in to the bootloader which then does a warm boot to 0x28000, which still contains the menu.
This is by far the most flexible way of using a menu. It allow for games using the original tinyfpga-bx-game-soc hardware configuration or @gundy’s new one, or the one I am using for Atari 2600 games, or any others that we choose to develop, including ones that use different soft processors such as a 6502 or Z80 soft processor.
You can reuse the direction button pins for the SD card reader connections - it just means those buttons cannot be used by the menu program.
When the TinyFPGA EX comes out I am sure we will want to produce a Games console based on that. It has the resources to emulate the video and audio capabilities of a much wider range of games consoles and home computers including the Commodore 64 and the Commodore Amiga.
The EX contains as SD card reader, so this is just an issue for the BX version.
This is great! When do you think you’ll be ordering these new PCBs?
My menu now supports up to 6 games. @gundy’s asteroids game doesn’t run from the sticky menu as that puts the hardware.bin at 0x78000 and the rom at 0x50000 giving a limit of 160KB for the rom, and asteroids is a little bigger than that. To fix that I would either need to change the multiboot configuration which might need changes to the icestorm icemulti tool, or I could change PicoSoc to put the flash rom at a different address, e.g 0xa0000.
I don’t know if I will order one of these. They are functionally identical to the previous version and I’m still not convinced by the layout.
Also I might want to do an EX version. (Note that the first version should be compatible with EX)
Do you have any plans to commit your changes to a repository, or are you too busy on other things?
I believe you made changes to ili9341.v for the timing and initialisation sequence, and I would like to see those as I suspect your version is better than the one I am using for the Atari 2600. In my RAM version of PicoSoc, I was using ili9341_direct.v, and the timing and initialisation sequence are different in that and probably more like the ones your are using. However, with the atari_2600 6502 CPU emulation, I am back to use the VGA-like ili9341.v and don’t want to have to repeat the work you did on improving it.
Also, I would like to play with your mult–coloured sprites, even if what you have is not finished.
Sorry, you’re right, I have been really quite busy with a lot of other stuff lately. I have been pushing everything I’ve done to github, but some of the changes you talk about are in an “8-bit-colour” branch (which is no longer technically accurate - it’s more like 6-bit colour)
Even though I haven’t had the time to do much myself, I’ve been watching from the sidelines and I’m super impressed with what you’ve been able to do!!!
Ah, I did not spot that branch. Thanks.
I am wondering where we want to go with this project.
So far, I believe we have the following working on the device:
- @fabien’s port of @gundy’s demo of sprites and audio - https://github.com/Fabien-Chouteau/tinyfpga-bx-game-soc/tree/develop/examples/audio_song_player
- My Pacman game built with the same system - https://github.com/lawrie/tinyfpga-bx-game-soc/tree/develop/games/pacman_lcd
- My tetris game using that system - https://github.com/lawrie/tinyfpga-bx-game-soc/tree/develop/games/tetris_lcd
- My start at a Mario plattform game with the same system - https://github.com/lawrie/tinyfpga-bx-game-soc/tree/develop/games/platform_lcd
- @gundy’s new multi-coloured sprite system running Asteroids - https://github.com/gundy/tinyfpga-bx-game-soc/tree/feature/8_bit_colour/games/gateroids
- My SD card menu for games - https://github.com/lawrie/tiny_ram_soc/tree/master/examples/game_menu, which needs some wires soldered on to connect to the SD card reader
- The “sticky” version of that menu that needs a new multiboot configuration - https://github.com/lawrie/tiny_ram_soc/tree/master/examples/sticky_game_menu
- My PicoSoc recreation of the Atari 2600 Adventure game - https://github.com/lawrie/atari_tia_soc/tree/master/games/adventure
- Ditto for Pitfall! - https://github.com/lawrie/atari_tia_soc/tree/master/games/pitfall
- My 6502 CPU version of Atari 2600 which runs original Atari 6502 source with slight modification for horizontal timing - https://github.com/lawrie/atari_2600
Some things I am considering are:
- Using @gundy’s new system to improve games such as Pacman and Tetris, and possibly the Mario platform game
- Doing an exact timing version of the Atari 2600 which should be able to run Atari 2600 ROMs unchanged. This would probably use the microcoded 6502 CPU.
- Doing a NES port that could run the smaller (8kb) NES ROMs. This would probably be based on https://github.com/strigeus/fpganes, which uses a microcoded CPU. It looks as if it could be made to work to me.
I don’t think we have sufficient BRAM for exact recreations of later games consoles or computers.
So, the other strategy is to concentrate on a new TinyFPGA EX version of the games console, which could emulate a lot more games consoles and home computers, or which could run a much more capable system of our own design.
It would be good to do an icestorm version of the MISTer project using either an LCD or HDMI output.
Any views on this?
Yeah, I think you guys pushed it to the limits. I still want to write my own game with @gundy’s design (tetris probably), but I don’t have time right now…
I think I said it somewhere, but the FPGC prototype should be compatible with the TinyFPGA EX.
Hi Dave, I have your Gateroids game building with nextpnr now, and plan to have a look at building games with this system. Any chance you could add a resources folder with your Gimp files, Tiled files etc., like we have for other games and examples?