Developer Notes - 17/10/06
The levels are currently loaded from the GBA ROM as if they were a constant array. No files here: Lemmings DS is designed to be loaded from a GBA flashcart or Supercard.
The location of the levels within the ROM are found by searching every CUSTOM_LEVEL_STRIDE (defined in lemmings_level_rom_scanner.h) bytes (aligned to every CUSTOM_LEVEL_STRIDE) from the end of the ROM (assuming GBA ROM PORT-2 loading), the location of which is arbitrarily specified in CUSTOM_LEVEL_SCAN_RANGE_BEGIN for the string string_marker_start_of_custom_chunk_appendix, specified in lemmings_level_rom_scanner.c as "__CUSTOM_LEMMINGS_DS_LEVELS_BEGIN".
Skipping CUSTOM_LEVEL_STRIDE bytes from the first byte of string_marker_start_of_custom_chunk_appendix will give you the address of the first appended level. The size of the level is determined from the level's chunk_size field. Skipping chunk_size (padded to the next multiple of CUSTOM_LEVEL_STRIDE) will give you the address of the next level.
When a level is found, its address is placed on the end of the lemmings_ds_levels_custom_one_player array in arm9_main.cpp, and no_lemmings_ds_levels_custom is incremented.
Level validation is achieved by checking the level's validation_string against the correct_validation_string stored in lemmings_level.c.
Level searching ends when the scan cursor is outside of the scan range (CUSTOM_LEVEL_SCAN_RANGE_BEGIN - CUSTOM_LEVEL_SCAN_RANGE_END), or when a level with a malformed validation_string is found.
If the string_marker_start_of_custom_chunk_appendix is not found by the time the scan cursor reaches CUSTOM_LEVEL_MARKER_SCAN_RANGE_END then level searching is aborted.
Ingame, all graphics are drawn to a large double-buffered 15-bit backbuffer, using MODE_5_2D on the main screen.
The two buffers are located at 0x0600:0000 and 0x0620:0000. (VRAM_A_MAIN_BG_0x6000000 and VRAM_B_MAIN_BG_0x6020000) The address of the current destination backbuffer is held in drawbuffer, and is flipped by the function FlipVRAMAAndB at the end of every frame render.
The ingame level data (level_data) is stored as a 1280 by 168 (The DS' 192 pixel screen minus 24 pixels for the lower interface) array of u8s. It stores the colour of every pixel in the level, with 0 as the lemming-passable background.
The 256 colour nature of the level data allows the level overview map to be drawn on the top screen as a series of 8x8 sprites, using the same palette as the level palette. The lemmings and the currently shown area border are taken from colours at the end of the level palette.
All of the sprites are stored as constant arrays of 16 colour information, exported from Usenti.
The lemmings and their 'pop' explosions share the same (const) palette.
The levels are stored as a large structure of general level information (two structures, even), followed by a list of LEMMINGS_LEVEL_OBJECT_* structures. The type of structure (stored in the common structure LEMMINGS_LEVEL_OBJECT_HEADER) tells the level renderer how to handle the LEMMINGS_LEVEL_OBJECT_* structure.
Level pieces are drawn as they're encountered in the list. (You have to design your levels as per the painter's algorithm, or just order them correctly in the level editor.)