How to make iLoader Themes
Some notes by Farthen follow, but this is nowhere near complete.
This will explain how to make own themes for iLoader.
Theme structure
A theme consists of these parts:- A config file, that describes the behaviour of iLoader
- Bitmaps that may be displayed by iLoader
Folder structure
iLoader expects to see a specific filesystem structure. So start off and create these two folders in a working directory:- iLoader/
- theme/
- bitmap1.ucl
- bitmap2.ucl
- bitmap3.ucl
- iloader.cfg
Bitmaps
To start with a theme it is recommended to make some bitmaps that will then be displayed on the iPod. Just take your favourite picture editing program like Photoshop or GIMP and start making something cool. The resolution if the iPod's display is 176 x 132 pixels.You can start with an image for the menu, then create images that get displayed when booting a firmware.
Once you are done with the images you need to save them as a RGB565 bitmap (also called r5g6b5 sometimes) and put them in the "theme" folder.
Config file
iLoader needs to have a config file to work properly. With the config file you can set all kinds of things like a delay until a default entry gets booted and also the files that get loaded when you press a secific button etc.It is essentially a simple programming language that tells iLoader what to do that is compiled and put on the iPod.
As an example, here is a download link to the source code of the default theme: iloader.conf
It should be easy to adapt it for your needs.
Structure
The config file consists of two parts:- The vector table - tells iLoader which functions to execute if specific buttons/button combinations are pressed at startup and where to jump if an error occurs
- The code - a description of the things that iLoader should do
Code syntax
The compiler uses a pretty easy code syntax. It consists of commands and arguments that are surrounded by parantheses.Example:
readflash(0x08000000, "diskmode")
readfile is the command, 0x08000000 is the first argument, "diskmode" is the second argument.
There are also functions that don't have any arguments:
blit()
Also it supports labels that work as pointers to the location in the file:
label1:
You can use them to make a reference to a function:
jmp(label1)
You can make comments by putting a # sign before them. The rest of the line is ignored by the compiler:
# This is a comment
Vector table
The vector table is a description of what to do when buttons are pressed. Here is the vector table from the default theme:# nothing center right center+right .word(wheel) .word(wheel) .word(wheel) .word(ibugger) # +nothing .word(wheel) .word(diagmode) .word(wheel) .word(wheel) # +left .word(wheel) .word(diskmode) .word(wheel) .word(wheel) # +play .word(wheel) .word(wheel) .word(wheel) .word(wheel) # +play+left .word(wheel) .word(wheel) .word(wheel) .word(wheel) # +menu .word(wheel) .word(wheel) .word(wheel) .word(wheel) # +menu+left .word(wheel) .word(wheel) .word(wheel) .word(wheel) # +play+menu .word(wheel) .word(wheel) .word(wheel) .word(wheel) # +play+menu+left # error handler .word(0xffffffff)
It should be easy to understand:
- The .word statement indicates that the compiler should insert a word (4 bytes) at the specified location, in this case starting at the very beginning of the file.
- The labels in the parantheses define what to excute when the specified button/combination is pressed on startup.
.word(diskmode)
in the second line as the second statement. (essentially as the 10th statement in the file)
Be careful: You NEED to specify all 34 .word statements and MUST NOT leave any statement out as this will lead to UNEXPECTED results.
Hint: If you have bugs in your theme and it will not load you may be forced to use norloader to restore.
To make your life a little bit easier you should make at least one key combo point to 0xffffffff instead of a label. This is an invalid address, and thus will drop into the recovery menu.
Loading firmwares
Now it is time for a small example to load the firmware file called "myos.bin" that is located in the root directory of the flash. We edited the vector table to make the it jump to the label "myos" automatically when the left button is being pressed during boot.myos: # Reads the file "/myos/myos.bin" from the flash to # 0x08000000 (the beginning of SDRAM) readfile(0x08000000, "/myos/myos.bin") # Turn on the backlight with the brightness 200 (of 255) and a fading speed of 32 backlight(1, 200, 32) # Execute the file that we just loaded from the flash exec(0x08000000)
As mentioned before it is recommended to edit the default config to your needs.
For descriptions of the available commands see the command reference.
Displaying images
Why do we do all this? To make a theme, right. And what would be a theme without some nice graphics? Not much.So after much theory and some examples to run firmwares you will get to learn how to make the iPod display a background image and make it have a small menu that jumps to the specified labels when buttons are pressed.
Beforehand we have edited the vector table to make it jump to the label "wheel" when nothing is pressed on startup.
So how does "wheel" look like? (parts taken from the default config)
wheel: readfile(0x08000000, "/iLoader/theme/menu.bmp") # Display the Bitmap we just loaded at position 0,0 # (upper left corner of the display) displaybmp(0, 0, 0x08000000) # Refresh the display to see the changes blit() # Make the center button jump to the label "diskmode", # right to run iBugger etc. button(diskmode, ibugger, appleos, rockbox, menu, 30000000) poweroff: # Shut down if the time specified before # (30000000 microseconds, 30 minutes) is over poweroff()
UCL Compression
You are pretty far. You made some pretty images, learned a lot about the config file and displayed the images to make a nice theme.To make it a little bit better, you should compress your bitmaps with UCL, because they are much smaller then.
This leads to the following advantages:
- smaller flash footprint
- faster loading time
To do this, use the tool "ucl2e10singleblk" from the ipodtools package. Open a command prompt in this directory and execute:
./ucl2e10singleblk path/to/bitmap.bmp path/to/bitmap.ucl
Do this for all of your images. Then remove the bitmaps from your working directory.
To make the example code from before work with the ucl compressed bitmaps change it to this:
wheel: # Load the file "menu.ucl" to 0x08000000 readfile(0x08000000, "/iLoader/theme/menu.ucl") # Unpack the bitmap we just loaded to 0x09000000 unpackucl(0x08000000, 0x09000000) # Display the unpacked bitmap displaybmp(0, 0, 0x09000000) # Refresh the display to see the changes blit() button(diskmode, ibugger, appleos, rockbox, menu, 30000000) poweroff: poweroff()