Recent Blogposts of WIP

Portable Game Console Project - Storage System Implemented!

Hey guys! The storage system of my portable game console is implemented!

Storage System Design

  • Each game is a ROM file stored in SD card
  • File system support: FAT16 and FAT32
  • FAT library used: Petit FAT File System Module
  • Up to 256 resources can be packed into a ROM
    • A python script were developed for packing the resources
  • Each resource can be flashed to the microcontroller
    • The first one is flashed upon the game is loaded
  • Each resource can be read by the game
    • It can be used to store static assets (like map of a level in the game)
  • Each resource can be rewritten by the game
    • Can be used for implementing game-saving feature
    • Yes, the save content is saved right inside the ROM.
  • Each resource is aligned to 512 bytes.
  • It isn't possible to seek to an offset of any resources. You have to read/write everything in the resource at once.

Why is the game save content located right inside the ROM?

It seems to be dumb to save the save content right inside the ROM file. I don't really have a choice because of the limitation of the FAT library. :(

My original idea was to have two files. One is the ROM file. Another is the save file. The save file is dynamically created by the game by using the API Calls.

However, when I tried to create the file by using the function pf_write() of the FAT library, it didn't work. Then I looked into the documentation and found out this restriction:

  • "Cannot create file. Only existing file can be written."

Alright. Then I had come up with three ideas. They're:

  • Use another FAT library
  • Pre-create a save file on the SD card
  • Write the save content right inside the ROM

Using another FAT library takes a lot of work. Pre-creating a save file on the SD card would bring quite a bit of nuisance to the player because the player would have to manually paste the save file to the SD card in addition of the ROM file. So it's apparently to me that storing the save file content right inside the ROM would be the solution to go.

Resource Alignment

Since the restriction of the file-writing function is "Cannot create file. Only existing file can be written", everything should be working after saving the content right inside the ROM, right?

It turned out that I was mistaken. When I tried writing something on the SD card, the offset of the content being written was wrong! And some of the content were corrupted by zeros. Why?

After reading the documentation again, I've found out why. The library has a function for reading from file, and another function for writing to file. The function for reading works with any file offset. However, the function for writing only works properly if the seek offset of the file is aligned to 512 bytes. Otherwise, the offset would be rounded down to the closest 512-bytes. In addition of that, the number of bytes written are padded with zeros to 512 bytes.

The solution? Simple! Just align the offset of each resources to 512 bytes and pad them.

ROM File Format

Here's the file format of the ROM of the game console.

Offset      Size    Description
0           3       Magic number
3           1       ROM file format version
4           32      Name of the game. NULL-terminated.
36          32      Author of the game. NULL-terminated.
68          256     Game Description. NULL-terminated.
324         700     Reserved
1024+8*N    4       Resource offset in file. N is from 0~255.
1024+8*N+4  4       Resource length. N is from 0~255. Can be zero.
3072        varies  The content of the resources. Each resources are aligned to 512 bytes.

ROM-packing Python Script

The python script takes a CSV input file and generate the ROM. The CSV file looks like this:

NAME,Name of the game goes here
AUTHOR,Sadale.net
DESCRIPTION,Description of the game goes here
0,assets/game.bin
1,assets/level1.map
2,assets/level2.map
128,assets/titleScreen.graphic
254,[1024]

It's rather obvious what does the CSV do except the last line. For the resource #254, it allocates a resource that contains 1024 bytes of zero. It's useful for allocating space for save file of the game.

API Calls

It's simple. There're only three functions.

  • void storageFlash(uint8_t resNum);
  • uint16_t storageRead(uint8_t resNum, void *buf, uint16_t len);
  • uint16_t storageWrite(uint8_t resNum, void *buf, uint16_t len);

It's rather intuitive. I guess I don't need to explain it here. :P

Sample program

To demonstrate that the storage system is working, I've developed a test program. The program is capable for playing three kind of sound with configurable duty cycle. The function of the buttons are shown below:

  • Up: Reduce duty cycle
  • Down: Increase duty cycle
  • Left: Select the previous sound
  • Right: Select the next sound
  • Button A: Play the sound
  • Button B: Save the sound

Click here and see how does the code of the program looks like. Please notice that this isn't a complete project and it's not buildable without extif.h, which I'm not releasing until the completion of the software.

After saving the content of the file, here's how does the content of the ROM looks like:

Content of ROM showing the bytes 0x55, 0x01 and 0x01

As you can see above, the first byte 0x55 is the magic number. It's used for informing the program that the save data is valid.

The second one is the sound ID. The value of 0x01 refers to the second sound.

The third one is duty cycle. A value of 0x01 refers to 50% duty cycle.

After relaunching the program, the sound and the duty cycle will be loaded. I've tested it. The sound was played correctly after I pressed the Button A. :)

What's next?

I'll be working on the following stuffs:

  • Graphic system
  • Power-saving, clock rate adjustment, etc.
  • Menu for game selection and stuffs

That's it for now. I'll update you guys for any progress! :)


[WIP]Cellphone Diver - Result Scene

Jan. 20, 2016, 10:06 a.m. Cellphone Diver Gamedev WIP

Just implemented the result scene of Cellphone Diver!

Screenshot of Cellphone Diver Result Scene

As shown on the screenshot above, the result scene shows the number of snail collected, earning contributed by the diving depth, diving time and the total of three.

Next task: Implement upgrade store!


[WIP]Cellphone Diver Prototype Update: Version 0.0.2

Jan. 15, 2016, 2:24 p.m. Cellphone Diver Gamedev WIP

The prototype version of Cellphone Diver is just updated to version 0.0.2!

Screenshot of Cellphone Diver Prototype

What's new:

  • Oxygen Implemented
  • Size of item reduced
  • Implemented new items: bubble, fish, starfish

Click here to play!


[WIP]Cellphone Diver Prototype Available!

Jan. 10, 2016, 3:06 p.m. Cellphone Diver Gamedev WIP

The prototype version of Cellphone Diver is now available!

Screenshot of Cellphone Diver Prototype

Click here to play!


[WIP]Cellphone Diver Game Design

Jan. 6, 2016, 10:04 a.m. Cellphone Diver Gamedev WIP

Behold the design document of our coming game Cellphone Diver!

Gameplay

  • initial downward speed
  • the speed gets slower and slower over time.
  • oxygen: consumed when you dive.
  • repeatedly press s to dive for maintaining the speed. Consumes oxygen.
  • left/right key to change the angle of movement
  • boost: put you in high speed for a short time. Does not consume oxygen.

Undersea items

  • plastic bags: slows you down
  • mines: instant death
  • bubble: recovers oxygen
  • snail: for purchasing upgrades
  • sea star: boost

Available upgrades

  • Launcher: affects initial speed
  • Upper body clothes: affects diving speed and damping
  • Lower body clothes: affects oxygen consumption and damping
  • Shoes: affects initial speed and damping
  • Backpack: affects oxygen, boost and weight
  • Headwear: affects initial speed, spawn probability of undersea items and lives

Endings

  • 2 endings designed. No startover is needed to get all two endings.