initial commit

This commit is contained in:
wgroeneveld 2018-08-01 16:03:16 +02:00
parent b11aef386d
commit b27b2be640
43 changed files with 6169 additions and 0 deletions

90
.gitignore vendored
View File

@ -1,3 +1,93 @@
# Created by https://www.gitignore.io/api/clion,cmake
### CLion ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
### CLion Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
.idea/sonarlint
### CMake ###
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
# End of https://www.gitignore.io/api/clion,cmake
# Prerequisites
*.d

16
CMakeLists.txt Normal file
View File

@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.10)
SET(CMAKE_C_COMPILER arm-none-eabi-gcc)
SET(CMAKE_CXX_COMPILER arm-none-eabi-g++)
SET(CMAKE_OBJCOPY arm-none-eabi-objcopy)
SET(BASE_CMAKE_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
SET(CMAKE_EXE_LINKER_FLAGS "${BASE_CMAKE_LINK_FLAGS} -mthumb-interwork -mthumb -specs=gba.specs")
project(gba-sprite-engine)
SET(CMAKE_CXX_STANDARD 11)
set(CMAKE_VERBOSE_MAKEFILE on)
include_directories(src)
include_directories(test)
add_subdirectory(src)
add_subdirectory(test)

9
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,9 @@
SET(CMAKE_C_COMPILER arm-none-eabi-gcc)
SET(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set_property(SOURCE engine/gba/sin_lut.s PROPERTY LANGUAGE C)
add_executable(${PROJECT_NAME}.elf main.cpp engine/sprites/sprite_manager.cpp engine/sprites/sprite_manager.h engine/gba/tonc_memmap.h engine/gba/tonc_core.h engine/gba/tonc_memdef.h engine/gba/tonc_types.h engine/sprites/sprite.cpp engine/sprites/sprite.h kul.h engine/palette_manager.cpp engine/palette_manager.h engine/allocator.cpp engine/allocator.h engine/gba/tonc_oam.h engine/gba/tonc_math.h engine/gba/sin_lut.s engine/Scene.cpp engine/Scene.h engine/sprites/sprite_builder.cpp engine/sprites/sprite_builder.h engine/sprites/affine_sprite.cpp engine/sprites/affine_sprite.h flying_stuff_scene.cpp flying_stuff_scene.h engine/gba_engine.cpp engine/gba_engine.h engine/background/text_stream.cpp engine/background/text_stream.h engine/background/background.cpp engine/background/background.h engine/background/text.h)
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -v -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.gba
)

5
src/engine/Scene.cpp Normal file
View File

@ -0,0 +1,5 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#include "Scene.h"

29
src/engine/Scene.h Normal file
View File

@ -0,0 +1,29 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#ifndef GBA_SPRITE_ENGINE_SCRENE_H
#define GBA_SPRITE_ENGINE_SCRENE_H
#include <vector>
#include <engine/background/background.h>
#include "engine/sprites/sprite.h"
class Scene {
public:
// bg in here
// bg music in here
virtual std::vector<Sprite*> sprites() = 0;
virtual std::vector<Background*> backgrounds() = 0;
virtual void load() = 0;
virtual void tick() = 0;
Scene() { }
~Scene() {
// scenes should manage their own resources - use std::unique_ptr
}
};
#endif //GBA_SPRITE_ENGINE_SCRENE_H

27
src/engine/allocator.cpp Normal file
View File

@ -0,0 +1,27 @@
//
// Created by Wouter Groeneveld on 27/07/18.
//
#include <stdexcept>
#include "allocator.h"
u32 voidPtrToU32(void* ptr) {
return static_cast<u32>(reinterpret_cast<intptr_t>(ptr));
}
u32 Allocator::currentSpriteIndex;
std::vector<AllocatedData> Allocator::allocatedSprites;
AllocatedData& Allocator::allocateObjectTiles(u32 size) {
AllocatedData s(currentSpriteIndex, size, MEM_OBJ_VRAM_BASE);
currentSpriteIndex += size;
allocatedSprites.push_back(s);
return allocatedSprites.at(allocatedSprites.size() - 1);
}
void Allocator::free() {
allocatedSprites.clear();
currentSpriteIndex = MEM_OBJ_VRAM_BASE;
}

46
src/engine/allocator.h Normal file
View File

@ -0,0 +1,46 @@
//
// Created by Wouter Groeneveld on 27/07/18.
// very loosely based on: https://github.com/Jambo51/GBA-Pokemon-Engine/blob/master/source/Entities/OAMObject.cpp
//
#ifndef GBA_SPRITE_ENGINE_ALLOCATOR_H
#define GBA_SPRITE_ENGINE_ALLOCATOR_H
#include <engine/gba/tonc_types.h>
#include <engine/gba/tonc_memmap.h>
#include <vector>
#define MEM_OBJ_VRAM_BASE (MEM_VRAM + VRAM_BG_SIZE)
u32 voidPtrToU32(void* ptr);
class AllocatedData {
public:
void * pointer()const { return (void*) currentAddress; };
u32 size, currentAddress, baseAddress;
const int getTileLocation()const {
return (currentAddress - baseAddress) >> 5;
}
AllocatedData(u32 address, u32 size, u32 base) : currentAddress(address), size(size), baseAddress(base) {}
};
class Allocator {
private:
Allocator() = delete;
Allocator(Allocator& other) = delete;
Allocator(Allocator&& other) = delete;
static u32 currentSpriteIndex;
static std::vector<AllocatedData> allocatedSprites;
public:
static void free();
static u32 getCurrentSpriteIndex() { return currentSpriteIndex; }
static int getAllocatedSprites() { return allocatedSprites.size(); }
static AllocatedData& allocateObjectTiles(u32 size);
};
#endif //GBA_SPRITE_ENGINE_ALLOCATOR_H

View File

@ -0,0 +1,66 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#include <engine/gba/tonc_memmap.h>
#include <stdexcept>
#include <engine/allocator.h>
#include <engine/gba/tonc_core.h>
#include "background.h"
#include "text_stream.h"
#define TRANSPARENT_TILE_NUMBER 192 // as shown in mGBA, next "free" tile after text. Hardcoded indeed.
// WHY using this instead of Allocation?
// Because each char block seems to be 16K and there are 4 - there are also 4 backgrounds.
// Use the bgIndex as a hardcoded char block and let the background decide on the map screen block.
void* screen_block(unsigned long block) {
return (void*) (0x6000000 + (block * 0x800));
}
void* char_block(unsigned long block) {
return (void*) (0x6000000 + (block * 0x4000));
}
void Background::persist() {
dma3_cpy(char_block(bgIndex), this->data, this->size);
if(this->map) {
dma3_cpy(screen_block(screenBlockIndex), this->map, this->mapSize);
}
buildRegister();
}
void Background::clearMap() {
volatile auto ptr = &se_mem[screenBlockIndex][0];
for (int i = 0; i < this->mapSize; i++) {
ptr[i] = TRANSPARENT_TILE_NUMBER;
}
}
u32 Background::getBgControlRegisterIndex() {
switch(bgIndex) {
case 0: return 0x0008;
case 1: return 0x000A;
case 2: return 0x000C;
case 3: return 0x000E;
}
throw std::runtime_error("unknown bg index");
}
void Background::buildRegister() {
*(vu16*)(REG_BASE+getBgControlRegisterIndex()) =
bgIndex | /* priority, 0 is highest, 3 is lowest */
(bgIndex << 2) | /* the char block the image data is stored in */
(0 << 6) | /* the mosaic flag */
(1 << 7) | /* color mode, 0 is 16 colors, 1 is 256 colors */
(screenBlockIndex << 8) | /* the screen block the tile data is stored in */
(1 << 13) | /* wrapping flag */
(0 << 14);
}
void Background::scroll(int x, int y) {
REG_BG_OFS[bgIndex].x = x;
REG_BG_OFS[bgIndex].y = y;
}

View File

@ -0,0 +1,36 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#ifndef GBA_SPRITE_ENGINE_BACKGROUND_H
#define GBA_SPRITE_ENGINE_BACKGROUND_H
#include <engine/gba/tonc_types.h>
class Background {
private:
void buildRegister();
u32 getBgControlRegisterIndex();
protected:
const void *data;
const void *map;
int size, bgIndex;
int mapSize;
int screenBlockIndex, charBlockIndex;
public:
const int getScreenBlock() { return screenBlockIndex; }
const int getCharBlock() { return charBlockIndex; }
void useMapScreenBlock(int block) { screenBlockIndex = block; }
void scroll(int x, int y);
Background(int bgIndex, const void *data, int size, const void* map, int mapSize) : data(data), bgIndex(bgIndex), size(size), map(map),
screenBlockIndex(0), charBlockIndex(0), mapSize(mapSize) {}
void persist();
void clearMap();
};
#endif //GBA_SPRITE_ENGINE_BACKGROUND_H

View File

@ -0,0 +1,526 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#ifndef GBA_SPRITE_ENGINE_TEXT_H
#define GBA_SPRITE_ENGINE_TEXT_H
#define text_background_width 256
#define text_background_height 24
const unsigned char text_data [] = {
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF1, 0xF5,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF1, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF1, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1,
0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF1, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF5, 0xF1, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF1, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF1, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF1, 0xF5, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF1, 0xF5, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF1, 0xF5, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF1, 0xF5,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF1, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF1, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF5, 0xF1, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1,
0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF5,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF5, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
};
#endif //GBA_SPRITE_ENGINE_TEXT_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,82 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#include <engine/gba/tonc_memmap.h>
#include "text_stream.h"
TextStream* TextStream::inst;
void TextStream::clear() {
currRow = 0;
currCol = 0;
clearMap();
}
TextStream::TextStream() : Background(0, text_data, sizeof(text_data), nullptr, TILE_WIDTH * TILE_WIDTH), currCol(0), currRow(0) {
useMapScreenBlock(24);
persist();
clearMap();
}
void log_text(const char* text) {
TextStream::instance().clear();
TextStream::instance() << text;
}
void consoleLog_func(const char* fileName, const int lineNr, const char* fnName, const char* msg) {
TextStream::instance().clear();
char lineNrBuf[10];
itoa(lineNr, lineNrBuf, 10);
TextStream::instance() <<
(std::string("DEBUG: ") +
std::string(fileName) +
std::string(":") +
std::string(fnName) +
std::string("@") +
std::string(lineNrBuf) +
std::string(" -- ") +
std::string(msg))
.c_str();
}
TextStream& TextStream::instance() {
if(!inst) {
inst = new TextStream();
}
return *inst;
}
// thank you Ian
// http://cs.umw.edu/~finlayson/class/spring18/cpsc305/
void TextStream::setText(const char* text, int row, int col) {
int index = row * TILE_WIDTH + col;
volatile auto ptr = &se_mem[screenBlockIndex][0];
while (*text) {
ptr[index] = *text - CHAR_OFFSET_INDEX;
index++;
text++;
}
}
TextStream& TextStream::operator<<(const int s) {
return *this << std::to_string(s).c_str();
}
TextStream& TextStream::operator<<(const u32 s) {
return *this << std::to_string(s).c_str();
}
TextStream& TextStream::operator<<(const bool s) {
return *this << (s ? "TRUE" : "FALSE");
}
TextStream& TextStream::operator<<(const char * s) {
setText(s, currRow, currCol);
currRow++;
return *this;
}

View File

@ -0,0 +1,41 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#ifndef GBA_SPRITE_ENGINE_TEXT_STREAM_H
#define GBA_SPRITE_ENGINE_TEXT_STREAM_H
#include "background.h"
#include "text.h"
#include <string>
#define CHAR_OFFSET_INDEX 32
#define TILE_WIDTH 32
#define failure(__mess) (consoleLog_func(__FILE__, __LINE__, __PRETTY_FUNCTION__, #__mess))
void log_text(const char* text);
void consoleLog_func(const char* fileName, const int lineNr, const char* fnName, const char* msg);
class TextStream : public Background {
private:
int currRow, currCol;
static TextStream* inst;
TextStream();
TextStream(TextStream& other) = delete;
TextStream(TextStream&& other) = delete;
public:
void clear();
void setText(const char* text, int row, int col);
static TextStream& instance();
TextStream& operator << (const char* s);
TextStream& operator << (const int s);
TextStream& operator << (const u32 s);
TextStream& operator << (const bool s);
};
#endif //GBA_SPRITE_ENGINE_TEXT_STREAM_H

90
src/engine/gba/sin_lut.s Normal file
View File

@ -0,0 +1,90 @@
@ ======================================================================
@ Look-Up Tables
@ sin_lut: sin(x*pi/256)
@
@ Exported by Cearn's excellut v1.0
@ (comments, kudos, flames to daytshen@hotmail.com)
@
@ ======================================================================
.section .rodata
@ -----------------------------------------------------------------------
@ sin_lut: a 514 long LUT of 16bit values in 4.12 format
@ sin(x*pi/256)
.global sin_lut
.align 2
sin_lut:
.hword 0x0000,0x0032,0x0064,0x0096,0x00C8,0x00FB,0x012D,0x015F
.hword 0x0191,0x01C3,0x01F5,0x0227,0x0259,0x028A,0x02BC,0x02ED
.hword 0x031F,0x0350,0x0381,0x03B2,0x03E3,0x0413,0x0444,0x0474
.hword 0x04A5,0x04D5,0x0504,0x0534,0x0563,0x0593,0x05C2,0x05F0
.hword 0x061F,0x064D,0x067B,0x06A9,0x06D7,0x0704,0x0731,0x075E
.hword 0x078A,0x07B7,0x07E2,0x080E,0x0839,0x0864,0x088F,0x08B9
.hword 0x08E3,0x090D,0x0936,0x095F,0x0987,0x09B0,0x09D7,0x09FF
.hword 0x0A26,0x0A4D,0x0A73,0x0A99,0x0ABE,0x0AE3,0x0B08,0x0B2C
.hword 0x0B50,0x0B73,0x0B96,0x0BB8,0x0BDA,0x0BFC,0x0C1D,0x0C3E
.hword 0x0C5E,0x0C7D,0x0C9D,0x0CBB,0x0CD9,0x0CF7,0x0D14,0x0D31
.hword 0x0D4D,0x0D69,0x0D84,0x0D9F,0x0DB9,0x0DD2,0x0DEB,0x0E04
.hword 0x0E1C,0x0E33,0x0E4A,0x0E60,0x0E76,0x0E8B,0x0EA0,0x0EB4
.hword 0x0EC8,0x0EDB,0x0EED,0x0EFF,0x0F10,0x0F21,0x0F31,0x0F40
.hword 0x0F4F,0x0F5D,0x0F6B,0x0F78,0x0F85,0x0F91,0x0F9C,0x0FA7
.hword 0x0FB1,0x0FBA,0x0FC3,0x0FCB,0x0FD3,0x0FDA,0x0FE1,0x0FE7
.hword 0x0FEC,0x0FF0,0x0FF4,0x0FF8,0x0FFB,0x0FFD,0x0FFE,0x0FFF
.hword 0x1000,0x0FFF,0x0FFE,0x0FFD,0x0FFB,0x0FF8,0x0FF4,0x0FF0
.hword 0x0FEC,0x0FE7,0x0FE1,0x0FDA,0x0FD3,0x0FCB,0x0FC3,0x0FBA
.hword 0x0FB1,0x0FA7,0x0F9C,0x0F91,0x0F85,0x0F78,0x0F6B,0x0F5D
.hword 0x0F4F,0x0F40,0x0F31,0x0F21,0x0F10,0x0EFF,0x0EED,0x0EDB
.hword 0x0EC8,0x0EB4,0x0EA0,0x0E8B,0x0E76,0x0E60,0x0E4A,0x0E33
.hword 0x0E1C,0x0E04,0x0DEB,0x0DD2,0x0DB9,0x0D9F,0x0D84,0x0D69
.hword 0x0D4D,0x0D31,0x0D14,0x0CF7,0x0CD9,0x0CBB,0x0C9D,0x0C7D
.hword 0x0C5E,0x0C3E,0x0C1D,0x0BFC,0x0BDA,0x0BB8,0x0B96,0x0B73
.hword 0x0B50,0x0B2C,0x0B08,0x0AE3,0x0ABE,0x0A99,0x0A73,0x0A4D
.hword 0x0A26,0x09FF,0x09D7,0x09B0,0x0987,0x095F,0x0936,0x090D
.hword 0x08E3,0x08B9,0x088F,0x0864,0x0839,0x080E,0x07E2,0x07B7
.hword 0x078A,0x075E,0x0731,0x0704,0x06D7,0x06A9,0x067B,0x064D
.hword 0x061F,0x05F0,0x05C2,0x0593,0x0563,0x0534,0x0504,0x04D5
.hword 0x04A5,0x0474,0x0444,0x0413,0x03E3,0x03B2,0x0381,0x0350
.hword 0x031F,0x02ED,0x02BC,0x028A,0x0259,0x0227,0x01F5,0x01C3
.hword 0x0191,0x015F,0x012D,0x00FB,0x00C8,0x0096,0x0064,0x0032
.hword 0x0000,0xFFCE,0xFF9C,0xFF6A,0xFF38,0xFF05,0xFED3,0xFEA1
.hword 0xFE6F,0xFE3D,0xFE0B,0xFDD9,0xFDA7,0xFD76,0xFD44,0xFD13
.hword 0xFCE1,0xFCB0,0xFC7F,0xFC4E,0xFC1D,0xFBED,0xFBBC,0xFB8C
.hword 0xFB5B,0xFB2B,0xFAFC,0xFACC,0xFA9D,0xFA6D,0xFA3E,0xFA10
.hword 0xF9E1,0xF9B3,0xF985,0xF957,0xF929,0xF8FC,0xF8CF,0xF8A2
.hword 0xF876,0xF849,0xF81E,0xF7F2,0xF7C7,0xF79C,0xF771,0xF747
.hword 0xF71D,0xF6F3,0xF6CA,0xF6A1,0xF679,0xF650,0xF629,0xF601
.hword 0xF5DA,0xF5B3,0xF58D,0xF567,0xF542,0xF51D,0xF4F8,0xF4D4
.hword 0xF4B0,0xF48D,0xF46A,0xF448,0xF426,0xF404,0xF3E3,0xF3C2
.hword 0xF3A2,0xF383,0xF363,0xF345,0xF327,0xF309,0xF2EC,0xF2CF
.hword 0xF2B3,0xF297,0xF27C,0xF261,0xF247,0xF22E,0xF215,0xF1FC
.hword 0xF1E4,0xF1CD,0xF1B6,0xF1A0,0xF18A,0xF175,0xF160,0xF14C
.hword 0xF138,0xF125,0xF113,0xF101,0xF0F0,0xF0DF,0xF0CF,0xF0C0
.hword 0xF0B1,0xF0A3,0xF095,0xF088,0xF07B,0xF06F,0xF064,0xF059
.hword 0xF04F,0xF046,0xF03D,0xF035,0xF02D,0xF026,0xF01F,0xF019
.hword 0xF014,0xF010,0xF00C,0xF008,0xF005,0xF003,0xF002,0xF001
.hword 0xF000,0xF001,0xF002,0xF003,0xF005,0xF008,0xF00C,0xF010
.hword 0xF014,0xF019,0xF01F,0xF026,0xF02D,0xF035,0xF03D,0xF046
.hword 0xF04F,0xF059,0xF064,0xF06F,0xF07B,0xF088,0xF095,0xF0A3
.hword 0xF0B1,0xF0C0,0xF0CF,0xF0DF,0xF0F0,0xF101,0xF113,0xF125
.hword 0xF138,0xF14C,0xF160,0xF175,0xF18A,0xF1A0,0xF1B6,0xF1CD
.hword 0xF1E4,0xF1FC,0xF215,0xF22E,0xF247,0xF261,0xF27C,0xF297
.hword 0xF2B3,0xF2CF,0xF2EC,0xF309,0xF327,0xF345,0xF363,0xF383
.hword 0xF3A2,0xF3C2,0xF3E3,0xF404,0xF426,0xF448,0xF46A,0xF48D
.hword 0xF4B0,0xF4D4,0xF4F8,0xF51D,0xF542,0xF567,0xF58D,0xF5B3
.hword 0xF5DA,0xF601,0xF629,0xF650,0xF679,0xF6A1,0xF6CA,0xF6F3
.hword 0xF71D,0xF747,0xF771,0xF79C,0xF7C7,0xF7F2,0xF81E,0xF849
.hword 0xF876,0xF8A2,0xF8CF,0xF8FC,0xF929,0xF957,0xF985,0xF9B3
.hword 0xF9E1,0xFA10,0xFA3E,0xFA6D,0xFA9D,0xFACC,0xFAFC,0xFB2B
.hword 0xFB5B,0xFB8C,0xFBBC,0xFBED,0xFC1D,0xFC4E,0xFC7F,0xFCB0
.hword 0xFCE1,0xFD13,0xFD44,0xFD76,0xFDA7,0xFDD9,0xFE0B,0xFE3D
.hword 0xFE6F,0xFEA1,0xFED3,0xFF05,0xFF38,0xFF6A,0xFF9C,0xFFCE
.hword 0x0000,0x0032
.size sin_lut, .-sin_lut

573
src/engine/gba/tonc_core.h Normal file
View File

@ -0,0 +1,573 @@
//
// Core functionality
//
//! \file tonc_core.h
//! \author J Vijn
//! \date 20060508 - 20080128
//
/* === NOTES ===
* Contents: bits, random, dma, timer
* 20080129,jv: added tonccpy/set routines.
*/
#ifndef TONC_CORE
#define TONC_CORE
#include "tonc_memmap.h"
#include "tonc_memdef.h"
// --------------------------------------------------------------------
// BITS and BITFIELDS
// --------------------------------------------------------------------
/*! \defgroup grpCoreBit Bit(field) macros
\ingroup grpCore
*/
/*! \{ */
//! \name Simple bit macros
//\{
//! Create value with bit \a n set
#define BIT(n) ( 1<<(n) )
//! Shift \a a by \a n
#define BIT_SHIFT(a, n) ( (a)<<(n) )
//! Create a bitmask \a len bits long
#define BIT_MASK(len) ( BIT(len)-1 )
//! Set the \a flag bits in \a word
#define BIT_SET(y, flag) ( y |= (flag) )
//! Clear the \a flag bits in \a word
#define BIT_CLEAR(y, flag) ( y &= ~(flag) )
//! Flip the \a flag bits in \a word
#define BIT_FLIP(y, flag) ( y ^= (flag) )
//! Test whether all the \a flag bits in \a word are set
#define BIT_EQ(y, flag) ( ((y)&(flag)) == (flag) )
//! Create a bitmask of length \a len starting at bit \a shift.
#define BF_MASK(shift, len) ( BIT_MASK(len)<<(shift) )
//! Retrieve a bitfield mask of length \a starting at bit \a shift from \a y.
#define _BF_GET(y, shift, len) ( ((y)>>(shift))&BIT_MASK(len) )
//! Prepare a bitmask for insertion or combining.
#define _BF_PREP(x, shift, len) ( ((x)&BIT_MASK(len))<<(shift) )
//! Insert a new bitfield value \a x into \a y.
#define _BF_SET(y, x, shift, len) \
( y= ((y) &~ BF_MASK(shift, len)) | _BF_PREP(x, shift, len) )
//\}
/*! \name some EVIL bit-field operations, >:)
* These allow you to mimic bitfields with macros. Most of the
* bitfields in the registers have <i>foo</i>_SHIFT and
* <i>foo</i>_SHIFT macros indicating the mask and shift values
* of the bitfield named <i>foo</i> in a variable.
* These macros let you prepare, get and set the bitfields.
*/
//\{
//! Prepare a named bit-field for for insterion or combination.
#define BFN_PREP(x, name) ( ((x)<<name##_SHIFT) & name##_MASK )
//! Get the value of a named bitfield from \a y. Equivalent to (var=) y.name
#define BFN_GET(y, name) ( ((y) & name##_MASK)>>name##_SHIFT )
//! Set a named bitfield in \a y to \a x. Equivalent to y.name= x.
#define BFN_SET(y, x, name) (y = ((y)&~name##_MASK) | BFN_PREP(x,name) )
//! Compare a named bitfield to named literal \a x.
#define BFN_CMP(y, x, name) ( ((y)&name##_MASK) == (x) )
//! Massage \a x for use in bitfield \a name with pre-shifted \a x
#define BFN_PREP2(x, name) ( (x) & name##_MASK )
//! Get the value of bitfield \a name from \a y, but don't down-shift
#define BFN_GET2(y, name) ( (y) & name##_MASK )
//! Set bitfield \a name from \a y to \a x with pre-shifted \a x
#define BFN_SET2(y,x,name) ( y = ((y)&~name##_MASK) | BFN_PREP2(x,name) )
//\}
INLINE u32 bf_get(u32 y, uint shift, uint len);
INLINE u32 bf_merge(u32 y, u32 x, uint shift, uint len);
INLINE u32 bf_clamp(int x, uint len);
INLINE int bit_tribool(u32 x, uint plus, uint minus);
INLINE u32 ROR(u32 x, uint ror);
/*! \} */
// --------------------------------------------------------------------
// DATA
// --------------------------------------------------------------------
/*! \defgroup grpData Data routines
\ingroup grpCore
*/
/*! \{ */
//! Get the number of elements in an array
#define countof(_array) ( sizeof(_array)/sizeof(_array[0]) )
//! Align \a x to the next multiple of \a width.
INLINE uint align(uint x, uint width);
//! \name Copying and filling routines
//\{
//! Simplified copier for GRIT-exported data.
#define GRIT_CPY(dst, name) memcpy16(dst, name, name##Len/2)
// Base memcpy/set replacements.
void *tonccpy(void *dst, const void *src, uint size);
void *__toncset(void *dst, u32 fill, uint size);
INLINE void *toncset(void *dst, u8 src, uint count);
INLINE void *toncset16(void *dst, u16 src, uint count);
INLINE void *toncset32(void *dst, u32 src, uint count);
// Fast memcpy/set
void memset16(void *dst, u16 hw, uint hwcount);
void memcpy16(void *dst, const void* src, uint hwcount);
IWRAM_CODE void memset32(void *dst, u32 wd, uint wcount);
IWRAM_CODE void memcpy32(void *dst, const void* src, uint wcount);
//! Fastfill for halfwords, analogous to memset()
/*! Uses <code>memset32()</code> if \a hwcount>5
* \param dst Destination address.
* \param hw Source halfword (not address).
* \param hwcount Number of halfwords to fill.
* \note \a dst <b>must</b> be halfword aligned.
* \note \a r0 returns as \a dst + \a hwcount*2.
*/
void memset16(void *dst, u16 hw, uint hwcount);
//! \brief Copy for halfwords.
/*! Uses <code>memcpy32()</code> if \a hwn>6 and
\a src and \a dst are aligned equally.
\param dst Destination address.
\param src Source address.
\param hwcount Number of halfwords to fill.
\note \a dst and \a src <b>must</b> be halfword aligned.
\note \a r0 and \a r1 return as
\a dst + \a hwcount*2 and \a src + \a hwcount*2.
*/
void memcpy16(void *dst, const void* src, uint hwcount);
//! Fast-fill by words, analogous to memset()
/*! Like CpuFastSet(), only without the requirement of
32byte chunks and no awkward store-value-in-memory-first issue.
\param dst Destination address.
\param wd Fill word (not address).
\param wdcount Number of words to fill.
\note \a dst <b>must</b> be word aligned.
\note \a r0 returns as \a dst + \a wdcount*4.
*/
IWRAM_CODE void memset32(void *dst, u32 wd, uint wdcount);
//! \brief Fast-copy by words.
/*! Like CpuFastFill(), only without the requirement of 32byte chunks
\param dst Destination address.
\param src Source address.
\param wdcount Number of words.
\note \a src and \a dst <b>must</b> be word aligned.
\note \a r0 and \a r1 return as
\a dst + \a wdcount*4 and \a src + \a wdcount*4.
*/
IWRAM_CODE void memcpy32(void *dst, const void* src, uint wdcount);
//\}
/*! \name Repeated-value creators
These function take a hex-value and duplicate it to all fields,
like 0x88 -> 0x88888888.
*/
//\{
INLINE u16 dup8(u8 x);
INLINE u32 dup16(u16 x);
INLINE u32 quad8(u8 x);
INLINE u32 octup(u8 x);
//\}
//! \name Packing routines.
//\{
INLINE u16 bytes2hword(u8 b0, u8 b1);
INLINE u32 bytes2word(u8 b0, u8 b1, u8 b2, u8 b3);
INLINE u32 hword2word(u16 h0, u16 h1);
//\}
/*! \} */
// --------------------------------------------------------------------
// DMA
// --------------------------------------------------------------------
/*! \addtogroup grpDma */
/*! \{ */
//! General purpose DMA transfer macro
/*! \param _dst Destination address.
\param _src Source address.
\param count Number of transfers.
\param ch DMA channel.
\param mode DMA mode.
*/
#define DMA_TRANSFER(_dst, _src, count, ch, mode) \
do { \
REG_DMA[ch].cnt= 0; \
REG_DMA[ch].src= (const void*)(_src); \
REG_DMA[ch].dst= (void*)(_dst); \
REG_DMA[ch].cnt= (count) | (mode); \
} while(0)
INLINE void dma_cpy(void *dst, const void *src, uint count, uint ch, u32 mode);
INLINE void dma_fill(void *dst, volatile u32 src, uint count, uint ch, u32 mode);
INLINE void dma3_cpy(void *dst, const void *src, uint size);
INLINE void dma3_fill(void *dst, volatile u32 src, uint size);
/*! \} */
// --------------------------------------------------------------------
// TIMER
// --------------------------------------------------------------------
INLINE void profile_start(void);
INLINE uint profile_stop(void);
// --------------------------------------------------------------------
// TONE GENERATOR
// --------------------------------------------------------------------
typedef enum
{
NOTE_C=0, NOTE_CIS, NOTE_D, NOTE_DIS,
NOTE_E, NOTE_F, NOTE_FIS, NOTE_G,
NOTE_GIS, NOTE_A, NOTE_BES, NOTE_B
} eSndNoteId;
extern const uint __snd_rates[12];
//! Gives the period of a note for the tone-gen registers.
/*! GBA sound range: 8 octaves: [-2, 5]; 8*12= 96 notes (kinda).
* \param note ID (range: [0,11>). See eSndNoteId.
* \param oct octave (range [-2,4)>).
*/
#define SND_RATE(note, oct) ( 2048-(__snd_rates[note]>>(4+(oct))) )
// --------------------------------------------------------------------
// MISC
// --------------------------------------------------------------------
/*! \defgroup grpCoreMisc Miscellaneous routines
* \ingroup grpCore
*/
/*! \{ */
#define STR(x) #x
//! Create text string from a literal
#define XSTR(x) STR(x)
//! \name Inline assembly
//\{
//! Assembly comment
#define ASM_CMT(str) asm volatile("@# " str)
//! No$gba breakpoint
#define ASM_BREAK() asm volatile("\tmov\t\tr11, r11")
//! No-op; wait a bit.
#define ASM_NOP() asm volatile("\tnop")
//\}
//! \name Sector checking
//\{
u32 octant(int x, int y);
u32 octant_rot(int x0, int y0);
//\}
//! \name Random numbers
//\{
#define QRAN_SHIFT 15
#define QRAN_MASK ((1<<QRAN_SHIFT)-1)
#define QRAN_MAX QRAN_MASK
int sqran(int seed);
INLINE int qran(void);
INLINE int qran_range(int min, int max);
//\}
/*! \} */
// --------------------------------------------------------------------
// GLOBALS
// --------------------------------------------------------------------
extern const u8 oam_sizes[3][4][2];
extern const BG_AFFINE bg_aff_default;
extern COLOR *vid_page;
extern int __qran_seed;
// --------------------------------------------------------------------
// INLINES
// --------------------------------------------------------------------
// --- Bit and bitfields -----------------------------------------------
//! Get \a len long bitfield from \a y, starting at \a shift.
/*! \param y Value containing bitfield.
\param shift Bitfield Start;
\param len Length of bitfield.
\return Bitfield between bits \a shift and \a shift + \a length.
*/
INLINE u32 bf_get(u32 y, uint shift, uint len)
{ return (y>>shift) & ( (1<<len)-1 ); }
//! Merge \a x into an \a len long bitfield from \a y, starting at \a shift.
/*! \param y Value containing bitfield.
\param x Value to merge (will be masked to fit).
\param shift Bitfield Start;
\param len Length of bitfield.
\return Result of merger: (y&~M) | (x<<s & M)
\note Does \e not write the result back into \a y (Because pure C
does't have references, that's why)
*/
INLINE u32 bf_merge(u32 y, u32 x, uint shift, uint len)
{
u32 mask= ((u32)(1<<len)-1);
return (y &~ (mask<<shift)) | (x & mask)<<shift;
}
//! Clamp \a to within the range allowed by \a len bits
INLINE u32 bf_clamp(int x, uint len)
{
u32 y=x>>len;
if(y)
x= (~y)>>(32-len);
return x;
}
//! Gives a tribool (-1, 0, or +1) depending on the state of some bits.
/*! Looks at the \a plus and \a minus bits of \a flags, and subtracts
their status to give a +1, -1 or 0 result. Useful for direction flags.
\param flags Value with bit-flags.
\param plus Bit number for positive result.
\param minus Bit number for negative result.
\return <b>+1</b> if \a plus bit is set but \a minus bit isn't<br>
<b>-1</b> if \a minus bit is set and \a plus bit isn't<br>
<b>0</b> if neither or both are set.
*/
INLINE int bit_tribool(u32 flags, uint plus, uint minus)
{ return ((flags>>plus)&1) - ((flags>>minus)&1); }
//! Rotate bits right. Yes, this does lead to a ror instruction.
INLINE u32 ROR(u32 x, uint ror)
{ return (x<<(32-ror)) | (x>>ror); }
// --- Data -----------------------------------------------------------
INLINE uint align(uint x, uint width)
{ return (x+width-1)/width*width; }
//! VRAM-safe memset, byte version. Size in bytes.
INLINE void *toncset(void *dst, u8 src, uint count)
{ return __toncset(dst, quad8(src), count); }
//! VRAM-safe memset, halfword version. Size in hwords.
INLINE void *toncset16(void *dst, u16 src, uint count)
{ return __toncset(dst, src|src<<16, count*2); }
//! VRAM-safe memset, word version. Size in words.
INLINE void *toncset32(void *dst, u32 src, uint count)
{ return __toncset(dst, src, count*4); }
//! Duplicate a byte to form a halfword: 0x12 -> 0x1212.
INLINE u16 dup8(u8 x) { return x|(x<<8); }
//! Duplicate a halfword to form a word: 0x1234 -> 0x12341234.
INLINE u32 dup16(u16 x) { return x|(x<<16); }
//! Quadruple a byte to form a word: 0x12 -> 0x12121212.
INLINE u32 quad8(u8 x) { return x*0x01010101; }
//! Octuple a nybble to form a word: 0x1 -> 0x11111111
INLINE u32 octup(u8 x) { return x*0x11111111; }
//! Pack 2 bytes into a word. Little-endian order.
INLINE u16 bytes2hword(u8 b0, u8 b1)
{ return b0 | b1<<8; }
//! Pack 4 bytes into a word. Little-endian order.
INLINE u32 bytes2word(u8 b0, u8 b1, u8 b2, u8 b3)
{ return b0 | b1<<8 | b2<<16 | b3<<24; }
INLINE u32 hword2word(u16 h0, u16 h1)
{ return h0 | h1<<16; }
// --- DMA ------------------------------------------------------------
/*! \addtogroup grpDma */
/*! \{ */
//! Generic DMA copy routine.
/*! \param dst Destination address.
* \param src Source address.
* \param count Number of copies to perform.
* \param ch DMA channel.
* \param mode DMA transfer mode.
* \note \a count is the number of copies, not the size in bytes.
*/
INLINE void dma_cpy(void *dst, const void *src, uint count, uint ch, u32 mode)
{
REG_DMA[ch].cnt= 0;
REG_DMA[ch].src= src;
REG_DMA[ch].dst= dst;
REG_DMA[ch].cnt= mode | count;
}
//! Generic DMA fill routine.
/*! \param dst Destination address.
* \param src Source value.
* \param count Number of copies to perform.
* \param ch DMA channel.
* \param mode DMA transfer mode.
* \note \a count is the number of copies, not the size in bytes.
*/
INLINE void dma_fill(void *dst, volatile u32 src, uint count, uint ch, u32 mode)
{
REG_DMA[ch].cnt= 0;
REG_DMA[ch].src= (const void*)&src;
REG_DMA[ch].dst= dst;
REG_DMA[ch].cnt= count | mode | DMA_SRC_FIXED;
}
//! Specific DMA copier, using channel 3, word transfers.
/*! \param dst Destination address.
* \param src Source address.
* \param size Number of bytes to copy
* \note \a size is the number of bytes
*/
INLINE void dma3_cpy(void *dst, const void *src, uint size)
{ dma_cpy(dst, src, size/4, 3, DMA_CPY32); }
//! Specific DMA filler, using channel 3, word transfers.
/*! \param dst Destination address.
* \param src Source value.
* \param size Number of bytes to copy
* \note \a size is the number of bytes
*/
INLINE void dma3_fill(void *dst, volatile u32 src, uint size)
{ dma_fill(dst, src, size/4, 3, DMA_FILL32); }
/*! \} */
// --- Random ---------------------------------------------------------
//! Quick (and very dirty) pseudo-random number generator
/*! \return random in range [0,8000h>
*/
INLINE int qran(void)
{
__qran_seed= 1664525*__qran_seed+1013904223;
return (__qran_seed>>16) & QRAN_MAX;
}
//! Ranged random number
/*! \return random in range [\a min, \a max>
* \note (max-min) must be lower than 8000h
*/
INLINE int qran_range(int min, int max)
{ return (qran()*(max-min)>>QRAN_SHIFT)+min; }
// --- Timer ----------------------------------------------------------
/*! \addtogroup grpTimer */
/*! \{ */
//! Start a profiling run
/*! \note Routine uses timers 3 and 3; if you're already using these
* somewhere, chaos is going to ensue.
*/
INLINE void profile_start(void)
{
REG_TM2D= 0; REG_TM3D= 0;
REG_TM2CNT= 0; REG_TM3CNT= 0;
REG_TM3CNT= TM_ENABLE | TM_CASCADE;
REG_TM2CNT= TM_ENABLE;
}
//! Stop a profiling run and return the time since its start.
/*! \return 32bit cycle count
*/
INLINE uint profile_stop(void)
{
REG_TM2CNT= 0;
return (REG_TM3D<<16)|REG_TM2D;
}
/*! \} /addtogroup */
#endif // TONC_CORE

691
src/engine/gba/tonc_math.h Normal file
View File

@ -0,0 +1,691 @@
//
// Mathematical functions
//
//! \file tonc_math.h
//! \author J Vijn
//! \date 20060508 - 20060908
//
// === NOTES ===
#ifndef TONC_MATH
#define TONC_MATH
#include "tonc_types.h"
// --- Doxygen modules ---
/*! \defgroup grpMathBase Base math
* \brief Basic math macros and functions like MIN, MAX
* \ingroup grpMath
*/
/*! \defgroup grpMathFixed Fixed point math
* \ingroup grpMath
*/
/*! \defgroup grpMathLut Look-up tables
* \brief Tonc's internal look-up tables and related routines.
* \ingroup grpMath
*/
/*! \defgroup grpMathPoint Point functions
* \ingroup grpMath
*/
/*! \defgroup grpMathVector Vector functions
* \ingroup grpMath
*/
/*! \defgroup grpMathRect Rect functions
* \ingroup grpMath
*/
// --------------------------------------------------------------------
// GENERAL
// --------------------------------------------------------------------
/*! \addtogroup grpMathBase */
/*! \{ */
// Also available as inline functions
//! \name core math macros
//\{
#ifndef ABS
//! Get the absolute value of \a x
#define ABS(x) ( (x)>=0 ? (x) : -(x) )
#endif // ABS
#ifndef SGN
//! Get the sign of \a x.
#define SGN(x) ( (x)>=0 ? 1 : -1 )
#define SGN2 SGN
#endif // SGN
#ifndef SGN3
//! Tri-state sign: -1 for negative, 0 for 0, +1 for positive.
#define SGN3(x) ( (x)>0 ? 1 : ( (x)<0 ? -1 : 0) )
#endif // SGN3
#ifndef MAX
//! Get the maximum of \a a and \a b
#define MAX(a, b) ( ((a) > (b)) ? (a) : (b) )
//! Get the minimum of \a a and \a b
#define MIN(a, b) ( ((a) < (b)) ? (a) : (b) )
#endif // MAX
#ifndef SWAP
//! In-place swap.
#define SWAP2(a, b) do { a=(a)-(b); b=(a)+(b); a=(b)-(a); } while(0)
#define SWAP SWAP2
//Alternative:
//#define SWAP2(a, b) ( (b) ^= ((a) ^= ((b) ^= (a))) )
//! Swaps \a a and \a b, using \a tmp as a temporary
#define SWAP3(a, b, tmp) do { (tmp)=(a); (a)=(b); (b)=(tmp); } while(0)
#endif // SWAP
INLINE int sgn(int x);
INLINE int sgn3(int x);
INLINE int max(int a, int b);
INLINE int min(int a, int b);
//\}
//! \name Boundary response macros
//\{
//! Range check
#define IN_RANGE(x, min, max) ( ((x)>=(min)) && ((x)<(max)) )
//! Truncates \a x to stay in range [\a min, \a max>
/*! \return Truncated value of \a x.
* \note \a max is exclusive!
*/
#define CLAMP(x, min, max) \
( (x)>=(max) ? ((max)-1) : ( ((x)<(min)) ? (min) : (x) ) )
//! Reflects \a x at boundaries \a min and \a max
/*! If \a x is outside the range [\a min, \a max>,
* it'll be placed inside again with the same distance
* to the 'wall', but on the other side. Example for lower
* border: y = \a min - (\a x- \a min) = 2*\a min + \a x.
* \return Reflected value of \a x.
* \note \a max is exclusive!
*/
#define REFLECT(x, min, max) \
( (x)>=(max) ? 2*((max)-1)-(x) : ( ((x)<(min)) ? 2*(min)-(x) : (x) ) )
//! Wraps \a x to stay in range [\a min, \a max>
#define WRAP(x, min, max) \
( (x)>=(max) ? (x)+(min)-(max) : ( ((x)<(min)) ? (x)+(max)-(min) : (x) ) )
INLINE BOOL in_range(int x, int min, int max);
INLINE int clamp(int x, int min, int max);
INLINE int reflect(int x, int min, int max);
INLINE int wrap(int x, int min, int max);
//\}
/* \} */
// --------------------------------------------------------------------
// FIXED POINT
// --------------------------------------------------------------------
/*! \addtogroup grpMathFixed */
/*! \{ */
#define FIX_SHIFT 8
#define FIX_SCALE ( 1<<FIX_SHIFT )
#define FIX_MASK ( FIX_SCALE-1 )
#define FIX_SCALEF ( (float)FIX_SCALE )
#define FIX_SCALEF_INV ( 1.0/FIX_SCALEF )
#define FIX_ONE FIX_SCALE
//! Get the fixed point reciprocal of \a a, in \a fp fractional bits.
/*!
* \param a Value to take the reciprocal of.
* \param fp Number of fixed point bits
* \note The routine does do a division, but the compiler will
* optimize it to a single constant ... \e if both \a a and \a fp
* are constants!
* \sa #FX_RECIMUL
*/
#define FX_RECIPROCAL(a, fp) ( ((1<<(fp))+(a)-1)/(a) )
//! Perform the division \a x/ \a a by reciprocal multiplication
/*! Division is slow, but you can approximate division by a constant
* by multiplying with its reciprocal: x/a vs x*(1/a). This routine
* gives the reciprocal of \a a as a fixed point number with \a fp
* fractional bits.
* \param a Value to take the reciprocal of.
* \param fp Number of fixed point bits
* \note The routine does do a division, but the compiler will
* optimize it to a single constant ... \e if both \a a and \a fp
* are constants!
* \note Rules for safe reciprocal division, using
* n = 2<sup>fp</sup> and m = (n+a-1)/a (i.e., rounding up)
* \li Maximum safe numerator \a x: x < n/(m*a-n)
* \li Minimum n for known \a x: n > x*(a-1)
*/
#define FX_RECIMUL(x, a, fp) ( ((x)*((1<<(fp))+(a)-1)/(a))>>(fp) )
INLINE FIXED int2fx(int d);
INLINE FIXED float2fx(float f);
INLINE u32 fx2uint(FIXED fx);
INLINE u32 fx2ufrac(FIXED fx);
INLINE int fx2int(FIXED fx);
INLINE float fx2float(FIXED fx);
INLINE FIXED fxadd(FIXED fa, FIXED fb);
INLINE FIXED fxsub(FIXED fa, FIXED fb);
INLINE FIXED fxmul(FIXED fa, FIXED fb);
INLINE FIXED fxdiv(FIXED fa, FIXED fb);
INLINE FIXED fxmul64(FIXED fa, FIXED fb);
INLINE FIXED fxdiv64(FIXED fa, FIXED fb);
/*! \} */
// === LUT ============================================================
/*! \addtogroup grpMathLut */
/*! \{ */
#define SIN_LUT_SIZE 514 // 512 for main lut, 2 extra for lerp
#define DIV_LUT_SIZE 257 // 256 for main lut, 1 extra for lerp
extern s32 div_lut[257]; // .16f
extern s16 sin_lut[514]; // .12f
INLINE s32 lu_sin(uint theta);
INLINE s32 lu_cos(uint theta);
INLINE uint lu_div(uint x);
INLINE int lu_lerp32(const s32 lut[], uint x, const uint shift);
INLINE int lu_lerp16(const s16 lut[], uint x, const uint shift);
/*! \} */
// === POINT ==========================================================
struct RECT;
//! \addtogroup grpMathPoint
//! \{
//! 2D Point struct
typedef struct POINT { int x, y; } POINT, POINT32;
// --- Point functions ---
INLINE POINT *pt_set(POINT *pd, int x, int y);
INLINE POINT *pt_add(POINT *pd, const POINT *pa, const POINT *pb);
INLINE POINT *pt_sub(POINT *pd, const POINT *pa, const POINT *pb);
INLINE POINT *pt_scale(POINT *pd, const POINT *pa, int c);
INLINE POINT *pt_add_eq(POINT *pd, const POINT *pb);
INLINE POINT *pt_sub_eq(POINT *pd, const POINT *pb);
INLINE POINT *pt_scale_eq(POINT *pd, int c);
INLINE int pt_cross(const POINT *pa, const POINT *pb);
INLINE int pt_dot(const POINT *pa, const POINT *pb);
int pt_in_rect(const POINT *pt, const struct RECT *rc);
//! \}
// === RECT ===========================================================
/*! \addtogroup grpMathRect */
/*! \{ */
//! Rectangle struct
typedef struct RECT
{
int left, top;
int right, bottom;
} RECT, RECT32;
INLINE RECT *rc_set(RECT *rc, int l, int t, int r, int b);
INLINE RECT *rc_set2(RECT *rc, int x, int y, int w, int h);
INLINE int rc_width(const RECT *rc);
INLINE int rc_height(const RECT *rc);
INLINE RECT *rc_set_pos(RECT *rc, int x, int y);
INLINE RECT *rc_set_size(RECT *rc, int w, int h);
INLINE RECT *rc_move(RECT *rc, int dx, int dy);
INLINE RECT *rc_inflate(RECT *rc, int dw, int dh);
INLINE RECT *rc_inflate2(RECT *rc, const RECT *dr);
RECT *rc_normalize(RECT *rc);
/*! \} */
// === VECTOR =========================================================
/*! \addtogroup grpMathVector */
/*! \{ */
//! Vector struct
typedef struct VECTOR { FIXED x, y, z; } VECTOR;
INLINE VECTOR *vec_set(VECTOR *vd, FIXED x, FIXED y, FIXED z);
INLINE VECTOR *vec_add(VECTOR *vd, const VECTOR *va, const VECTOR *vb);
INLINE VECTOR *vec_sub(VECTOR *vd, const VECTOR *va, const VECTOR *vb);
INLINE VECTOR *vec_mul(VECTOR *vd, const VECTOR *va, const VECTOR *vb);
INLINE VECTOR *vec_scale(VECTOR *vd, const VECTOR *va, FIXED c);
INLINE FIXED vec_dot(const VECTOR *va, const VECTOR *vb);
INLINE VECTOR *vec_add_eq(VECTOR *vd, const VECTOR *vb);
INLINE VECTOR *vec_sub_eq(VECTOR *vd, const VECTOR *vb);
INLINE VECTOR *vec_mul_eq(VECTOR *vd, const VECTOR *vb);
INLINE VECTOR *vec_scale_eq(VECTOR *vd, FIXED c);
VECTOR *vec_cross(VECTOR *vd, const VECTOR *va, const VECTOR *vb);
/*! \} */
// === INLINE =========================================================
// --- General --------------------------------------------------------
//! Get the sign of \a x.
INLINE int sgn(int x)
{ return (x>=0) ? +1 : -1; }
//! Tri-state sign of \a x: -1 for negative, 0 for 0, +1 for positive.
INLINE int sgn3(int x)
{ return (x>>31) - (-x>>31); }
//! Get the maximum of \a a and \a b
INLINE int max(int a, int b)
{ return (a > b) ? (a) : (b); }
//! Get the minimum of \a a and \a b
INLINE int min(int a, int b)
{ return (a < b) ? (a) : (b); }
//! Range check
INLINE BOOL in_range(int x, int min, int max)
{ return (u32)(x-min) < (u32)(max-min); }
//! Truncates \a x to stay in range [\a min, \a max>
/*! \return Truncated value of \a x.
* \note \a max is exclusive!
*/
INLINE int clamp(int x, int min, int max)
{ return (x>=max) ? (max-1) : ( (x<min) ? min : x ); }
//! Reflects \a x at boundaries \a min and \a max
/*! If \a x is outside the range [\a min, \a max>,
* it'll be placed inside again with the same distance
* to the 'wall', but on the other side. Example for lower
* border: y = \a min - (\a x- \a min) = 2*\a min + \a x.
* \return Reflected value of \a x.
* \note \a max is exclusive!
*/
INLINE int reflect(int x, int min, int max)
{ return (x>=max) ? (2*(max-1)-x) : ( (x<min) ? (2*min-x) : x ); }
//! Wraps \a x to stay in range [\a min, \a max>
INLINE int wrap(int x, int min, int max)
{ return (x>=max) ? (x+min-max) : ( (x<min) ? (x+max-min) : x ); }
// --- Fixed point ----------------------------------------------------
//! Convert an integer to fixed-point
INLINE FIXED int2fx(int d)
{ return d<<FIX_SHIFT; }
//! Convert a float to fixed-point
INLINE FIXED float2fx(float f)
{ return (FIXED)(f*FIX_SCALEF); }
//! Convert a FIXED point value to an unsigned integer (orly?).
INLINE u32 fx2uint(FIXED fx)
{ return fx>>FIX_SHIFT; }
//! Get the unsigned fractional part of a fixed point value (orly?).
INLINE u32 fx2ufrac(FIXED fx)
{ return fx&FIX_MASK; }
//! Convert a FIXED point value to an signed integer.
INLINE int fx2int(FIXED fx)
{ return fx/FIX_SCALE; }
//! Convert a fixed point value to floating point.
INLINE float fx2float(FIXED fx)
{ return fx/FIX_SCALEF; }
//! Add two fixed point values
INLINE FIXED fxadd(FIXED fa, FIXED fb)
{ return fa + fb; }
//! Subtract two fixed point values
INLINE FIXED fxsub(FIXED fa, FIXED fb)
{ return fa - fb; }
//! Multiply two fixed point values
INLINE FIXED fxmul(FIXED fa, FIXED fb)
{ return (fa*fb)>>FIX_SHIFT; }
//! Divide two fixed point values.
INLINE FIXED fxdiv(FIXED fa, FIXED fb)
{ return ((fa)*FIX_SCALE)/(fb); }
//! Multiply two fixed point values using 64bit math.
INLINE FIXED fxmul64(FIXED fa, FIXED fb)
{ return (((s64)fa)*fb)>>FIX_SHIFT; }
//! Divide two fixed point values using 64bit math.
INLINE FIXED fxdiv64(FIXED fa, FIXED fb)
{ return ( ((s64)fa)<<FIX_SHIFT)/(fb); }
// --- LUT ------------------------------------------------------------
//! Look-up a sine value (2&#960; = 0x10000)
/*! \param theta Angle in [0,FFFFh] range
* \return .12f sine value
*/
INLINE s32 lu_sin(uint theta)
{ return sin_lut[(theta>>7)&0x1FF]; }
//! Look-up a cosine value (2&#960; = 0x10000)
/*! \param theta Angle in [0,FFFFh] range
* \return .12f cosine value
*/
INLINE s32 lu_cos(uint theta)
{ return sin_lut[((theta>>7)+128)&0x1FF]; }
//! Look-up a division value between 0 and 255
/*! \param x reciprocal to look up.
* \return 1/x (.16f)
*/
INLINE uint lu_div(uint x)
{ return div_lut[x]; }
//! Linear interpolator for 32bit LUTs.
/*! A lut is essentially the discrete form of a function, f(<i>x</i>).
* You can get values for non-integer \e x via (linear)
* interpolation between f(x) and f(x+1).
* \param lut The LUT to interpolate from.
* \param x Fixed point number to interpolate at.
* \param shift Number of fixed-point bits of \a x.
*/
INLINE int lu_lerp32(const s32 lut[], uint x, const uint shift)
{
int xa, ya, yb;
xa=x>>shift;
ya= lut[xa]; yb= lut[xa+1];
return ya + ( (yb-ya)*(x-(xa<<shift))>>shift );
}
//! As lu_lerp32, but for 16bit LUTs.
INLINE int lu_lerp16(const s16 lut[], uint x, const uint shift)
{
int xa, ya, yb;
xa=x>>shift;
ya= lut[xa]; yb= lut[xa+1];
return ya + ( (yb-ya)*(x-(xa<<shift))>>shift );
}
// --- Point ----------------------------------------------------------
//! Initialize \a pd to (\a x, \a y)
INLINE POINT *pt_set(POINT *pd, int x, int y)
{
pd->x= x; pd->y= y;
return pd;
}
//! Point addition: \a pd = \a pa + \a pb
INLINE POINT *pt_add(POINT *pd, const POINT *pa, const POINT *pb)
{
pd->x= pa->x + pb->x;
pd->y= pa->x + pb->y;
return pd;
}
//! Point subtraction: \a pd = \a pa - \a pb
INLINE POINT *pt_sub(POINT *pd, const POINT *pa, const POINT *pb)
{
pd->x= pa->x - pb->x;
pd->y= pa->x - pb->y;
return pd;
}
//! Point scale: \a pd = \a c * \a pa
INLINE POINT *pt_scale(POINT *pd, const POINT *pa, int c)
{
pd->x= pa->x*c;
pd->y= pa->y*c;
return pd;
}
//! Point increment: \a pd += \a pb
INLINE POINT *pt_add_eq(POINT *pd, const POINT *pb)
{
pd->x += pb->y;
pd->y += pb->y;
return pd;
}
//! Point decrement: \a pd -= \a pb
INLINE POINT *pt_sub_eq(POINT *pd, const POINT *pb)
{
pd->x -= pb->y;
pd->y -= pb->y;
return pd;
}
//! Point scale: \a pd *= \a c
INLINE POINT *pt_scale_eq(POINT *pd, int c)
{
pd->x *= c;
pd->y *= c;
return pd;
}
//! Point 'cross'-product: \a pa \htmlonly &times; \endhtmlonly \a pb
/*! Actually, there's no such thing as a 2D cross-product, but you could
* extend it to 3D and get the value of its <i>z</i>-component,
* which can be used for a test for parallelism.
*/
INLINE int pt_cross(const POINT *pa, const POINT *pb)
{ return pa->x * pb->y - pa->y * pb->x; }
//! Point 'dot'-product:\a pa \htmlonly &middot; \endhtmlonly \a pb
INLINE int pt_dot(const POINT *pa, const POINT *pb)
{ return pa->x * pb->x + pa->y * pb->y; }
// --- Rect -----------------------------------------------------------
//! Initialize a rectangle.
/*! \param l Left side.
* \param t Top side.
* \param r Right side.
* \param b Bottom side.
*/
INLINE RECT *rc_set(RECT *rc, int l, int t, int r, int b)
{
rc->left= l; rc->top= t; rc->right= r; rc->bottom= b;
return rc;
}
//! Initialize a rectangle, with sizes inside of max boundaries.
/*! \param x Left side.
* \param y Top side.
* \param w Width.
* \param h Height.
*/
INLINE RECT *rc_set2(RECT *rc, int x, int y, int w, int h)
{
rc->left= x; rc->top= y; rc->right= x+w; rc->bottom= y+h;
return rc;
}
//! Get rectangle width.
INLINE int rc_width(const RECT *rc)
{ return rc->right - rc->left; }
//! Get rectangle height
INLINE int rc_height(const RECT *rc)
{ return rc->bottom - rc->top; }
//! Move rectangle to (\a x, \a y) position.
INLINE RECT *rc_set_pos(RECT *rc, int x, int y)
{
rc->right += x-rc->left; rc->left= x;
rc->bottom += y-rc->top; rc->top= y;
return rc;
}
//! Reside rectangle.
INLINE RECT *rc_set_size(RECT *rc, int w, int h)
{
rc->right= rc->left+w; rc->bottom= rc->top+h;
return rc;
}
//! Move rectangle by (\a dx, \a dy).
INLINE RECT *rc_move(RECT *rc, int dx, int dy)
{
rc->left += dx; rc->top += dy;
rc->right += dx; rc->bottom += dy;
return rc;
}
//! Increase size by \a dw horizontally and \a dh vertically.
INLINE RECT *rc_inflate(RECT *rc, int dw, int dh)
{
rc->left -= dw; rc->top -= dh;
rc->right += dw; rc->bottom += dh;
return rc;
}
//! Increase sizes on all sides by values of rectangle \a dr.
INLINE RECT *rc_inflate2(RECT *rc, const RECT *dr)
{
rc->left += dr->left; rc->top += dr->top;
rc->right += dr->right; rc->bottom += dr->bottom;
return rc;
}
// --- Vector ---------------------------------------------------------
//! Initialize a vector
INLINE VECTOR *vec_set(VECTOR *vd, FIXED x, FIXED y, FIXED z)
{
vd->x= x; vd->y= y; vd->z= z;
return vd;
}
//! Add vectors: \b d = \b a + \b b;
INLINE VECTOR *vec_add(VECTOR *vd, const VECTOR *va, const VECTOR *vb)
{
vd->x= va->x + vb->x;
vd->y= va->y + vb->y;
vd->z= va->z + vb->z;
return vd;
}
//! Subtract vectors: \b d = \b a - \b b;
INLINE VECTOR *vec_sub(VECTOR *vd, const VECTOR *va, const VECTOR *vb)
{
vd->x= va->x - vb->x;
vd->y= va->y - vb->y;
vd->z= va->z - vb->z;
return vd;
}
//! Multiply vectors elements: \b d = \b S(ax, ay, az) <20>\b b
INLINE VECTOR *vec_mul(VECTOR *vd, const VECTOR *va, const VECTOR *vb)
{
vd->x= fxmul(va->x, vb->x);
vd->y= fxmul(va->y, vb->y);
vd->z= fxmul(va->z, vb->z);
return vd;
}
//! Scale vector: \b d = c*\b a
INLINE VECTOR *vec_scale(VECTOR *vd, const VECTOR *va, FIXED c)
{
vd->x= fxmul(va->x, c);
vd->y= fxmul(va->y, c);
vd->z= fxmul(va->z, c);
return vd;
}
//! Dot-product: d = \b a <20>\b b
INLINE FIXED vec_dot(const VECTOR *va, const VECTOR *vb)
{
FIXED dot;
dot = fxmul(va->x, vb->x);
dot += fxmul(va->y, vb->y);
dot += fxmul(va->z, vb->z);
return dot;
}
//! Increment vector: \b d += \b b;
INLINE VECTOR *vec_add_eq(VECTOR *vd, const VECTOR *vb)
{ vd->x += vb->x; vd->y += vb->y; vd->z += vb->z; return vd; }
//! Decrease vector: \b d -= \b b;
INLINE VECTOR *vec_sub_eq(VECTOR *vd, const VECTOR *vb)
{ vd->x -= vb->x; vd->y -= vb->y; vd->z -= vb->z; return vd; }
//! Multiply vectors elements: \b d = \b S(dx, dy, dz) <20>\b b
INLINE VECTOR *vec_mul_eq(VECTOR *vd, const VECTOR *vb)
{
vd->x= fxmul(vd->x, vb->x);
vd->y= fxmul(vd->y, vb->y);
vd->z= fxmul(vd->z, vb->z);
return vd;
}
//! Scale vector: \b d = c*\b d
INLINE VECTOR *vec_scale_eq(VECTOR *vd, FIXED c)
{
vd->x= fxmul(vd->x, c);
vd->y= fxmul(vd->y, c);
vd->z= fxmul(vd->z, c);
return vd;
}
#endif // TONC_MATH

View File

@ -0,0 +1,962 @@
//
// Memory map defines. All of them
//
//! \file tonc_memdef.h
//! \author J Vijn
//! \date 20060508 - 20080521
//
/* === NOTES ===
* 20080521 : comms items taken from libgba
*/
#ifndef TONC_MEMDEF
#define TONC_MEMDEF
/*! \defgroup grpMemBits Memory map bit(fields)
\ingroup grpMemmap
\brief List of all bit(field) definitions of memory mapped items.
*/
// --- Prefixes ---
// REG_DISPCNT : DCNT
// REG_DISPSTAT : DSTAT
// REG_BGxCNT : BG
// REG_WIN_x : WIN
// REG_MOSAIC : MOS
// REG_BLDCNT : BLD
// REG_SND1SWEEP : SSW
// REG_SNDxCNT, : SSQR
// REG_SNDxFREQ, : SFREQ
// REG_SNDDMGCNT : SDMG
// REG_SNDDSCNT : SDS
// REG_SNDSTAT : SSTAT
// REG_DMAxCNT : DMA
// REG_TMxCNT : TM
// REG_SIOCNT : SIO(N/M/U)
// REG_RCNT : R / GPIO
// REG_KEYINPUT : KEY
// REG_KEYCNT : KCNT
// REG_IE, REG_IF : IRQ
// REG_WSCNT : WS
// Regular SE : SE
// OAM attr 0 : ATTR0
// OAM attr 1 : ATTR1
// OAM attr 2 : ATTR2
// --- REG_DISPCNT -----------------------------------------------------
/*! \defgroup grpVideoDCNT Display Control Flags
\ingroup grpMemBits
\brief Bits for REG_DISPCNT
*/
/*! \{ */
#define DCNT_MODE0 0 //!< Mode 0; bg 0-4: reg
#define DCNT_MODE1 0x0001 //!< Mode 1; bg 0-1: reg; bg 2: affine
#define DCNT_MODE2 0x0002 //!< Mode 2; bg 2-3: affine
#define DCNT_MODE3 0x0003 //!< Mode 3; bg2: 240x160\@16 bitmap
#define DCNT_MODE4 0x0004 //!< Mode 4; bg2: 240x160\@8 bitmap
#define DCNT_MODE5 0x0005 //!< Mode 5; bg2: 160x128\@16 bitmap
#define DCNT_GB 0x0008 //!< (R) GBC indicator
#define DCNT_PAGE 0x0010 //!< Page indicator
#define DCNT_OAM_HBL 0x0020 //!< Allow OAM updates in HBlank
#define DCNT_OBJ_2D 0 //!< OBJ-VRAM as matrix
#define DCNT_OBJ_1D 0x0040 //!< OBJ-VRAM as array
#define DCNT_BLANK 0x0080 //!< Force screen blank
#define DCNT_BG0 0x0100 //!< Enable bg 0
#define DCNT_BG1 0x0200 //!< Enable bg 1
#define DCNT_BG2 0x0400 //!< Enable bg 2
#define DCNT_BG3 0x0800 //!< Enable bg 3
#define DCNT_OBJ 0x1000 //!< Enable objects
#define DCNT_WIN0 0x2000 //!< Enable window 0
#define DCNT_WIN1 0x4000 //!< Enable window 1
#define DCNT_WINOBJ 0x8000 //!< Enable object window
#define DCNT_MODE_MASK 0x0007
#define DCNT_MODE_SHIFT 0
#define DCNT_MODE(n) ((n)<<DCNT_MODE_SHIFT)
#define DCNT_LAYER_MASK 0x1F00
#define DCNT_LAYER_SHIFT 8
#define DCNT_LAYER(n) ((n)<<DCNT_LAYER_SHIFT)
#define DCNT_WIN_MASK 0xE000
#define DCNT_WIN_SHIFT 13
#define DCNT_WIN(n) ((n)<<DCNT_WIN_SHIFT)
#define DCNT_BUILD(mode, layer, win, obj1d, objhbl) \
( \
(((win)&7)<<13) | (((layer)&31)<<8) | (((obj1d)&1)<<6) \
| (((objhbl)&1)<<5) | ((mode)&7) \
)
/*! \} /defgroup */
// --- REG_DISPSTAT ----------------------------------------------------
/*! \defgroup grpVideoDSTAT Display Status Flags
\ingroup grpMemBits
\brief Bits for REG_DISPSTAT
*/
/*! \{ */
#define DSTAT_IN_VBL 0x0001 //!< Now in VBlank
#define DSTAT_IN_HBL 0x0002 //!< Now in HBlank
#define DSTAT_IN_VCT 0x0004 //!< Now in set VCount
#define DSTAT_VBL_IRQ 0x0008 //!< Enable VBlank irq
#define DSTAT_HBL_IRQ 0x0010 //!< Enable HBlank irq
#define DSTAT_VCT_IRQ 0x0020 //!< Enable VCount irq
#define DSTAT_VCT_MASK 0xFF00
#define DSTAT_VCT_SHIFT 8
#define DSTAT_VCT(n) ((n)<<DSTAT_VCT_SHIFT)
/*! \} /defgroup */
// --- REG_BGxCNT ------------------------------------------------------
/*! \defgroup grpVideoBGCNT Background Control Flags
\ingroup grpMemBits
\brief Bits for REG_BGxCNT
*/
/*! \{ */
#define BG_MOSAIC 0x0040 //!< Enable Mosaic
#define BG_4BPP 0 //!< 4bpp (16 color) bg (no effect on affine bg)
#define BG_8BPP 0x0080 //!< 8bpp (256 color) bg (no effect on affine bg)
#define BG_WRAP 0x2000 //!< Wrap around edges of affine bgs
#define BG_SIZE0 0
#define BG_SIZE1 0x4000
#define BG_SIZE2 0x8000
#define BG_SIZE3 0xC000
#define BG_REG_32x32 0 //!< reg bg, 32x32 (256x256 px)
#define BG_REG_64x32 0x4000 //!< reg bg, 64x32 (512x256 px)
#define BG_REG_32x64 0x8000 //!< reg bg, 32x64 (256x512 px)
#define BG_REG_64x64 0xC000 //!< reg bg, 64x64 (512x512 px)
#define BG_AFF_16x16 0 //!< affine bg, 16x16 (128x128 px)
#define BG_AFF_32x32 0x4000 //!< affine bg, 32x32 (256x256 px)
#define BG_AFF_64x64 0x8000 //!< affine bg, 64x64 (512x512 px)
#define BG_AFF_128x128 0xC000 //!< affine bg, 128x128 (1024x1024 px)
#define BG_PRIO_MASK 0x0003
#define BG_PRIO_SHIFT 0
#define BG_PRIO(n) ((n)<<BG_PRIO_SHIFT)
#define BG_CBB_MASK 0x000C
#define BG_CBB_SHIFT 2
#define BG_CBB(n) ((n)<<BG_CBB_SHIFT)
#define BG_SBB_MASK 0x1F00
#define BG_SBB_SHIFT 8
#define BG_SBB(n) ((n)<<BG_SBB_SHIFT)
#define BG_SIZE_MASK 0xC000
#define BG_SIZE_SHIFT 14
#define BG_SIZE(n) ((n)<<BG_SIZE_SHIFT)
#define BG_BUILD(cbb, sbb, size, bpp, prio, mos, wrap) \
( \
((size)<<14) | (((wrap)&1)<<13) | (((sbb)&31)<<8 \
| (((bpp)&8)<<4) | (((mos)&1)<<6) | (((cbb)&3)<<2) \
| ((prio)&3) \
)
/*! \} */
/*! \defgroup grpVideoGfx Graphic effects
\ingroup grpMemBits
*/
/*! \{ */
// --- REG_WIN_x ------------------------------------------------------
//! \name Window macros
//\{
#define WIN_BG0 0x0001 //!< Windowed bg 0
#define WIN_BG1 0x0002 //!< Windowed bg 1
#define WIN_BG2 0x0004 //!< Windowed bg 2
#define WIN_BG3 0x0008 //!< Windowed bg 3
#define WIN_OBJ 0x0010 //!< Windowed objects
#define WIN_ALL 0x001F //!< All layers in window.
#define WIN_BLD 0x0020 //!< Windowed blending
#define WIN_LAYER_MASK 0x003F
#define WIN_LAYER_SHIFT 0
#define WIN_LAYER(n) ((n)<<WIN_LAYER_SHIFT)
#define WIN_BUILD(low, high) \
( ((high)<<8) | (low) )
#define WININ_BUILD(win0, win1) WIN_BUILD(win0, win1)
#define WINOUT_BUILD(out, obj) WIN_BUILD(out, obj)
//\}
// --- REG_MOSAIC ------------------------------------------------------
//! \name Mosaic macros
//\{
#define MOS_BH_MASK 0x000F
#define MOS_BH_SHIFT 0
#define MOS_BH(n) ((n)<<MOS_BH_SHIFT)
#define MOS_BV_MASK 0x00F0
#define MOS_BV_SHIFT 4
#define MOS_BV(n) ((n)<<MOS_BV_SHIFT)
#define MOS_OH_MASK 0x0F00
#define MOS_OH_SHIFT 8
#define MOS_OH(n) ((n)<<MOS_OH_SHIFT)
#define MOS_OV_MASK 0xF000
#define MOS_OV_SHIFT 12
#define MOS_OV(n) ((n)<<MOS_OV_SHIFT)
#define MOS_BUILD(bh, bv, oh, ov) \
( (((ov)&15)<<12) | (((oh)&15)<<8) | (((bv)&15)<<4)| ((bh)&15) )
//\}
/* \} */
// --- REG_BLDCNT ------------------------------------------------------
/*! \defgroup grpVideoBLD Blend Flags
\ingroup grpMemBits
\brief Macros for REG_BLDCNT, REG_BLDY and REG_BLDALPHA
*/
/*! \{ */
//!\ name Blend control
//\{
#define BLD_BG0 0x0001 //!< Blend bg 0
#define BLD_BG1 0x0002 //!< Blend bg 1
#define BLD_BG2 0x0004 //!< Blend bg 2
#define BLD_BG3 0x0008 //!< Blend bg 3
#define BLD_OBJ 0x0010 //!< Blend objects
#define BLD_ALL 0x001F //!< All layers (except backdrop)
#define BLD_BACKDROP 0x0020 //!< Blend backdrop
#define BLD_OFF 0 //!< Blend mode is off
#define BLD_STD 0x0040 //!< Normal alpha blend (with REG_EV)
#define BLD_WHITE 0x0080 //!< Fade to white (with REG_Y)
#define BLD_BLACK 0x00C0 //!< Fade to black (with REG_Y)
#define BLD_TOP_MASK 0x003F
#define BLD_TOP_SHIFT 0
#define BLD_TOP(n) ((n)<<BLD_TOP_SHIFT)
#define BLD_MODE_MASK 0x00C0
#define BLD_MODE_SHIFT 6
#define BLD_MODE(n) ((n)<<BLD_MODE_SHIFT)
#define BLD_BOT_MASK 0x3F00
#define BLD_BOT_SHIFT 8
#define BLD_BOT(n) ((n)<<BLD_BOT_SHIFT)
#define BLD_BUILD(top, bot, mode) \
( (((bot)&63)<<8) | (((mode)&3)<<6) | ((top)&63) )
//\}
// --- REG_BLDALPHA ---
//! \name Blend weights
#define BLD_EVA_MASK 0x001F
#define BLD_EVA_SHIFT 0
#define BLD_EVA(n) ((n)<<BLD_EVA_SHIFT)
#define BLD_EVB_MASK 0x1F00
#define BLD_EVB_SHIFT 8
#define BLD_EVB(n) ((n)<<BLD_EVB_SHIFT)
#define BLDA_BUILD(eva, evb) \
( ((eva)&31) | (((evb)&31)<<8) )
//\}
// --- REG_BLDY ---
//! \name Fade levels
#define BLDY_MASK 0x001F
#define BLDY_SHIFT 0
#define BLDY(n) ((n)<<BLD_EY_SHIFT)
#define BLDY_BUILD(ey) \
( (ey)&31 )
//\}
/*! \} */
// --- REG_SND1SWEEP ---------------------------------------------------
/*! \defgroup grpAudioSSW Tone Generator, Sweep Flags
\ingroup grpMemBits
\brief Bits for REG_SND1SWEEP (aka REG_SOUND1CNT_L)
*/
/*! \{ */
#define SSW_INC 0 //!< Increasing sweep rate
#define SSW_DEC 0x0008 //!< Decreasing sweep rate
#define SSW_OFF 0x0008 //!< Disable sweep altogether
#define SSW_SHIFT_MASK 0x0007
#define SSW_SHIFT_SHIFT 0
#define SSW_SHIFT(n) ((n)<<SSW_SHIFT_SHIFT)
#define SSW_TIME_MASK 0x0070
#define SSW_TIME_SHIFT 4
#define SSW_TIME(n) ((n)<<SSW_TIME_SHIFT)
#define SSW_BUILD(shift, dir, time) \
( (((time)&7)<<4) | ((dir)<<3) | ((shift)&7) )
/*! \} /defgroup */
// --- REG_SND1CNT, REG_SND2CNT, REG_SND4CNT ---------------------------
/*! \defgroup grpAudioSSQR Tone Generator, Square Flags
\ingroup grpMemBits
\brief Bits for REG_SND{1,2,4}CNT
(aka REG_SOUND1CNT_H, REG_SOUND2CNT_L, REG_SOUND4CNT_L, respectively)
*/
/*! \{ */
#define SSQR_DUTY1_8 0 //!< 12.5% duty cycle (#-------)
#define SSQR_DUTY1_4 0x0040 //!< 25% duty cycle (##------)
#define SSQR_DUTY1_2 0x0080 //!< 50% duty cycle (####----)
#define SSQR_DUTY3_4 0x00C0 //!< 75% duty cycle (######--) Equivalent to 25%
#define SSQR_INC 0 //!< Increasing volume
#define SSQR_DEC 0x0800 //!< Decreasing volume
#define SSQR_LEN_MASK 0x003F
#define SSQR_LEN_SHIFT 0
#define SSQR_LEN(n) ((n)<<SSQR_LEN_SHIFT)
#define SSQR_DUTY_MASK 0x00C0
#define SSQR_DUTY_SHIFT 6
#define SSQR_DUTY(n) ((n)<<SSQR_DUTY_SHIFT)
#define SSQR_TIME_MASK 0x0700
#define SSQR_TIME_SHIFT 8
#define SSQR_TIME(n) ((n)<<SSQR_TIME_SHIFT)
#define SSQR_IVOL_MASK 0xF000
#define SSQR_IVOL_SHIFT 12
#define SSQR_IVOL(n) ((n)<<SSQR_IVOL_SHIFT)
#define SSQR_ENV_BUILD(ivol, dir, time) \
( ((ivol)<<12) | ((dir)<<11) | (((time)&7)<<8) )
#define SSQR_BUILD(_ivol, dir, step, duty, len) \
( SSQR_ENV_BUILD(ivol,dir,step) | (((duty)&3)<<6) | ((len)&63) )
/*! \} /defgroup */
// --- REG_SND1FREQ, REG_SND2FREQ, REG_SND3FREQ ------------------------
/*! \defgroup grpAudioSFREQ Tone Generator, Frequency Flags
\ingroup grpMemBits
\brief Bits for REG_SND{1-3}FREQ
(aka REG_SOUND1CNT_X, REG_SOUND2CNT_H, REG_SOUND3CNT_X)
*/
/*! \{ */
#define SFREQ_HOLD 0 //!< Continuous play
#define SFREQ_TIMED 0x4000 //!< Timed play
#define SFREQ_RESET 0x8000 //!< Reset sound
#define SFREQ_RATE_MASK 0x07FF
#define SFREQ_RATE_SHIFT 0
#define SFREQ_RATE(n) ((n)<<SFREQ_RATE_SHIFT)
#define SFREQ_BUILD(rate, timed, reset) \
( ((rate)&0x7FF) | ((timed)<<14) | ((reset)<<15) )
/*! \} /defgroup */
// --- REG_SNDDMGCNT ---------------------------------------------------
/*! \defgroup grpAudioSDMG Tone Generator, Control Flags
\ingroup grpMemBits
\brief Bits for REG_SNDDMGCNT (aka REG_SOUNDCNT_L)
*/
/*! \{ */
#define SDMG_LSQR1 0x0100 //!< Enable channel 1 on left
#define SDMG_LSQR2 0x0200 //!< Enable channel 2 on left
#define SDMG_LWAVE 0x0400 //!< Enable channel 3 on left
#define SDMG_LNOISE 0x0800 //!< Enable channel 4 on left
#define SDMG_RSQR1 0x1000 //!< Enable channel 1 on right
#define SDMG_RSQR2 0x2000 //!< Enable channel 2 on right
#define SDMG_RWAVE 0x4000 //!< Enable channel 3 on right
#define SDMG_RNOISE 0x8000 //!< Enable channel 4 on right
#define SDMG_LVOL_MASK 0x0007
#define SDMG_LVOL_SHIFT 0
#define SDMG_LVOL(n) ((n)<<SDMG_LVOL_SHIFT)
#define SDMG_RVOL_MASK 0x0070
#define SDMG_RVOL_SHIFT 4
#define SDMG_RVOL(n) ((n)<<SDMG_RVOL_SHIFT)
// Unshifted values
#define SDMG_SQR1 0x01
#define SDMG_SQR2 0x02
#define SDMG_WAVE 0x04
#define SDMG_NOISE 0x08
#define SDMG_BUILD(_lmode, _rmode, _lvol, _rvol) \
( ((_rmode)<<12) | ((_lmode)<<8) | (((_rvol)&7)<<4) | ((_lvol)&7) )
#define SDMG_BUILD_LR(_mode, _vol) SDMG_BUILD(_mode, _mode, _vol, _vol)
/*! \} /defgroup */
// --- REG_SNDDSCNT ----------------------------------------------------
/*! \defgroup grpAudioSDS Direct Sound Flags
\ingroup grpMemBits
\brief Bits for REG_SNDDSCNT (aka REG_SOUNDCNT_H)
*/
/*! \{ */
#define SDS_DMG25 0 //!< Tone generators at 25% volume
#define SDS_DMG50 0x0001 //!< Tone generators at 50% volume
#define SDS_DMG100 0x0002 //!< Tone generators at 100% volume
#define SDS_A50 0 //!< Direct Sound A at 50% volume
#define SDS_A100 0x0004 //!< Direct Sound A at 100% volume
#define SDS_B50 0 //!< Direct Sound B at 50% volume
#define SDS_B100 0x0008 //!< Direct Sound B at 100% volume
#define SDS_AR 0x0100 //!< Enable Direct Sound A on right
#define SDS_AL 0x0200 //!< Enable Direct Sound A on left
#define SDS_ATMR0 0 //!< Direct Sound A to use timer 0
#define SDS_ATMR1 0x0400 //!< Direct Sound A to use timer 1
#define SDS_ARESET 0x0800 //!< Reset FIFO of Direct Sound A
#define SDS_BR 0x1000 //!< Enable Direct Sound B on right
#define SDS_BL 0x2000 //!< Enable Direct Sound B on left
#define SDS_BTMR0 0 //!< Direct Sound B to use timer 0
#define SDS_BTMR1 0x4000 //!< Direct Sound B to use timer 1
#define SDS_BRESET 0x8000 //!< Reset FIFO of Direct Sound B
/*! \} /defgroup */
// --- REG_SNDSTAT -----------------------------------------------------
/*! \defgroup grpAudioSSTAT Sound Status Flags
\ingroup grpMemBits
\brief Bits for REG_SNDSTAT (and REG_SOUNDCNT_X)
*/
/*! \{ */
#define SSTAT_SQR1 0x0001 //!< (R) Channel 1 status
#define SSTAT_SQR2 0x0002 //!< (R) Channel 2 status
#define SSTAT_WAVE 0x0004 //!< (R) Channel 3 status
#define SSTAT_NOISE 0x0008 //!< (R) Channel 4 status
#define SSTAT_DISABLE 0 //!< Disable sound
#define SSTAT_ENABLE 0x0080 //!< Enable sound. NOTE: enable before using any other sound regs
/*! \} /defgroup */
// --- REG_DMAxCNT -----------------------------------------------------
/*! \defgroup grpAudioDMA DMA Control Flags
\ingroup grpMemBits
\brief Bits for REG_DMAxCNT
*/
/*! \{ */
#define DMA_DST_INC 0 //!< Incrementing destination address
#define DMA_DST_DEC 0x00200000 //!< Decrementing destination
#define DMA_DST_FIXED 0x00400000 //!< Fixed destination
#define DMA_DST_RELOAD 0x00600000 //!< Increment destination, reset after full run
#define DMA_SRC_INC 0 //!< Incrementing source address
#define DMA_SRC_DEC 0x00800000 //!< Decrementing source address
#define DMA_SRC_FIXED 0x01000000 //!< Fixed source address
#define DMA_REPEAT 0x02000000 //!< Repeat transfer at next start condition
#define DMA_16 0 //!< Transfer by halfword
#define DMA_32 0x04000000 //!< Transfer by word
#define DMA_AT_NOW 0 //!< Start transfer now
#define DMA_GAMEPAK 0x08000000 //!< Gamepak DRQ
#define DMA_AT_VBLANK 0x10000000 //!< Start transfer at VBlank
#define DMA_AT_HBLANK 0x20000000 //!< Start transfer at HBlank
#define DMA_AT_SPECIAL 0x30000000 //!< Start copy at 'special' condition. Channel dependent
#define DMA_AT_FIFO 0x30000000 //!< Start at FIFO empty (DMA0/DMA1)
#define DMA_AT_REFRESH 0x30000000 //!< VRAM special; start at VCount=2 (DMA3)
#define DMA_IRQ 0x40000000 //!< Enable DMA irq
#define DMA_ENABLE 0x80000000 //!< Enable DMA
#define DMA_COUNT_MASK 0x0000FFFF
#define DMA_COUNT_SHIFT 0
#define DMA_COUNT(n) ((n)<<DMA_COUNT_SHIFT)
// \name Extra
//\{
#define DMA_NOW (DMA_ENABLE | DMA_AT_NOW)
#define DMA_16NOW (DMA_NOW | DMA_16)
#define DMA_32NOW (DMA_NOW | DMA_32)
// copies
#define DMA_CPY16 (DMA_NOW | DMA_16)
#define DMA_CPY32 (DMA_NOW | DMA_32)
// fills
#define DMA_FILL16 (DMA_NOW | DMA_SRC_FIXED | DMA_16)
#define DMA_FILL32 (DMA_NOW | DMA_SRC_FIXED | DMA_32)
#define DMA_HDMA (DMA_ENABLE | DMA_REPEAT | DMA_AT_HBLANK | DMA_DST_RELOAD)
//\}
/*! \} /defgroup */
// --- REG_TMxCNT ------------------------------------------------------
/*! \defgroup grpTimerTM Timer Control Flags
\ingroup grpMemBits
\brief Bits for REG_TMxCNT
*/
/*! \{ */
#define TM_FREQ_SYS 0 //!< System clock timer (16.7 Mhz)
#define TM_FREQ_1 0 //!< 1 cycle/tick (16.7 Mhz)
#define TM_FREQ_64 0x0001 //!< 64 cycles/tick (262 kHz)
#define TM_FREQ_256 0x0002 //!< 256 cycles/tick (66 kHz)
#define TM_FREQ_1024 0x0003 //!< 1024 cycles/tick (16 kHz)
#define TM_CASCADE 0x0004 //!< Increment when preceding timer overflows
#define TM_IRQ 0x0040 //!< Enable timer irq
#define TM_ENABLE 0x0080 //!< Enable timer
#define TM_FREQ_MASK 0x0003
#define TM_FREQ_SHIFT 0
#define TM_FREQ(n) ((n)<<TM_FREQ_SHIFT)
/*! \} /defgroup */
// --- REG_SIOCNT ----------------------------------------------------------
/*! \defgroup grpSioCnt Serial I/O Control
\ingroup grpMemBits
\brief Bits for REG_TMxCNT
*/
/*! \{ */
//! \name General SIO bits.
//\{
#define SIO_MODE_8BIT 0x0000 //!< Normal comm mode, 8-bit.
#define SIO_MODE_32BIT 0x1000 //!< Normal comm mode, 32-bit.
#define SIO_MODE_MULTI 0x2000 //!< Multi-play comm mode.
#define SIO_MODE_UART 0x3000 //!< UART comm mode.
#define SIO_SI_HIGH 0x0004
#define SIO_IRQ 0x4000 //!< Enable serial irq.
#define SIO_MODE_MASK 0x3000
#define SIO_MODE_SHIFT 12
#define SIO_MODE(n) ((n)<<SIO_MODE_SHIFT)
//\}
//! \name Normal mode bits. UNTESTED.
//\{
#define SION_CLK_EXT 0x0000 //!< Slave unit; use external clock (default).
#define SION_CLK_INT 0x0001 //!< Master unit; use internal clock.
#define SION_256KHZ 0x0000 //!< 256 kHz clockspeed (default).
#define SION_2MHZ 0x0002 //!< 2 MHz clockspeed.
#define SION_RECV_HIGH 0x0004 //!< SI high; opponent ready to receive (R).
#define SION_SEND_HIGH 0x0008 //!< SO high; ready to transfer.
#define SION_ENABLE 0x0080 //!< Start transfer/transfer enabled.
//\}
//! \name Multiplayer mode bits. UNTESTED.
//\{
#define SIOM_9600 0x0000 //!< Baud rate, 9.6 kbps.
#define SIOM_38400 0x0001 //!< Baud rate, 38.4 kbps.
#define SIOM_57600 0x0002 //!< Baud rate, 57.6 kbps.
#define SIOM_115200 0x0003 //!< Baud rate, 115.2 kbps.
#define SIOM_SI 0x0004 //!< SI port (R).
#define SIOM_SLAVE 0x0004 //!< Not the master (R).
#define SIOM_SD 0x0008 //!< SD port (R).
#define SIOM_CONNECTED 0x0008 //!< All GBAs connected (R)
#define SIOM_ERROR 0x0040 //!< Error in transfer (R).
#define SIOM_ENABLE 0x0080 //!< Start transfer/transfer enabled.
#define SIOM_BAUD_MASK 0x0003
#define SIOM_BAUD_SHIFT 0
#define SIOM_BAUD(n) ((n)<<SIOM_BAUD_SHIFT)
#define SIOM_ID_MASK 0x0030 //!< Multi-player ID mask (R)
#define SIOM_ID_SHIFT 4
#define SIOM_ID(n) ((n)<<SIOM_ID_SHIFT)
//\}
//! \name UART mode bits. UNTESTED.
//!\{
#define SIOU_9600 0x0000 //!< Baud rate, 9.6 kbps.
#define SIOU_38400 0x0001 //!< Baud rate, 38.4 kbps.
#define SIOU_57600 0x0002 //!< Baud rate, 57.6 kbps.
#define SIOU_115200 0x0003 //!< Baud rate, 115.2 kbps.
#define SIOU_CTS 0x0004 //!< CTS enable.
#define SIOU_PARITY_EVEN 0x0000 //!< Use even parity.
#define SIOU_PARITY_ODD 0x0008 //!< Use odd parity.
#define SIOU_SEND_FULL 0x0010 //!< Send data is full (R).
#define SIOU_RECV_EMPTY 0x0020 //!< Receive data is empty (R).
#define SIOU_ERROR 0x0040 //!< Error in transfer (R).
#define SIOU_7BIT 0x0000 //!< Data is 7bits long.
#define SIOU_8BIT 0x0080 //!< Data is 8bits long.
#define SIOU_SEND 0x0100 //!< Start sending data.
#define SIOU_RECV 0x0200 //!< Start receiving data.
#define SIOU_BAUD_MASK 0x0003
#define SIOU_BAUD_SHIFT 0
#define SIOU_BAUD(n) ((n)<<SIOU_BAUD_SHIFT)
//\}
/*! \} */
/*! \defgroup grpCommR Comm control.
\ingroup grpMemBits
\brief Communication mode select and general purpose I/O (REG_RCNT).
*/
/*! \{ */
//! \name Communication mode select.
//\{
#define R_MODE_NORMAL 0x0000 //!< Normal mode.
#define R_MODE_MULTI 0x0000 //!< Multiplayer mode.
#define R_MODE_UART 0x0000 //!< UART mode.
#define R_MODE_GPIO 0x8000 //!< General purpose mode.
#define R_MODE_JOYBUS 0xC000 //!< JOY mode.
#define R_MODE_MASK 0xC000
#define R_MODE_SHIFT 14
#define R_MODE(n) ((n)<<R_MODE_SHIFT)
//\}
//! \name General purpose I/O data
//\{
#define GPIO_SC 0x0001 // Data
#define GPIO_SD 0x0002
#define GPIO_SI 0x0004
#define GPIO_SO 0x0008
#define GPIO_SC_IO 0x0010 // Select I/O
#define GPIO_SD_IO 0x0020
#define GPIO_SI_IO 0x0040
#define GPIO_SO_IO 0x0080
#define GPIO_SC_INPUT 0x0000 // Input setting
#define GPIO_SD_INPUT 0x0000
#define GPIO_SI_INPUT 0x0000
#define GPIO_SO_INPUT 0x0000
#define GPIO_SC_OUTPUT 0x0010 // Output setting
#define GPIO_SD_OUTPUT 0x0020
#define GPIO_SI_OUTPUT 0x0040
#define GPIO_SO_OUTPUT 0x0080
#define GPIO_IRQ 0x0100 //! Interrupt on SI.
//\}
/*! \} */
// --- REG_KEYINPUT --------------------------------------------------------
/*! \defgroup grpInputKEY Key Flags
\ingroup grpMemBits
\brief Bits for REG_KEYINPUT and REG_KEYCNT
*/
/*! \{ */
#define KEY_A 0x0001 //!< Button A
#define KEY_B 0x0002 //!< Button B
#define KEY_SELECT 0x0004 //!< Select button
#define KEY_START 0x0008 //!< Start button
#define KEY_RIGHT 0x0010 //!< Right D-pad
#define KEY_LEFT 0x0020 //!< Left D-pad
#define KEY_UP 0x0040 //!< Up D-pad
#define KEY_DOWN 0x0080 //!< Down D-pad
#define KEY_R 0x0100 //!< Shoulder R
#define KEY_L 0x0200 //!< Shoulder L
#define KEY_ACCEPT 0x0009 //!< Accept buttons: A or start
#define KEY_CANCEL 0x0002 //!< Cancel button: B (well, it usually is)
#define KEY_RESET 0x030C //!< St+Se+L+R
#define KEY_FIRE 0x0003 //!< Fire buttons: A or B
#define KEY_SPECIAL 0x000C //!< Special buttons: Select or Start
#define KEY_DIR 0x00F0 //!< Directions: left, right, up down
#define KEY_SHOULDER 0x0300 //!< L or R
#define KEY_ANY 0x03FF //!< Here's the Any key :)
#define KEY_MASK 0x03FF
/*! \} /defgroup */
// --- REG_KEYCNT ------------------------------------------------------
/*! \defgroup grpInputKCNT Key Control Flags
\ingroup grpMemBits
\brief Bits for REG_KEYCNT
*/
/*! \{ */
#define KCNT_IRQ 0x4000 //!< Enable key irq
#define KCNT_OR 0 //!< Interrupt on any of selected keys
#define KCNT_AND 0x8000 //!< Interrupt on all of selected keys
/*! \} /defgroup */
// --- REG_IE, REG_IF, REG_IF_BIOS -------------------------------------
/*! \defgroup grpIrqIRQ Interrupt Flags
\ingroup grpMemBits
\brief Bits for REG_IE, REG_IF and REG_IFBIOS
*/
/*! \{ */
#define IRQ_VBLANK 0x0001 //!< Catch VBlank irq
#define IRQ_HBLANK 0x0002 //!< Catch HBlank irq
#define IRQ_VCOUNT 0x0004 //!< Catch VCount irq
#define IRQ_TIMER0 0x0008 //!< Catch timer 0 irq
#define IRQ_TIMER1 0x0010 //!< Catch timer 1 irq
#define IRQ_TIMER2 0x0020 //!< Catch timer 2 irq
#define IRQ_TIMER3 0x0040 //!< Catch timer 3 irq
#define IRQ_SERIAL 0x0080 //!< Catch serial comm irq
#define IRQ_DMA0 0x0100 //!< Catch DMA 0 irq
#define IRQ_DMA1 0x0200 //!< Catch DMA 1 irq
#define IRQ_DMA2 0x0400 //!< Catch DMA 2 irq
#define IRQ_DMA3 0x0800 //!< Catch DMA 3 irq
#define IRQ_KEYPAD 0x1000 //!< Catch key irq
#define IRQ_GAMEPAK 0x2000 //!< Catch cart irq
/*! \} /defgroup */
// --- REG_WSCNT -------------------------------------------------------
/*! \defgroup grpMiscWS Waitstate Control Flags
\ingroup grpMemBits
\brief Bits for REG_WAITCNT
*/
/*! \{ */
#define WS_SRAM_4 0
#define WS_SRAM_3 0x0001
#define WS_SRAM_2 0x0002
#define WS_SRAM_8 0x0003
#define WS_ROM0_N4 0
#define WS_ROM0_N3 0x0004
#define WS_ROM0_N2 0x0008
#define WS_ROM0_N8 0x000C
#define WS_ROM0_S2 0
#define WS_ROM0_S1 0x0010
#define WS_ROM1_N4 0
#define WS_ROM1_N3 0x0020
#define WS_ROM1_N2 0x0040
#define WS_ROM1_N8 0x0060
#define WS_ROM1_S4 0
#define WS_ROM1_S1 0x0080
#define WS_ROM2_N4 0
#define WS_ROM2_N3 0x0100
#define WS_ROM2_N2 0x0200
#define WS_ROM2_N8 0x0300
#define WS_ROM2_S8 0
#define WS_ROM2_S1 0x0400
#define WS_PHI_OFF 0
#define WS_PHI_4 0x0800
#define WS_PHI_2 0x1000
#define WS_PHI_1 0x1800
#define WS_PREFETCH 0x4000
#define WS_GBA 0
#define WS_CGB 0x8000
#define WS_STANDARD 0x4317
/*! \} /defgroup */
// --- Reg screen entries ----------------------------------------------
/*! \defgroup grpVideoSE Screen-entry Flags
\ingroup grpMemBits
*/
/*! \{ */
#define SE_HFLIP 0x0400 //!< Horizontal flip
#define SE_VFLIP 0x0800 //!< Vertical flip
#define SE_ID_MASK 0x03FF
#define SE_ID_SHIFT 0
#define SE_ID(n) ((n)<<SE_ID_SHIFT)
#define SE_FLIP_MASK 0x0C00
#define SE_FLIP_SHIFT 10
#define SE_FLIP(n) ((n)<<SE_FLIP_SHIFT)
#define SE_PALBANK_MASK 0xF000
#define SE_PALBANK_SHIFT 12
#define SE_PALBANK(n) ((n)<<SE_PALBANK_SHIFT)
#define SE_BUILD(id, PALBANK, hflip, vflip) \
( ((id)&0x03FF) | (((hflip)&1)<<10) | (((vflip)&1)<<11) | ((PALBANK)<<12) )
/*! \} /defgroup */
// --- OAM attribute 0 -------------------------------------------------
/*! \defgroup grpVideoAttr0 Object Attribute 0 Flags
\ingroup grpMemBits
*/
/*! \{ */
#define ATTR0_REG 0 //!< Regular object
#define ATTR0_AFF 0x0100 //!< Affine object
#define ATTR0_HIDE 0x0200 //!< Inactive object
#define ATTR0_AFF_DBL 0x0300 //!< Double-size affine object
#define ATTR0_AFF_DBL_BIT 0x0200
#define ATTR0_BLEND 0x0400 //!< Enable blend
#define ATTR0_WINDOW 0x0800 //!< Use for object window
#define ATTR0_MOSAIC 0x1000 //!< Enable mosaic
#define ATTR0_4BPP 0 //!< Use 4bpp (16 color) tiles
#define ATTR0_8BPP 0x2000 //!< Use 8bpp (256 color) tiles
#define ATTR0_SQUARE 0 //!< Square shape
#define ATTR0_WIDE 0x4000 //!< Tall shape (height &gt; width)
#define ATTR0_TALL 0x8000 //!< Wide shape (height &lt; width)
#define ATTR0_Y_MASK 0x00FF
#define ATTR0_Y_SHIFT 0
#define ATTR0_Y(n) ((n)<<ATTR0_Y_SHIFT)
#define ATTR0_MODE_MASK 0x0300
#define ATTR0_MODE_SHIFT 8
#define ATTR0_MODE(n) ((n)<<ATTR0_MODE_SHIFT)
#define ATTR0_SHAPE_MASK 0xC000
#define ATTR0_SHAPE_SHIFT 14
#define ATTR0_SHAPE(n) ((n)<<ATTR0_SHAPE_SHIFT)
#define ATTR0_BUILD(y, shape, bpp, mode, mos, bld, win) \
( \
((y)&255) | (((mode)&3)<<8) | (((bld)&1)<<10) | (((win)&1)<<11) \
| (((mos)&1)<<12) | (((bpp)&8)<<10)| (((shape)&3)<<14) \
)
/*! \} /defgroup */
// --- OAM attribute 1 -------------------------------------------------
/*! \defgroup grpVideoAttr1 Object Attribute 1 Flags
\ingroup grpMemBits
*/
/*! \{ */
#define ATTR1_HFLIP 0x1000 //!< Horizontal flip (reg obj only)
#define ATTR1_VFLIP 0x2000 //!< Vertical flip (reg obj only)
// Base sizes
#define ATTR1_SIZE_8 0
#define ATTR1_SIZE_16 0x4000
#define ATTR1_SIZE_32 0x8000
#define ATTR1_SIZE_64 0xC000
// Square sizes
#define ATTR1_SIZE_8x8 0 //!< Size flag for 8x8 px object
#define ATTR1_SIZE_16x16 0x4000 //!< Size flag for 16x16 px object
#define ATTR1_SIZE_32x32 0x8000 //!< Size flag for 32x32 px object
#define ATTR1_SIZE_64x64 0xC000 //!< Size flag for 64x64 px object
// Tall sizes
#define ATTR1_SIZE_8x16 0 //!< Size flag for 8x16 px object
#define ATTR1_SIZE_8x32 0x4000 //!< Size flag for 8x32 px object
#define ATTR1_SIZE_16x32 0x8000 //!< Size flag for 16x32 px object
#define ATTR1_SIZE_32x64 0xC000 //!< Size flag for 32x64 px object
// Wide sizes
#define ATTR1_SIZE_16x8 0 //!< Size flag for 16x8 px object
#define ATTR1_SIZE_32x8 0x4000 //!< Size flag for 32x8 px object
#define ATTR1_SIZE_32x16 0x8000 //!< Size flag for 32x16 px object
#define ATTR1_SIZE_64x32 0xC000 //!< Size flag for 64x64 px object
#define ATTR1_X_MASK 0x01FF
#define ATTR1_X_SHIFT 0
#define ATTR1_X(n) ((n)<<ATTR1_X_SHIFT)
#define ATTR1_AFF_ID_MASK 0x3E00
#define ATTR1_AFF_ID_SHIFT 9
#define ATTR1_AFF_ID(n) ((n)<<ATTR1_AFF_ID_SHIFT)
#define ATTR1_FLIP_MASK 0x3000
#define ATTR1_FLIP_SHIFT 12
#define ATTR1_FLIP(n) ((n)<<ATTR1_FLIP_SHIFT)
#define ATTR1_SIZE_MASK 0xC000
#define ATTR1_SIZE_SHIFT 14
#define ATTR1_SIZE(n) ((n)<<ATTR1_SIZE_SHIFT)
#define ATTR1_BUILDR(x, size, hflip, vflip) \
( ((x)&511) | (((hflip)&1)<<12) | (((vflip)&1)<<13) | (((size)&3)<<14) )
#define ATTR1_BUILDA(x, size, affid) \
( ((x)&511) | (((affid)&31)<<9) | (((size)&3)<<14) )
/*! \} /defgroup */
// --- OAM attribute 2 -------------------------------------------------
/*! \defgroup grpVideoAttr2 Object Attribute 2 Flags
\ingroup grpMemBits
*/
/*! \{ */
#define ATTR2_ID_MASK 0x03FF
#define ATTR2_ID_SHIFT 0
#define ATTR2_ID(n) ((n)<<ATTR2_ID_SHIFT)
#define ATTR2_PRIO_MASK 0x0C00
#define ATTR2_PRIO_SHIFT 10
#define ATTR2_PRIO(n) ((n)<<ATTR2_PRIO_SHIFT)
#define ATTR2_PALBANK_MASK 0xF000
#define ATTR2_PALBANK_SHIFT 12
#define ATTR2_PALBANK(n) ((n)<<ATTR2_PALBANK_SHIFT)
#define ATTR2_BUILD(id, pb, prio) \
( ((id)&0x3FF) | (((pb)&15)<<12) | (((prio)&3)<<10) )
/*! \} //defgroup */
#endif // TONC_MEMDEF

View File

@ -0,0 +1,583 @@
//
// GBA Memory map
//
//! \file tonc_memmap.h
//! \author J Vijn
//! \date 20060508 - 20060508
//
//
// === NOTES ===
//
// * The REG_BGxy registers for affine backgrounds
// should be _signed_ (vs16 / vs32), not unsigned (vu16 / vu32)
// * I have removed several REG_x_L, REG_x_H pairs because all they
// do is clutter up the file
// * C++ doesn't seem to like struct copies if the type specifiers
// don't match (e.g., volatile, non-volatile). Most registers
// don't really need the volatile specifier anyway, so if this
// presents a problem consider removing it.
// * I'm using defines for the memory map here, but GCC cannot optimize
// these properly and they will often appear inside a loop, potentially
// slowing it down to up 50% or so, depending on how much you do
// in the loop. Possible remedy: use a set of global pointers for the
// memory map instead of defines. It'll only be 4 or so pointers, so
// it should be ok. (PONDER: system with void pointers?)
#ifndef TONC_MEMMAP
#define TONC_MEMMAP
#ifndef __ASM__
#include "tonc_types.h"
#endif
/*! \defgroup grpReg IO Registers */
/*! \defgroup grpRegAlt IO Alternates */
// === MEMORY SECTIONS ================================================
/*! \addtogroup grpMemmap
\brief Basic memory map
*/
/*! \{ */
//! \name Main sections
//\{
#define MEM_EWRAM 0x02000000 //!< External work RAM
#define MEM_IWRAM 0x03000000 //!< Internal work RAM
#define MEM_IO 0x04000000 //!< I/O registers
#define MEM_PAL 0x05000000 //!< Palette. Note: no 8bit write !!
#define MEM_VRAM 0x06000000 //!< Video RAM. Note: no 8bit write !!
#define MEM_OAM 0x07000000 //!< Object Attribute Memory (OAM) Note: no 8bit write !!
#define MEM_ROM 0x08000000 //!< ROM. No write at all (duh)
#define MEM_SRAM 0x0E000000 //!< Static RAM. 8bit write only
//\}
//! \name Main section sizes
//\{
#define EWRAM_SIZE 0x40000
#define IWRAM_SIZE 0x08000
#define PAL_SIZE 0x00400
#define VRAM_SIZE 0x18000
#define OAM_SIZE 0x00400
#define SRAM_SIZE 0x10000
//\}
//! \name Sub section sizes
//\{
#define PAL_BG_SIZE 0x00200 //!< BG palette size
#define PAL_OBJ_SIZE 0x00200 //!< Object palette size
#define CBB_SIZE 0x04000 //!< Charblock size
#define SBB_SIZE 0x00800 //!< Screenblock size
#define VRAM_BG_SIZE 0x10000 //!< BG VRAM size
#define VRAM_OBJ_SIZE 0x08000 //!< Object VRAM size
#define M3_SIZE 0x12C00 //!< Mode 3 buffer size
#define M4_SIZE 0x09600 //!< Mode 4 buffer size
#define M5_SIZE 0x0A000 //!< Mode 5 buffer size
#define VRAM_PAGE_SIZE 0x0A000 //!< Bitmap page size
//\}
//! \name Sub sections
//\{
#define REG_BASE MEM_IO
#define MEM_PAL_BG (MEM_PAL) //!< Background palette address
#define MEM_PAL_OBJ (MEM_PAL + PAL_BG_SIZE) //!< Object palette address
#define MEM_VRAM_FRONT (MEM_VRAM) //!< Front page address
#define MEM_VRAM_BACK (MEM_VRAM + VRAM_PAGE_SIZE) //!< Back page address
#define MEM_VRAM_OBJ (MEM_VRAM + VRAM_BG_SIZE) //!< Object VRAM address
//\}
/*! \} */
// --------------------------------------------------------------------
// STRUCTURED MEMORY MAP
// --------------------------------------------------------------------
/*! \defgroup grpMemArray Memory mapped arrays
\ingroup grpMemmap
\brief These are some macros for easier access of various
memory sections. They're all arrays or matrices, using the
types that would be the most natural for that concept.
*/
/* \{ */
//! \name Palette
//\{
//! Background palette.
/*! pal_bg_mem[i] = color i ( COLOR )
*/
#define pal_bg_mem ((COLOR*)MEM_PAL)
//! Object palette.
/*! pal_obj_mem[i] = color i ( COLOR )
*/
#define pal_obj_mem ((COLOR*)MEM_PAL_OBJ)
//! Background palette matrix.
/*! pal_bg_bank[y] = bank y ( COLOR[ ] )<br>
pal_bg_bank[y][x] = color color y*16+x ( COLOR )
*/
#define pal_bg_bank ((PALBANK*)MEM_PAL)
//! Object palette matrix.
/*! pal_obj_bank[y] = bank y ( COLOR[ ] )<br>
pal_obj_bank[y][x] = color y*16+x ( COLOR )
*/
#define pal_obj_bank ((PALBANK*)MEM_PAL_OBJ)
//\} // End Palette
//! \name VRAM
//\{
//! Charblocks, 4bpp tiles.
/*! tile_mem[y] = charblock y ( TILE[ ] )<br>
tile_mem[y][x] = block y, tile x ( TILE )
*/
#define tile_mem ( (CHARBLOCK*)MEM_VRAM)
//! Charblocks, 8bpp tiles.
/*! tile_mem[y] = charblock y ( TILE[ ] )<br>
tile_mem[y][x] = block y, tile x ( TILE )
*/
#define tile8_mem ((CHARBLOCK8*)MEM_VRAM)
//! Object charblocks, 4bpp tiles.
/*! tile_mem[y] = charblock y ( TILE[ ] )<br>
tile_mem[y][x] = block y, tile x ( TILE )
*/
#define tile_mem_obj ( (CHARBLOCK*)MEM_VRAM_OBJ)
//! Object charblocks, 4bpp tiles.
/*! tile_mem[y] = charblock y ( TILE[ ] )<br>
tile_mem[y][x] = block y, tile x ( TILE )
*/
#define tile8_mem_obj ((CHARBLOCK8*)MEM_VRAM_OBJ)
//! Screenblocks as arrays
/*! se_mem[y] = screenblock y ( SCR_ENTRY[ ] )<br>
* se_mem[y][x] = screenblock y, entry x ( SCR_ENTRY )
*/
#define se_mem ((SCREENBLOCK*)MEM_VRAM)
//! Screenblock as matrices
/*! se_mat[s] = screenblock s ( SCR_ENTRY[ ][ ] )<br>
se_mat[s][y][x] = screenblock s, entry (x,y) ( SCR_ENTRY )
*/
#define se_mat ((SCREENMAT*)MEM_VRAM)
//! Main mode 3/5 frame as an array
/*! vid_mem[i] = pixel i ( COLOR )
*/
#define vid_mem ((COLOR*)MEM_VRAM)
//! Mode 3 frame as a matrix
/*! m3_mem[y][x] = pixel (x, y) ( COLOR )
*/
#define m3_mem ((M3LINE*)MEM_VRAM)
//! Mode 4 first page as a matrix
/*! m4_mem[y][x] = pixel (x, y) ( u8 )
* \note This is a byte-buffer. Not to be used for writing.
*/
#define m4_mem ((M4LINE*)MEM_VRAM)
//! Mode 5 first page as a matrix
/*! m5_mem[y][x] = pixel (x, y) ( COLOR )
*/
#define m5_mem ((M5LINE*)MEM_VRAM)
//! First page array
#define vid_mem_front ((COLOR*)MEM_VRAM)
//! Second page array
#define vid_mem_back ((COLOR*)MEM_VRAM_BACK)
//! Mode 4 second page as a matrix
/*! m4_mem[y][x] = pixel (x, y) ( u8 )
* \note This is a byte-buffer. Not to be used for writing.
*/
#define m4_mem_back ((M4LINE*)MEM_VRAM_BACK)
//! Mode 5 second page as a matrix
/*! m5_mem[y][x] = pixel (x, y) ( COLOR )
*/
#define m5_mem_back ((M5LINE*)MEM_VRAM_BACK)
//\} // End VRAM
//! \name OAM
//\{
//! Object attribute memory
/*! oam_mem[i] = object i ( OBJ_ATTR )
*/
#define oam_mem ((OBJ_ATTR*)MEM_OAM)
#define obj_mem ((OBJ_ATTR*)MEM_OAM)
//! Object affine memory
/*! obj_aff_mem[i] = object matrix i ( OBJ_AFFINE )
*/
#define obj_aff_mem ((OBJ_AFFINE*)MEM_OAM)
//\} // End OAM
//! \name ROM
//\{
//! ROM pointer
#define rom_mem ((u16*)MEM_ROM)
//\}
//! \name SRAM
//\{
//! SRAM pointer
#define sram_mem ((u8*)MEM_SRAM)
//\}
/*! \} */
// --------------------------------------------------------------------
// REGISTER LIST
// --------------------------------------------------------------------
/*! \addtogroup grpReg
\ingroup grpMemmap
*/
/*! \{ */
//! \name IWRAM 'registers'
//\{
// 0300:7ff[y] is mirrored at 03ff:fff[y], which is why this works out:
#define REG_IFBIOS *(vu16*)(REG_BASE-0x0008) //!< IRQ ack for IntrWait functions
#define REG_RESET_DST *(vu16*)(REG_BASE-0x0006) //!< Destination for after SoftReset
#define REG_ISR_MAIN *(fnptr*)(REG_BASE-0x0004) //!< IRQ handler address
//\}
//! \name Display registers
//\{
#define REG_DISPCNT *(vu32*)(REG_BASE+0x0000) //!< Display control
#define REG_DISPSTAT *(vu16*)(REG_BASE+0x0004) //!< Display status
#define REG_VCOUNT *(vu16*)(REG_BASE+0x0006) //!< Scanline count
//\}
//! \name Background control registers
//\{
#define REG_BGCNT ((vu16*)(REG_BASE+0x0008)) //!< Bg control array
#define REG_BG0CNT *(vu16*)(REG_BASE+0x0008) //!< Bg0 control
#define REG_BG1CNT *(vu16*)(REG_BASE+0x000A) //!< Bg1 control
#define REG_BG2CNT *(vu16*)(REG_BASE+0x000C) //!< Bg2 control
#define REG_BG3CNT *(vu16*)(REG_BASE+0x000E) //!< Bg3 control
//\}
//! \name Regular background scroll registers. (write only!)
//\{
#define REG_BG_OFS ((BG_POINT*)(REG_BASE+0x0010)) //!< Bg scroll array
#define REG_BG0HOFS *(vu16*)(REG_BASE+0x0010) //!< Bg0 horizontal scroll
#define REG_BG0VOFS *(vu16*)(REG_BASE+0x0012) //!< Bg0 vertical scroll
#define REG_BG1HOFS *(vu16*)(REG_BASE+0x0014) //!< Bg1 horizontal scroll
#define REG_BG1VOFS *(vu16*)(REG_BASE+0x0016) //!< Bg1 vertical scroll
#define REG_BG2HOFS *(vu16*)(REG_BASE+0x0018) //!< Bg2 horizontal scroll
#define REG_BG2VOFS *(vu16*)(REG_BASE+0x001A) //!< Bg2 vertical scroll
#define REG_BG3HOFS *(vu16*)(REG_BASE+0x001C) //!< Bg3 horizontal scroll
#define REG_BG3VOFS *(vu16*)(REG_BASE+0x001E) //!< Bg3 vertical scroll
//\}
//! \name Affine background parameters. (write only!)
//\{
#define REG_BG_AFFINE ((BG_AFFINE*)(REG_BASE+0x0000)) //!< Bg affine array
#define REG_BG2PA *(vs16*)(REG_BASE+0x0020) //!< Bg2 matrix.pa
#define REG_BG2PB *(vs16*)(REG_BASE+0x0022) //!< Bg2 matrix.pb
#define REG_BG2PC *(vs16*)(REG_BASE+0x0024) //!< Bg2 matrix.pc
#define REG_BG2PD *(vs16*)(REG_BASE+0x0026) //!< Bg2 matrix.pd
#define REG_BG2X *(vs32*)(REG_BASE+0x0028) //!< Bg2 x scroll
#define REG_BG2Y *(vs32*)(REG_BASE+0x002C) //!< Bg2 y scroll
#define REG_BG3PA *(vs16*)(REG_BASE+0x0030) //!< Bg3 matrix.pa.
#define REG_BG3PB *(vs16*)(REG_BASE+0x0032) //!< Bg3 matrix.pb
#define REG_BG3PC *(vs16*)(REG_BASE+0x0034) //!< Bg3 matrix.pc
#define REG_BG3PD *(vs16*)(REG_BASE+0x0036) //!< Bg3 matrix.pd
#define REG_BG3X *(vs32*)(REG_BASE+0x0038) //!< Bg3 x scroll
#define REG_BG3Y *(vs32*)(REG_BASE+0x003C) //!< Bg3 y scroll
//\}
//! \name Windowing registers
//\{
#define REG_WIN0H *(vu16*)(REG_BASE+0x0040) //!< win0 right, left (0xLLRR)
#define REG_WIN1H *(vu16*)(REG_BASE+0x0042) //!< win1 right, left (0xLLRR)
#define REG_WIN0V *(vu16*)(REG_BASE+0x0044) //!< win0 bottom, top (0xTTBB)
#define REG_WIN1V *(vu16*)(REG_BASE+0x0046) //!< win1 bottom, top (0xTTBB)
#define REG_WININ *(vu16*)(REG_BASE+0x0048) //!< win0, win1 control
#define REG_WINOUT *(vu16*)(REG_BASE+0x004A) //!< winOut, winObj control
//\}
//! \name Alternate Windowing registers
//\{
#define REG_WIN0R *(vu8*)(REG_BASE+0x0040) //!< Win 0 right
#define REG_WIN0L *(vu8*)(REG_BASE+0x0041) //!< Win 0 left
#define REG_WIN1R *(vu8*)(REG_BASE+0x0042) //!< Win 1 right
#define REG_WIN1L *(vu8*)(REG_BASE+0x0043) //!< Win 1 left
#define REG_WIN0B *(vu8*)(REG_BASE+0x0044) //!< Win 0 bottom
#define REG_WIN0T *(vu8*)(REG_BASE+0x0045) //!< Win 0 top
#define REG_WIN1B *(vu8*)(REG_BASE+0x0046) //!< Win 1 bottom
#define REG_WIN1T *(vu8*)(REG_BASE+0x0047) //!< Win 1 top
#define REG_WIN0CNT *(vu8*)(REG_BASE+0x0048) //!< window 0 control
#define REG_WIN1CNT *(vu8*)(REG_BASE+0x0049) //!< window 1 control
#define REG_WINOUTCNT *(vu8*)(REG_BASE+0x004A) //!< Out window control
#define REG_WINOBJCNT *(vu8*)(REG_BASE+0x004B) //!< Obj window control
//\}
//! \name Graphic effects
//\{
#define REG_MOSAIC *(vu32*)(REG_BASE+0x004C) //!< Mosaic control
#define REG_BLDCNT *(vu16*)(REG_BASE+0x0050) //!< Alpha control
#define REG_BLDALPHA *(vu16*)(REG_BASE+0x0052) //!< Fade level
#define REG_BLDY *(vu16*)(REG_BASE+0x0054) //!< Blend levels
//\}
// === SOUND REGISTERS ===
// sound regs, partially following pin8gba's nomenclature
//! \name Channel 1: Square wave with sweep
//\{
#define REG_SND1SWEEP *(vu16*)(REG_BASE+0x0060) //!< Channel 1 Sweep
#define REG_SND1CNT *(vu16*)(REG_BASE+0x0062) //!< Channel 1 Control
#define REG_SND1FREQ *(vu16*)(REG_BASE+0x0064) //!< Channel 1 frequency
//\}
//! \name Channel 2: Simple square wave
//\{
#define REG_SND2CNT *(vu16*)(REG_BASE+0x0068) //!< Channel 2 control
#define REG_SND2FREQ *(vu16*)(REG_BASE+0x006C) //!< Channel 2 frequency
//\}
//! \name Channel 3: Wave player
//\{
#define REG_SND3SEL *(vu16*)(REG_BASE+0x0070) //!< Channel 3 wave select
#define REG_SND3CNT *(vu16*)(REG_BASE+0x0072) //!< Channel 3 control
#define REG_SND3FREQ *(vu16*)(REG_BASE+0x0074) //!< Channel 3 frequency
//\}
//! \name Channel 4: Noise generator
//\{
#define REG_SND4CNT *(vu16*)(REG_BASE+0x0078) //!< Channel 4 control
#define REG_SND4FREQ *(vu16*)(REG_BASE+0x007C) //!< Channel 4 frequency
//\}
//! \name Sound control
//\{
#define REG_SNDCNT *(vu32*)(REG_BASE+0x0080) //!< Main sound control
#define REG_SNDDMGCNT *(vu16*)(REG_BASE+0x0080) //!< DMG channel control
#define REG_SNDDSCNT *(vu16*)(REG_BASE+0x0082) //!< Direct Sound control
#define REG_SNDSTAT *(vu16*)(REG_BASE+0x0084) //!< Sound status
#define REG_SNDBIAS *(vu16*)(REG_BASE+0x0088) //!< Sound bias
//\}
//! \name Sound buffers
//\{
#define REG_WAVE_RAM (vu32*)(REG_BASE+0x0090) //!< Channel 3 wave buffer
#define REG_WAVE_RAM0 *(vu32*)(REG_BASE+0x0090)
#define REG_WAVE_RAM1 *(vu32*)(REG_BASE+0x0094)
#define REG_WAVE_RAM2 *(vu32*)(REG_BASE+0x0098)
#define REG_WAVE_RAM3 *(vu32*)(REG_BASE+0x009C)
#define REG_FIFO_A *(vu32*)(REG_BASE+0x00A0) //!< DSound A FIFO
#define REG_FIFO_B *(vu32*)(REG_BASE+0x00A4) //!< DSound B FIFO
//\}
//! \name DMA registers
//\{
#define REG_DMA ((volatile DMA_REC*)(REG_BASE+0x00B0)) //!< DMA as DMA_REC array
#define REG_DMA0SAD *(vu32*)(REG_BASE+0x00B0) //!< DMA 0 Source address
#define REG_DMA0DAD *(vu32*)(REG_BASE+0x00B4) //!< DMA 0 Destination address
#define REG_DMA0CNT *(vu32*)(REG_BASE+0x00B8) //!< DMA 0 Control
#define REG_DMA1SAD *(vu32*)(REG_BASE+0x00BC) //!< DMA 1 Source address
#define REG_DMA1DAD *(vu32*)(REG_BASE+0x00C0) //!< DMA 1 Destination address
#define REG_DMA1CNT *(vu32*)(REG_BASE+0x00C4) //!< DMA 1 Control
#define REG_DMA2SAD *(vu32*)(REG_BASE+0x00C8) //!< DMA 2 Source address
#define REG_DMA2DAD *(vu32*)(REG_BASE+0x00CC) //!< DMA 2 Destination address
#define REG_DMA2CNT *(vu32*)(REG_BASE+0x00D0) //!< DMA 2 Control
#define REG_DMA3SAD *(vu32*)(REG_BASE+0x00D4) //!< DMA 3 Source address
#define REG_DMA3DAD *(vu32*)(REG_BASE+0x00D8) //!< DMA 3 Destination address
#define REG_DMA3CNT *(vu32*)(REG_BASE+0x00DC) //!< DMA 3 Control
//\}
//! \name Timer registers
//\{
#define REG_TM ((volatile TMR_REC*)(REG_BASE+0x0100)) //!< Timers as TMR_REC array
#define REG_TM0D *(vu16*)(REG_BASE+0x0100) //!< Timer 0 data
#define REG_TM0CNT *(vu16*)(REG_BASE+0x0102) //!< Timer 0 control
#define REG_TM1D *(vu16*)(REG_BASE+0x0104) //!< Timer 1 data
#define REG_TM1CNT *(vu16*)(REG_BASE+0x0106) //!< Timer 1 control
#define REG_TM2D *(vu16*)(REG_BASE+0x0108) //!< Timer 2 data
#define REG_TM2CNT *(vu16*)(REG_BASE+0x010A) //!< Timer 2 control
#define REG_TM3D *(vu16*)(REG_BASE+0x010C) //!< Timer 3 data
#define REG_TM3CNT *(vu16*)(REG_BASE+0x010E) //!< Timer 3 control
//\}
//! \name Serial communication
//{
#define REG_SIOCNT *(vu16*)(REG_BASE+0x0128) //!< Serial IO control (Normal/MP/UART)
#define REG_SIODATA ((vu32*)(REG_BASE+0x0120))
#define REG_SIODATA32 *(vu32*)(REG_BASE+0x0120) //!< Normal/UART 32bit data
#define REG_SIODATA8 *(vu16*)(REG_BASE+0x012A) //!< Normal/UART 8bit data
#define REG_SIOMULTI ((vu16*)(REG_BASE+0x0120)) //!< Multiplayer data array
#define REG_SIOMULTI0 *(vu16*)(REG_BASE+0x0120) //!< MP master data
#define REG_SIOMULTI1 *(vu16*)(REG_BASE+0x0122) //!< MP Slave 1 data
#define REG_SIOMULTI2 *(vu16*)(REG_BASE+0x0124) //!< MP Slave 2 data
#define REG_SIOMULTI3 *(vu16*)(REG_BASE+0x0126) //!< MP Slave 3 data
#define REG_SIOMLT_RECV *(vu16*)(REG_BASE+0x0120) //!< MP data receiver
#define REG_SIOMLT_SEND *(vu16*)(REG_BASE+0x012A) //!< MP data sender
//\}
//! \name Keypad registers
//\{
#define REG_KEYINPUT *(vu16*)(REG_BASE+0x0130) //!< Key status (read only??)
#define REG_KEYCNT *(vu16*)(REG_BASE+0x0132) //!< Key IRQ control
//\}
//! \name Joybus communication
//\{
#define REG_RCNT *(vu16*)(REG_BASE+0x0134) //!< SIO Mode Select/General Purpose Data
#define REG_JOYCNT *(vu16*)(REG_BASE+0x0140) //!< JOY bus control
#define REG_JOY_RECV *(vu32*)(REG_BASE+0x0150) //!< JOY bus receiever
#define REG_JOY_TRANS *(vu32*)(REG_BASE+0x0154) //!< JOY bus transmitter
#define REG_JOYSTAT *(vu16*)(REG_BASE+0x0158) //!< JOY bus status
//\}
//! \name Interrupt / System registers
//\{
#define REG_IE *(vu16*)(REG_BASE+0x0200) //!< IRQ enable
#define REG_IF *(vu16*)(REG_BASE+0x0202) //!< IRQ status/acknowledge
#define REG_WAITCNT *(vu16*)(REG_BASE+0x0204) //!< Waitstate control
#define REG_IME *(vu16*)(REG_BASE+0x0208) //!< IRQ master enable
#define REG_PAUSE *(vu16*)(REG_BASE+0x0300) //!< Pause system (?)
//\}
/*! \} */
// --------------------------------------------------------------------
// ALT REGISTERS
// --------------------------------------------------------------------
/*! \addtogroup grpRegAlt
\ingroup grpMemmap
\brief Alternate names for some of the registers
*/
/*! \{ */
#define REG_BLDMOD *(vu16*)(REG_BASE+0x0050) // alpha control
#define REG_COLEV *(vu16*)(REG_BASE+0x0052) // fade level
#define REG_COLEY *(vu16*)(REG_BASE+0x0054) // blend levels
// sound regs as in belogic and GBATek (mostly for compatability)
#define REG_SOUND1CNT *(vu32*)(REG_BASE+0x0060)
#define REG_SOUND1CNT_L *(vu16*)(REG_BASE+0x0060)
#define REG_SOUND1CNT_H *(vu16*)(REG_BASE+0x0062)
#define REG_SOUND1CNT_X *(vu16*)(REG_BASE+0x0064)
#define REG_SOUND2CNT_L *(vu16*)(REG_BASE+0x0068)
#define REG_SOUND2CNT_H *(vu16*)(REG_BASE+0x006C)
#define REG_SOUND3CNT *(vu32*)(REG_BASE+0x0070)
#define REG_SOUND3CNT_L *(vu16*)(REG_BASE+0x0070)
#define REG_SOUND3CNT_H *(vu16*)(REG_BASE+0x0072)
#define REG_SOUND3CNT_X *(vu16*)(REG_BASE+0x0074)
#define REG_SOUND4CNT_L *(vu16*)(REG_BASE+0x0078)
#define REG_SOUND4CNT_H *(vu16*)(REG_BASE+0x007C)
#define REG_SOUNDCNT *(vu32*)(REG_BASE+0x0080)
#define REG_SOUNDCNT_L *(vu16*)(REG_BASE+0x0080)
#define REG_SOUNDCNT_H *(vu16*)(REG_BASE+0x0082)
#define REG_SOUNDCNT_X *(vu16*)(REG_BASE+0x0084)
#define REG_SOUNDBIAS *(vu16*)(REG_BASE+0x0088)
#define REG_WAVE (vu32*)(REG_BASE+0x0090)
#define REG_FIFOA *(vu32*)(REG_BASE+0x00A0)
#define REG_FIFOB *(vu32*)(REG_BASE+0x00A4)
#define REG_DMA0CNT_L *(vu16*)(REG_BASE+0x00B8) // count
#define REG_DMA0CNT_H *(vu16*)(REG_BASE+0x00BA) // flags
#define REG_DMA1CNT_L *(vu16*)(REG_BASE+0x00C4)
#define REG_DMA1CNT_H *(vu16*)(REG_BASE+0x00C6)
#define REG_DMA2CNT_L *(vu16*)(REG_BASE+0x00D0)
#define REG_DMA2CNT_H *(vu16*)(REG_BASE+0x00D2)
#define REG_DMA3CNT_L *(vu16*)(REG_BASE+0x00DC)
#define REG_DMA3CNT_H *(vu16*)(REG_BASE+0x00DE)
#define REG_TM0CNT_L *(vu16*)(REG_BASE+0x0100)
#define REG_TM0CNT_H *(vu16*)(REG_BASE+0x0102)
#define REG_TM1CNT_L *(vu16*)(REG_BASE+0x0104)
#define REG_TM1CNT_H *(vu16*)(REG_BASE+0x0106)
#define REG_TM2CNT_L *(vu16*)(REG_BASE+0x0108)
#define REG_TM2CNT_H *(vu16*)(REG_BASE+0x010a)
#define REG_TM3CNT_L *(vu16*)(REG_BASE+0x010c)
#define REG_TM3CNT_H *(vu16*)(REG_BASE+0x010e)
#define REG_KEYS *(vu16*)(REG_BASE+0x0130) // Key status
#define REG_P1 *(vu16*)(REG_BASE+0x0130) // for backward combatibility
#define REG_P1CNT *(vu16*)(REG_BASE+0x0132) // ditto
#define REG_SCD0 *(vu16*)(REG_BASE+0x0120)
#define REG_SCD1 *(vu16*)(REG_BASE+0x0122)
#define REG_SCD2 *(vu16*)(REG_BASE+0x0124)
#define REG_SCD3 *(vu16*)(REG_BASE+0x0126)
#define REG_SCCNT *(vu32*)(REG_BASE+0x0128)
#define REG_SCCNT_L *(vu16*)(REG_BASE+0x0128)
#define REG_SCCNT_H *(vu16*)(REG_BASE+0x012A)
#define REG_R *(vu16*)(REG_BASE+0x0134)
#define REG_HS_CTRL *(vu16*)(REG_BASE+0x0140)
#define REG_JOYRE *(vu32*)(REG_BASE+0x0150)
#define REG_JOYRE_L *(vu16*)(REG_BASE+0x0150)
#define REG_JOYRE_H *(vu16*)(REG_BASE+0x0152)
#define REG_JOYTR *(vu32*)(REG_BASE+0x0154)
#define REG_JOYTR_L *(vu16*)(REG_BASE+0x0154)
#define REG_JOYTR_H *(vu16*)(REG_BASE+0x0156)
#define REG_JSTAT *(vu16*)(REG_BASE+0x0158)
#define REG_WSCNT *(vu16*)(REG_BASE+0x0204)
/*! \} */
#endif // TONC_MEMMAP
// EOF

226
src/engine/gba/tonc_oam.h Normal file
View File

@ -0,0 +1,226 @@
//
// Basic video functions
//
//! \file tonc_oam.h
//! \author J Vijn
//! \date 20060604 - 20060604
//
// === NOTES ===
// * Basic video-IO, color, background and object functionality
#ifndef TONC_OAM
#define TONC_OAM
#include "tonc_memmap.h"
#include "tonc_memdef.h"
#include "tonc_core.h"
#include "tonc_math.h"
// --------------------------------------------------------------------
// OBJECTS
// --------------------------------------------------------------------
//! \addtogroup grpVideoObj
/*! \{ */
#define OAM_CLEAR() memset32(oam_mem, 0, OAM_SIZE/4)
// --- Prototypes -----------------------------------------------------
// --- Full OAM ---
void oam_init(OBJ_ATTR *obj, uint count);
INLINE void oam_copy(OBJ_ATTR *dst, const OBJ_ATTR *src, uint count);
// --- Obj attr only ---
INLINE OBJ_ATTR *obj_set_attr(OBJ_ATTR *obj, u16 a0, u16 a1, u16 a2);
INLINE void obj_set_pos(OBJ_ATTR *obj, int x, int y);
INLINE void obj_hide(OBJ_ATTR *oatr);
INLINE void obj_unhide(OBJ_ATTR *obj, u16 mode);
INLINE const u8 *obj_get_size(const OBJ_ATTR *obj);
INLINE int obj_get_width(const OBJ_ATTR *obj);
INLINE int obj_get_height(const OBJ_ATTR *obj);
void obj_copy(OBJ_ATTR *dst, const OBJ_ATTR *src, uint count);
void obj_hide_multi(OBJ_ATTR *obj, u32 count);
void obj_unhide_multi(OBJ_ATTR *obj, u16 mode, uint count);
// --- Obj affine only ---
void obj_aff_copy(OBJ_AFFINE *dst, const OBJ_AFFINE *src, uint count);
INLINE void obj_aff_set(OBJ_AFFINE *oaff,
FIXED pa, FIXED pb, FIXED pc, FIXED pd);
INLINE void obj_aff_identity(OBJ_AFFINE *oaff);
INLINE void obj_aff_scale(OBJ_AFFINE *oaff, FIXED sx, FIXED sy);
INLINE void obj_aff_shearx(OBJ_AFFINE *oaff, FIXED hx);
INLINE void obj_aff_sheary(OBJ_AFFINE *oaff, FIXED hy);
void obj_aff_rotate(OBJ_AFFINE *oaff, u16 alpha);
void obj_aff_rotscale(OBJ_AFFINE *oaff, FIXED sx, FIXED sy, u16 alpha);
void obj_aff_premul(OBJ_AFFINE *dst, const OBJ_AFFINE *src);
void obj_aff_postmul(OBJ_AFFINE *dst, const OBJ_AFFINE *src);
void obj_aff_rotscale2(OBJ_AFFINE *oaff, const AFF_SRC *as);
void obj_rotscale_ex(OBJ_ATTR *obj, OBJ_AFFINE *oaff, const AFF_SRC_EX *asx);
// inverse (object -> screen) functions, could be useful
// inverses (prototypes)
INLINE void obj_aff_scale_inv(OBJ_AFFINE *oa, FIXED wx, FIXED wy);
INLINE void obj_aff_rotate_inv(OBJ_AFFINE *oa, u16 theta);
INLINE void obj_aff_shearx_inv(OBJ_AFFINE *oa, FIXED hx);
INLINE void obj_aff_sheary_inv(OBJ_AFFINE *oa, FIXED hy);
/*! \} */
// --------------------------------------------------------------------
// INLINES
// --------------------------------------------------------------------
/*! \addtogroup grpVideoObj */
/*! \{ */
//! Set the attributes of an object.
INLINE OBJ_ATTR *obj_set_attr(OBJ_ATTR *obj, u16 a0, u16 a1, u16 a2)
{
obj->attr0= a0; obj->attr1= a1; obj->attr2= a2;
return obj;
}
//! Set the position of \a obj
INLINE void obj_set_pos(OBJ_ATTR *obj, int x, int y)
{
BFN_SET(obj->attr0, y, ATTR0_Y);
BFN_SET(obj->attr1, x, ATTR1_X);
}
//! Copies \a count OAM entries from \a src to \a dst.
INLINE void oam_copy(OBJ_ATTR *dst, const OBJ_ATTR *src, uint count)
{ memcpy32(dst, src, count*2); }
//! Hide an object.
INLINE void obj_hide(OBJ_ATTR *obj)
{ BFN_SET2(obj->attr0, ATTR0_HIDE, ATTR0_MODE); }
//! Unhide an object.
/*! \param obj Object to unhide.
* \param mode Object mode to unhide to. Necessary because this affects
* the affine-ness of the object.
*/
INLINE void obj_unhide(OBJ_ATTR *obj, u16 mode)
{ BFN_SET2(obj->attr0, mode, ATTR0_MODE); }
//! Get object's sizes as a byte array
INLINE const u8 *obj_get_size(const OBJ_ATTR *obj)
{ return oam_sizes[obj->attr0>>14][obj->attr1>>14]; }
//! Get object's width
INLINE int obj_get_width(const OBJ_ATTR *obj)
{ return obj_get_size(obj)[0]; }
//! Gets object's height
INLINE int obj_get_height(const OBJ_ATTR *obj)
{ return obj_get_size(obj)[1]; }
// --- Affine only ---
//! Set the elements of an \a object affine matrix.
INLINE void obj_aff_set(OBJ_AFFINE *oaff,
FIXED pa, FIXED pb, FIXED pc, FIXED pd)
{
oaff->pa= pa; oaff->pb= pb;
oaff->pc= pc; oaff->pd= pd;
}
//! Set an object affine matrix to the identity matrix
INLINE void obj_aff_identity(OBJ_AFFINE *oaff)
{
oaff->pa= 0x0100l; oaff->pb= 0;
oaff->pc= 0; oaff->pd= 0x0100;
}
//! Set an object affine matrix for scaling.
INLINE void obj_aff_scale(OBJ_AFFINE *oaff, FIXED sx, FIXED sy)
{
oaff->pa= sx; oaff->pb= 0;
oaff->pb= 0; oaff->pd= sy;
}
INLINE void obj_aff_shearx(OBJ_AFFINE *oaff, FIXED hx)
{
oaff->pa= 0x0100; oaff->pb= hx;
oaff->pc= 0; oaff->pd= 0x0100;
}
INLINE void obj_aff_sheary(OBJ_AFFINE *oaff, FIXED hy)
{
oaff->pa= 0x0100; oaff->pb= 0;
oaff->pc= hy; oaff->pd= 0x0100;
}
// --- Inverse operations ---
INLINE void obj_aff_scale_inv(OBJ_AFFINE *oaff, FIXED wx, FIXED wy)
{ obj_aff_scale(oaff, ((1<<24)/wx)>>8, ((1<<24)/wy)>>8); }
INLINE void obj_aff_rotate_inv(OBJ_AFFINE *oaff, u16 theta)
{ obj_aff_rotate(oaff, -theta); }
INLINE void obj_aff_shearx_inv(OBJ_AFFINE *oaff, FIXED hx)
{ obj_aff_shearx(oaff, -hx); }
INLINE void obj_aff_sheary_inv(OBJ_AFFINE *oaff, FIXED hy)
{ obj_aff_sheary(oaff, -hy); }
/*! \} */
void obj_aff_copy(OBJ_AFFINE *dst, const OBJ_AFFINE *src, u32 count)
{
int ii;
for(ii=0; ii<count; ii++)
{
dst->pa= src->pa;
dst->pb= src->pb;
dst->pc= src->pc;
dst->pd= src->pd;
src++;
dst++;
}
}
//! Set obj matrix to counter-clockwise rotation.
/*!
\param oaff Object affine struct to set.
\param alpha CCW angle. full-circle is 10000h.
*/
void obj_aff_rotate(OBJ_AFFINE *oaff, u16 alpha)
{
int ss= lu_sin(alpha)>>4, cc= lu_cos(alpha)>>4;
oaff->pa= cc; oaff->pb= -ss;
oaff->pc= ss; oaff->pd= cc;
}
//! Post-multiply \a dst by \a src: D= D*S
void obj_aff_postmul(OBJ_AFFINE *dst, const OBJ_AFFINE *src)
{
FIXED tmp_a, tmp_b, tmp_c, tmp_d;
tmp_a= dst->pa; tmp_b= dst->pb;
tmp_c= dst->pc; tmp_d= dst->pd;
dst->pa= (tmp_a*src->pa + tmp_b*src->pc)>>8;
dst->pb= (tmp_a*src->pb + tmp_b*src->pd)>>8;
dst->pc= (tmp_c*src->pa + tmp_d*src->pc)>>8;
dst->pd= (tmp_c*src->pb + tmp_d*src->pd)>>8;
}
#endif // TONC_OAM

377
src/engine/gba/tonc_types.h Normal file
View File

@ -0,0 +1,377 @@
//
// Basic structs and typedefs
//
//! \file tonc_types.h
//! \author J Vijn
//! \date 20060508 - 20080111
//
// === NOTES ===
// * When doing anything, always, ALWAYS!!! check the type.
// Especially when you're combining things from different sources.
// Look around on the forum and count the number of times people
// have copied, say, from a u32 source to a u16 destination.
#ifndef TONC_TYPES
#define TONC_TYPES
/*! \defgroup grpTypes Types and attributes */
// --------------------------------------------------------------------
// GCC ATTRIBUTES
// --------------------------------------------------------------------
/*! \defgroup grpTypeAttr Type attributes
* \ingroup grpTypes
*/
/*! \{ */
// If you want your data in specific sections, add this
// to your variables or functions.
// Example:
//
// //Declaration
// IWRAM_CODE void function(int x, int y, etc);
//
// //Definition
// IWRAM_CODE void function(int x, int y, etc)
// {
// // code
// }
//! Put variable in IWRAM (default).
#define IWRAM_DATA __attribute__((section(".iwram")))
//! Put variable in EWRAM.
#define EWRAM_DATA __attribute__((section(".ewram")))
//! Put <b>non</b>-initialized variable in EWRAM.
#define EWRAM_BSS __attribute__((section(".sbss")))
//! Put function in IWRAM.
#define IWRAM_CODE __attribute__((section(".iwram"), long_call))
//! Put function in EWRAM.
#define EWRAM_CODE __attribute__((section(".ewram"), long_call))
//! Force a variable to an \a n-byte boundary
#define ALIGN(n) __attribute__((aligned(n)))
//! Force word alignment.
/*! \note In the old days, GCC aggregates were always word aligned.
In the EABI environment (devkitPro r19 and higher), they are
aligned to their widest member. While technically a good thing,
it may cause problems for struct-copies. If you have aggregates
that can multiples of 4 in size but don't have word members,
consider using this attribute to make struct-copies possible again.
*/
#define ALIGN4 __attribute__((aligned(4)))
//! Pack aggregate members
/*! By default, members in aggregates are aligned to their native
boundaries. Adding this prevents that. It will slow access though.
*/
#define PACKED __attribute__((packed))
//! Deprecated notice.
/*! Indicates that this function/type/variable should not be used anymore.
Replacements are (usually) present somewhere as well.
*/
#define DEPRECATED __attribute__((deprecated))
//! Inline function declarator
/*! `inline' inlines the function when -O > 0 when called,
but also creates a body for the function itself
`static' removes the body as well
*/
#define INLINE static inline
/* \} */
// --------------------------------------------------------------------
// TYPES
// --------------------------------------------------------------------
// === primary typedefs ===============================================
/*! \defgroup grpTypePrim Primary types
\ingroup grpTypes
*/
/*! \{ */
/*! \name Base types
Basic signed and unsigned types for 8, 16, 32 and 64-bit integers.
<ul>
<li>s# : signed #-bit integer. </li>
<li>u#/u{type} : unsigned #-bit integer.</li>
<li>e{type} : enum'ed #-bit integer.</li>
</ul>
*/
//\{
typedef unsigned char u8, byte, uchar, echar;
typedef unsigned short u16, hword, ushort, eshort;
typedef unsigned int u32, word, uint, eint;
typedef unsigned long long u64;
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef signed long long s64;
//\}
/*! \name Volatile types
* Volatile types for registers
*/
//\{
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
typedef volatile u64 vu64;
typedef volatile s8 vs8;
typedef volatile s16 vs16;
typedef volatile s32 vs32;
typedef volatile s64 vs64;
//\}
/*! \name Const types
* Const types for const function aprameters
*/
//\{
typedef const u8 cu8;
typedef const u16 cu16;
typedef const u32 cu32;
typedef const u64 cu64;
typedef const s8 cs8;
typedef const s16 cs16;
typedef const s32 cs32;
typedef const s64 cs64;
//\}
//! 8-word type for fast struct-copies
typedef struct { u32 data[8]; } BLOCK;
//! Type for consting a string as well as the pointer than points to it.
typedef const char * const CSTR;
/* \} */
// === secondary typedefs =============================================
/*! \defgroup grpTypeSec Secondary types
* \ingroup grpTypes
*/
/*! \{ */
typedef s32 FIXED; //!< Fixed point type
typedef u16 COLOR; //!< Type for colors
typedef u16 SCR_ENTRY, SE; //!< Type for screen entries
typedef u8 SCR_AFF_ENTRY, SAE; //!< Type for affine screen entries
//! 4bpp tile type, for easy indexing and copying of 4-bit tiles
typedef struct { u32 data[8]; } TILE, TILE4;
//! 8bpp tile type, for easy indexing and 8-bit tiles
typedef struct { u32 data[16]; } TILE8;
#ifndef __cplusplus
//! Boolean type
typedef enum { false, true } bool;
#endif
#ifndef BOOL
typedef u8 BOOL; // C++ bool == u8 too, that's why
#define TRUE 1
#define FALSE 0
#endif
// --- function pointer ---
typedef void (*fnptr)(void); //!< void foo() function pointer
typedef void (*fn_v_i)(int); //!< void foo(int x) function pointer
typedef int (*fn_i_i)(int); //!< int foo(int x) function pointer
//! \name affine structs
//\{
//! Simple scale-rotation source struct.
/*! This can be used with ObjAffineSet, and several of tonc's
* affine functions
*/
typedef struct AFF_SRC
{
s16 sx; //!< Horizontal zoom (8.8f)
s16 sy; //!< Vertical zoom (8.8f)
u16 alpha; //!< Counter-clockwise angle ( range [0, 0xFFFF] )
} ALIGN4 AFF_SRC, ObjAffineSource;
//! Extended scale-rotate source struct
/*! This is used to scale/rotate around an arbitrary point. See
* tonc's main text for all the details.
*/
typedef struct AFF_SRC_EX
{
s32 tex_x; //!< Texture-space anchor, x coordinate (.8f)
s32 tex_y; //!< Texture-space anchor, y coordinate (.8f)
s16 scr_x; //!< Screen-space anchor, x coordinate (.0f)
s16 scr_y; //!< Screen-space anchor, y coordinate (.0f)
s16 sx; //!< Horizontal zoom (8.8f)
s16 sy; //!< Vertical zoom (8.8f)
u16 alpha; //!< Counter-clockwise angle ( range [0, 0xFFFF] )
} ALIGN4 AFF_SRC_EX, BgAffineSource;
//! Simple scale-rotation destination struct, BG version.
/*! This is a P-matrix with continuous elements, like the BG matrix.
* It can be used with ObjAffineSet.
*/
typedef struct AFF_DST
{
s16 pa, pb;
s16 pc, pd;
} ALIGN4 AFF_DST, ObjAffineDest;
//! Extended scale-rotate destination struct
/*! This contains the P-matrix and a fixed-point offset , the
* combination can be used to rotate around an arbitrary point.
* Mainly intended for BgAffineSet, but the struct cna be used
* for object transforms too.
*/
typedef struct AFF_DST_EX
{
s16 pa, pb;
s16 pc, pd;
s32 dx, dy;
} ALIGN4 AFF_DST_EX, BgAffineDest;
//\}
/* \} */
// === memory map structs ============================================
/*! \defgroup grpTypeTert Tertiary types
* These types are used for memory mapping of VRAM, affine registers
* and other areas that would benefit from logical memory mapping.
* \ingroup grpTypes
*/
/*! \{ */
//! \name IO register types
//\{
//! Regular bg points; range: :0010 - :001F
typedef struct POINT16 { s16 x, y; } ALIGN4 POINT16, BG_POINT;
//! Affine parameters for backgrounds; range : 0400:0020 - 0400:003F
typedef struct AFF_DST_EX BG_AFFINE;
//! DMA struct; range: 0400:00B0 - 0400:00DF
typedef struct DMA_REC
{
const void *src;
void *dst;
u32 cnt;
} DMA_REC;
//! Timer struct, range: 0400:0100 - 0400:010F
/*! \note The attribute is required, because union's counted as u32 otherwise.
*/
typedef struct TMR_REC
{
union { u16 start, count; } PACKED;
u16 cnt;
} ALIGN4 TMR_REC;
//\}
//! \name PAL types
//\{
//! Palette bank type, for 16-color palette banks
typedef COLOR PALBANK[16];
//\}
/*! \name VRAM array types
* These types allow VRAM access as arrays or matrices in their
* most natural types.
*/
//\{
typedef SCR_ENTRY SCREENLINE[32];
typedef SCR_ENTRY SCREENMAT[32][32];
typedef SCR_ENTRY SCREENBLOCK[1024];
typedef COLOR M3LINE[240];
typedef u8 M4LINE[240]; // NOTE: u8, not u16!!
typedef COLOR M5LINE[160];
typedef TILE CHARBLOCK[512];
typedef TILE8 CHARBLOCK8[256];
//\}
/*! \name OAM structs
* \note These OBJ_ATTR and OBJ_AFFINE structs are interlaced in OAM.
* When using affine objs, struct/DMA/mem copies will give bad results.
*/
//\{
//! Object attributes.
/*! \note attribute 3 is padding for the interlace with OBJ_AFFINE. If
* not using affine objects, it can be used as a free field
*/
typedef struct OBJ_ATTR
{
u16 attr0;
u16 attr1;
u16 attr2;
s16 fill;
} ALIGN4 OBJ_ATTR;
//! Object affine parameters.
/*! \note most fields are padding for the interlace with OBJ_ATTR.
*/
typedef struct OBJ_AFFINE
{
u16 fill0[3]; s16 pa;
u16 fill1[3]; s16 pb;
u16 fill2[3]; s16 pc;
u16 fill3[3]; s16 pd;
} ALIGN4 OBJ_AFFINE;
//\}
/*! \} */
// --------------------------------------------------------------------
// DEFINES
// --------------------------------------------------------------------
#ifndef NULL
#define NULL (void*)0
#endif
#endif // TONC_TYPES

39
src/engine/gba_engine.cpp Normal file
View File

@ -0,0 +1,39 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#include <engine/gba/tonc_memdef.h>
#include <engine/background/text_stream.h>
#include "gba_engine.h"
#include "allocator.h"
void GBAEngine::render() {
vsync();
spriteManager.render();
this->currentScene->tick();
}
GBAEngine::GBAEngine() {
REG_DISPCNT = DCNT_MODE0 | DCNT_OBJ | DCNT_OBJ_1D | DCNT_BG0 | DCNT_BG1;
Allocator::free();
}
void GBAEngine::setScene(Scene& scene) {
if(this->currentScene) {
cleanupPreviousScene();
}
scene.load();
Allocator::free();
TextStream::instance().persist();
spriteManager.set(scene.sprites());
spriteManager.persist();
for(const auto bg : scene.backgrounds()) {
bg->persist();
}
this->currentScene = &scene;
}

37
src/engine/gba_engine.h Normal file
View File

@ -0,0 +1,37 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#ifndef GBA_SPRITE_ENGINE_GBAENGINE_H
#define GBA_SPRITE_ENGINE_GBAENGINE_H
#include <engine/sprites/sprite_manager.h>
#include <engine/gba/tonc_memmap.h>
#include "Scene.h"
class GBAEngine {
private:
Scene* currentScene;
SpriteManager spriteManager;
void vsync() {
while (REG_VCOUNT >= 160);
while (REG_VCOUNT < 160);
}
void cleanupPreviousScene() {
delete currentScene;
}
public:
GBAEngine();
void setScene(Scene& scene);
void render();
void delay(int times) {
for(int i = 0; i < times; i++){}
}
};
#endif //GBA_SPRITE_ENGINE_GBAENGINE_H

View File

@ -0,0 +1,10 @@
//
// Created by Wouter Groeneveld on 27/07/18.
//
#include <engine/gba/tonc_core.h>
#include "palette_manager.h"
void PaletteManager::persist() {
dma3_cpy(this->palletteAddress(), this->data, this->size);
}

View File

@ -0,0 +1,49 @@
//
// Created by Wouter Groeneveld on 27/07/18.
//
#ifndef GBA_SPRITE_ENGINE_PALETTE_MANAGER_H
#define GBA_SPRITE_ENGINE_PALETTE_MANAGER_H
#include <engine/gba/tonc_types.h>
#define PALETTE_BANK_SIZE 16
#define PALETTE_MAX_SIZE 256
class PaletteManager {
protected:
const u16 *data;
int size;
virtual void* palletteAddress() = 0;
public:
PaletteManager(const u16 paletteData[]) : data(paletteData), size(PALETTE_MAX_SIZE) {}
PaletteManager(const u16 paletteData[], int size) : data(paletteData), size(size) {}
void persist();
};
class BackgroundPaletteManager : public PaletteManager {
protected:
void *palletteAddress() override {
return pal_bg_mem;
}
public:
BackgroundPaletteManager(const u16 paletteData[]) : PaletteManager(paletteData) {}
BackgroundPaletteManager(const u16 paletteData[], int size) : PaletteManager(paletteData, size) {}
};
class ForegroundPaletteManager : public PaletteManager {
protected:
void *palletteAddress() override {
return pal_obj_mem;
}
public:
ForegroundPaletteManager(const u16 paletteData[]) : PaletteManager(paletteData) {}
ForegroundPaletteManager(const u16 paletteData[], int size) : PaletteManager(paletteData, size) {}
};
#endif //GBA_SPRITE_ENGINE_PALETTE_MANAGER_H

View File

@ -0,0 +1,51 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#include <engine/gba/tonc_memdef.h>
#include <engine/gba/tonc_oam.h>
#include "affine_sprite.h"
void AffineSprite::identity() {
obj_aff_identity(this->affine.get());
}
void AffineSprite::rotate(u16 alpha) {
obj_aff_rotate(this->affine.get(), alpha);
}
void AffineSprite::syncOam() {
Sprite::syncOam();
rebuildOamAttr1ForAffineIndex();
}
void AffineSprite::setTransformationMatrix(OBJ_AFFINE *matrix) {
// Only copy over affine related pX properties, watch out with OAM overlapping!
obj_aff_copy(matrix, this->affine.get(), 1);
//obj_aff_identity(matrix);
//obj_aff_scale(matrix, 1, 2);
//obj_aff_postmul(matrix, this->affine.get());
}
void AffineSprite::rebuildOamAttr1ForAffineIndex() {
this->oam->attr1 = this->x |
ATTR1_AFF_ID(affIndex) |
(HORIZONTAL_FLIP_FLAG << 12) |
(VERTICAL_FLIP_FLAG << 13) |
(this->size_bits << 14);
}
void AffineSprite::buildOam(int tileIndex) {
Sprite::buildOam(tileIndex);
this->oam->attr0 = ATTR0_Y(this->y) |
ATTR0_MODE(1) |
(GFX_MODE << 10) |
(MOSAIC_MODE << 12) |
(COLOR_MODE_256 << 13) |
(this->shape_bits << 14);
rebuildOamAttr1ForAffineIndex();
this->affine = std::unique_ptr<OBJ_AFFINE>(new OBJ_AFFINE());
identity();
}

View File

@ -0,0 +1,34 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#ifndef GBA_SPRITE_ENGINE_AFFINE_SPRITE_H
#define GBA_SPRITE_ENGINE_AFFINE_SPRITE_H
#include "sprite.h"
class SpriteManager;
class AffineSprite : public Sprite {
private:
int affIndex;
std::unique_ptr<OBJ_AFFINE> affine;
void setTransformationMatrix(OBJ_AFFINE *matrix);
void rebuildOamAttr1ForAffineIndex();
protected:
void buildOam(int tileIndex) override;
void syncOam() override;
public:
void setAffineIndex(int index) { this->affIndex = index; }
void identity();
void rotate(u16 alpha);
AffineSprite(const u32 *imgData, int imgSize, int xC, int yC, SpriteSize spriteSize) : Sprite(imgData, imgSize, xC, yC, spriteSize), affIndex(0) {
}
friend class SpriteManager;
};
#endif //GBA_SPRITE_ENGINE_AFFINE_SPRITE_H

View File

@ -0,0 +1,76 @@
//
// Created by Wouter Groeneveld on 26/07/18.
//
#include <cstdlib>
#include <engine/gba/tonc_memdef.h>
#include "sprite.h"
Sprite::Sprite(const void *imageData, int imageSize, int x, int y, SpriteSize size)
: x(x), y(y), data(imageData), imageSize(imageSize) {
setAttributesBasedOnSize(size);
}
void Sprite::moveTo(int x, int y) {
this->x = x;
this->y = y;
syncOam();
}
void Sprite::syncOam() {
oam->attr0 = (oam->attr0 & ~ATTR0_Y_MASK) | (y & ATTR0_Y_MASK);
oam->attr1 = (oam->attr1 & ~ATTR1_X_MASK) | (x & ATTR1_X_MASK);
}
void Sprite::move() {
this->x += this->dx;
this-> y += this->dy;
syncOam();
}
void Sprite::setAttributesBasedOnSize(SpriteSize size) {
switch (size) {
case SIZE_8_8: size_bits = 0; shape_bits = 0; w = 8; h = 8; break;
case SIZE_16_16: size_bits = 1; shape_bits = 0; w = 16; h = 16; break;
case SIZE_32_32: size_bits = 2; shape_bits = 0; w = 32; h = 32; break;
case SIZE_64_64: size_bits = 3; shape_bits = 0; w = 64; h = 64; break;
case SIZE_16_8: size_bits = 0; shape_bits = 1; w = 16; h = 8; break;
case SIZE_32_8: size_bits = 1; shape_bits = 1; w = 32; h = 8; break;
case SIZE_32_16: size_bits = 2; shape_bits = 1; w = 32; h = 16; break;
case SIZE_64_32: size_bits = 3; shape_bits = 1; w = 64; h = 32; break;
case SIZE_8_16: size_bits = 0; shape_bits = 2; w = 8; h = 16; break;
case SIZE_8_32: size_bits = 1; shape_bits = 2; w = 8; h = 32; break;
case SIZE_16_32: size_bits = 2; shape_bits = 2; w = 16; h = 32; break;
case SIZE_32_64: size_bits = 3; shape_bits = 2; w = 32; h = 64; break;
}
}
bool Sprite::collidesWith(const Sprite &o) {
const Sprite &s = *this;
if((abs(s.x - o.x) < (s.w + o.w) / 2)
&& abs(s.y - o.y) < (s.h + o.h) / 2) {
return true;
}
return false;
}
void Sprite::buildOam(int tileIndex) {
this->oam = std::unique_ptr<OBJ_ATTR>(new OBJ_ATTR());
this->oam->attr0 = ATTR0_Y(this->y) |
ATTR0_MODE(0) |
(GFX_MODE << 10) |
(MOSAIC_MODE << 12) |
(COLOR_MODE_256 << 13) |
(this->shape_bits << 14);
this->oam->attr1 = this->x |
(AFFINE_FLAG_NONE_SET_YET << 9) |
(HORIZONTAL_FLIP_FLAG << 12) |
(VERTICAL_FLIP_FLAG << 13) |
(this->size_bits << 14);
this->oam->attr2 = ATTR2_ID(tileIndex) |
ATTR2_PRIO(priority) |
ATTR2_PALBANK(0);
}

View File

@ -0,0 +1,69 @@
//
// Created by Wouter Groeneveld on 26/07/18.
//
#ifndef GBA_SPRITE_ENGINE_SPRITE_H
#define GBA_SPRITE_ENGINE_SPRITE_H
#include <engine/gba/tonc_types.h>
#include <memory>
#define COLOR_MODE_16 0
#define COLOR_MODE_256 1
#define GFX_MODE 0
#define MOSAIC_MODE 0
#define AFFINE_FLAG_NONE_SET_YET 0
#define HORIZONTAL_FLIP_FLAG 0
#define VERTICAL_FLIP_FLAG 0
enum SpriteSize {
SIZE_8_8,
SIZE_16_16,
SIZE_32_32,
SIZE_64_64,
SIZE_16_8,
SIZE_32_8,
SIZE_32_16,
SIZE_64_32,
SIZE_8_16,
SIZE_8_32,
SIZE_16_32,
SIZE_32_64
};
class SpriteManager;
class Sprite {
protected:
const void *data;
int x, y, priority, dx, dy;
int w, h, size_bits, shape_bits;
int imageSize;
std::unique_ptr<OBJ_ATTR> oam;
virtual void syncOam();
virtual void buildOam(int tileIndex);
void setAttributesBasedOnSize(SpriteSize size);
public:
Sprite(const void *imageData, int imageSize, int x, int y, SpriteSize size);
void setVelocity(int dx, int dy) {
this->dx = dx;
this->dy = dy;
}
void move();
void moveTo(int x, int y);
bool collidesWith(const Sprite &other);
int getX() { return x; }
int getHeight() { return h; }
int getWidth() { return w; }
int getY() { return y; }
friend class SpriteManager;
};
#endif //GBA_SPRITE_ENGINE_SPRITE_H

View File

@ -0,0 +1,5 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#include "sprite_builder.h"

View File

@ -0,0 +1,63 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#ifndef GBA_SPRITE_ENGINE_SPRITE_BUILDER_H
#define GBA_SPRITE_ENGINE_SPRITE_BUILDER_H
#include "sprite.h"
template<typename T> class SpriteBuilder {
private:
int imageSize;
const u32 *imageData;
int x, y, dx, dy;
SpriteSize size;
void reset() {
imageSize = x = y = dx = dy = 0;
imageData = nullptr;
size = SIZE_16_16;
}
public:
SpriteBuilder& withData(const u32 imageData[], int imageSize) {
this->imageData = imageData;
this->imageSize = imageSize;
return *this;
}
SpriteBuilder& withVelocity(int dx, int dy) {
this->dx = dx;
this->dy = dy;
return *this;
}
SpriteBuilder& withLocation(int x, int y) {
this->x = x;
this->y = y;
return *this;
}
SpriteBuilder& withSize(const SpriteSize &size) {
this->size = size;
return *this;
}
T build();
std::unique_ptr<T> buildPtr();
};
template<typename T> std::unique_ptr<T> SpriteBuilder<T>::buildPtr() {
auto s = new T(this->imageData, this->imageSize, this->x, this->y, this->size);
s->setVelocity(this->dx, this->dy);
reset();
return std::unique_ptr<T>(s);
}
template<typename T> T SpriteBuilder<T>::build() {
T s(this->imageData, this->imageSize, this->x, this->y, this->size);
s.setVelocity(this->dx, this->dy);
reset();
return s;
}
#endif //GBA_SPRITE_ENGINE_SPRITE_BUILDER_H

View File

@ -0,0 +1,80 @@
//
// Created by Wouter Groeneveld on 26/07/18.
//
#include "sprite_manager.h"
#include "affine_sprite.h"
#include <engine/gba/tonc_core.h>
#include <engine/allocator.h>
#define MAX_SPRITE_SIZE 128
#define MAX_AFFINE_SIZE 31
void SpriteManager::set(std::vector<Sprite *> sprites) {
initialized = false;
this->sprites.clear();
this->sprites.insert(this->sprites.end(), sprites.begin(), sprites.end());
}
void SpriteManager::add(const Sprite &sprite) {
if(sprites.size() == MAX_SPRITE_SIZE) {
throw std::runtime_error("maximum sprite limit reached");
}
const Sprite* sPtr = &sprite;
sprites.push_back(const_cast<Sprite*>(sPtr));
}
void SpriteManager::render() {
if(!initialized) {
throw std::runtime_error("can't render before initialization");
}
copyOverSpriteOAMToVRAM();
}
void SpriteManager::persist() {
copyOverImageDataToVRAM();
initialized = true;
}
void SpriteManager::copyOverSpriteOAMToVRAM() {
int i = 0;
int affineIndex = 0;
for(auto sprite : this->sprites) {
if(affineIndex > MAX_AFFINE_SIZE) {
throw std::runtime_error("max amount of sprites with affine matriches reached");
}
sprite->move();
auto oam = sprite->oam.get();
oam_mem[i] = *oam;
auto affine = dynamic_cast<AffineSprite*>(sprite);
if(affine) {
// WHY warning: can't do this: obj_aff_mem[affineIndex] = *affineShadow;
// because that would override OAM also! only want to set non-overlapping affine attribs
affine->setTransformationMatrix(&obj_aff_mem[1]);
affine->setAffineIndex(affineIndex);
affineIndex++;
}
i++;
}
for(int j = i; j < MAX_SPRITE_SIZE; j++) {
oam_mem[j].attr0 = ATTR0_HIDE;
}
}
void SpriteManager::copyOverImageDataToVRAM() {
for(auto sprite : this->sprites) {
const auto allocated = Allocator::allocateObjectTiles(sprite->imageSize);
dma3_cpy(allocated.pointer(), sprite->data, allocated.size);
sprite->buildOam(allocated.getTileLocation());
}
}

View File

@ -0,0 +1,30 @@
//
// Created by Wouter Groeneveld on 26/07/18.
//
#ifndef GBA_SPRITE_ENGINE_SPRITE_MANAGER_H
#define GBA_SPRITE_ENGINE_SPRITE_MANAGER_H
#include <engine/gba/tonc_types.h>
#include "sprite.h"
#include <vector>
class SpriteManager {
private:
bool initialized;
std::vector<Sprite*> sprites;
void copyOverSpriteOAMToVRAM();
void copyOverImageDataToVRAM();
public:
int getSpriteSize() { return sprites.size(); }
void add(const Sprite& sprite);
void set(std::vector<Sprite*> sprites);
void persist(); // copies over image and palette data to VRAM, modifies sprite OAM indiches
void render(); // copies over OAM buffer to OAM RAM, called in game loop
};
#endif //GBA_SPRITE_ENGINE_SPRITE_MANAGER_H

BIN
src/flying_stuff_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,63 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#include <engine/sprites/affine_sprite.h>
#include <engine/sprites/sprite_builder.h>
#include <engine/gba/tonc_memmap.h>
#include "flying_stuff_scene.h"
#include "kul.h"
std::vector<Sprite *> FlyingStuffScene::sprites() {
return {
smiley.get(), kul.get(), kulFlying.get(), player.get()
};
}
std::vector<Background *> FlyingStuffScene::backgrounds() {
return {
bg.get()
};
}
void FlyingStuffScene::load() {
SpriteBuilder<Sprite> builder;
SpriteBuilder<AffineSprite> affineBuilder;
smiley = builder
.withData(piskelTiles, sizeof(piskelTiles))
.withSize(SIZE_16_16)
.withLocation(10, 10)
.buildPtr();
kul = builder
.withData(kulTiles, sizeof(kulTiles))
.withSize(SIZE_64_32)
.withLocation(30, 30)
.buildPtr();
kulFlying = affineBuilder
.withData(kulTiles, sizeof(kulTiles))
.withSize(SIZE_64_32)
.withLocation(100, 50)
.withVelocity(1, 1)
.buildPtr();
player = affineBuilder
.withData(piskel2Tiles, sizeof(piskel2Tiles))
.withSize(SIZE_16_16)
.withLocation(150, 60)
.buildPtr();
bg = std::unique_ptr<Background>(new Background(1, background_data, sizeof(background_data), map, sizeof(map)));
bg.get()->useMapScreenBlock(16);
}
void FlyingStuffScene::tick() {
scrollX += 1;
rotation += rotationDiff;
kulFlying.get()->rotate(rotation);
player.get()->rotate(rotation);
bg.get()->scroll(scrollX, scrollY);
}

35
src/flying_stuff_scene.h Normal file
View File

@ -0,0 +1,35 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#ifndef GBA_SPRITE_ENGINE_FLYING_STUFF_SCENE_H
#define GBA_SPRITE_ENGINE_FLYING_STUFF_SCENE_H
#include <engine/sprites/sprite.h>
#include <engine/sprites/affine_sprite.h>
#include <engine/Scene.h>
#include <engine/background/background.h>
class FlyingStuffScene : public Scene {
private:
std::unique_ptr<Sprite> smiley;
std::unique_ptr<AffineSprite> player;
std::unique_ptr<Sprite> kul;
std::unique_ptr<AffineSprite> kulFlying;
std::unique_ptr<Background> bg;
int scrollX, scrollY;
int rotation;
int rotationDiff = 128;
public:
FlyingStuffScene() : rotation(0), rotationDiff(128), scrollX(0), scrollY(0) {}
std::vector<Sprite *> sprites() override;
std::vector<Background *> backgrounds() override;
void load() override;
void tick() override;
};
#endif //GBA_SPRITE_ENGINE_FLYING_STUFF_SCENE_H

627
src/kul.h Normal file
View File

@ -0,0 +1,627 @@
const unsigned short sharedPal[84] __attribute__((aligned(4)))=
{
0x0000,0x3AE2,0x7BBD,0x4042,0x008C,0x3614,0x633B,0x1151,
0x36FD,0x4AB8,0x21B2,0x77BE,0x3E56,0x0D0F,0x1971,0x56FA,
0x6B7D,0x2DD3,0x7FFF,0x04EE,0x1550,0x1593,0x4697,0x677C,
0x52D9,0x5B1A,0x112F,0x1DF5,0x08EE,0x31F4,0x3635,0x08EF,
0x739D,0x7BDF,0x371D,0x29B3,0x4677,0x00CD,0x2192,0x5F1A,
0x1950,0x675B,0x1130,0x77DE,0x4276,0x3214,0x04CE,0x4EB8,
0x4A97,0x56F9,0x25B2,0x3A35,0x5F3B,0x635B,0x3615,0x73BE,
0x2DF4,0x1D91,0x25B3,0x6F9D,0x4ED8,0x6B5C,0x1530,0x56D9,
0x6B7C,0x29D3,0x04CD,0x3A36,0x7BFF,0x00AD,0x4277,0x675C,
0x1D71,0x73BD,0x5F1B,0x4256,0x1951,0x5AFA,0x7BDE,0x4A98,
0x6F7D,0x2DF3,0x090F,
};
#define background_width 88
#define background_height 48
const unsigned char background_data [] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x04, 0x03,
0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02,
0x02, 0x03, 0x03, 0x03, 0x02, 0x02, 0x04, 0x04, 0x02, 0x03, 0x03, 0x03,
0x02, 0x02, 0x04, 0x03, 0x02, 0x03, 0x03, 0x03, 0x02, 0x02, 0x04, 0x03,
0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x03, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04,
0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x03, 0x04, 0x02, 0x02, 0x03, 0x03,
0x03, 0x03, 0x03, 0x04, 0x04, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04,
0x03, 0x02, 0x02, 0x04, 0x03, 0x03, 0x03, 0x04, 0x03, 0x02, 0x02, 0x04,
0x03, 0x03, 0x03, 0x04, 0x02, 0x02, 0x02, 0x04, 0x03, 0x03, 0x03, 0x04,
0x01, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02,
0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x01,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02,
0x02, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x05, 0x04, 0x02, 0x05, 0x05, 0x05, 0x05, 0x02, 0x02, 0x04, 0x05, 0x02,
0x02, 0x02, 0x02, 0x04, 0x02, 0x04, 0x05, 0x02, 0x02, 0x02, 0x02, 0x04,
0x02, 0x04, 0x05, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x04, 0x05, 0x04,
0x02, 0x02, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02,
0x02, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x02, 0x04, 0x05, 0x02,
0x02, 0x02, 0x02, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x04, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x06, 0x06,
0x01, 0x01, 0x01, 0x04, 0x04, 0x06, 0x06, 0x06, 0x01, 0x01, 0x04, 0x06,
0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06,
0x01, 0x01, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x04, 0x06, 0x06,
0x06, 0x07, 0x07, 0x06, 0x04, 0x06, 0x06, 0x06, 0x07, 0x06, 0x06, 0x06,
0x04, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x04, 0x01,
0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01,
0x06, 0x06, 0x06, 0x04, 0x01, 0x04, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06,
0x04, 0x06, 0x04, 0x01, 0x06, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04,
0x06, 0x06, 0x07, 0x06, 0x06, 0x06, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x02, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03,
0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04,
0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x03, 0x03,
0x03, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04,
0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x03, 0x03,
0x03, 0x04, 0x03, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x01, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x04,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x01, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x05, 0x05, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02,
0x05, 0x02, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 0x02, 0x02, 0x02,
0x05, 0x05, 0x05, 0x04, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04,
0x02, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x04, 0x05, 0x02,
0x02, 0x02, 0x02, 0x04, 0x02, 0x04, 0x05, 0x02, 0x02, 0x02, 0x02, 0x04,
0x04, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x05, 0x02, 0x02,
0x02, 0x02, 0x02, 0x04, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04,
0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x05, 0x02, 0x02, 0x02,
0x02, 0x02, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x02,
0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x04, 0x01, 0x01, 0x01, 0x01,
0x04, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x04, 0x06, 0x06, 0x06, 0x06,
0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x04, 0x04, 0x06,
0x06, 0x06, 0x06, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x04, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x04, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x04, 0x06,
0x04, 0x01, 0x01, 0x01, 0x06, 0x04, 0x06, 0x06, 0x04, 0x01, 0x01, 0x01,
0x06, 0x06, 0x06, 0x06, 0x04, 0x01, 0x04, 0x01, 0x06, 0x06, 0x06, 0x06,
0x06, 0x04, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x08,
0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x08, 0x08, 0x01, 0x01, 0x01, 0x01,
0x04, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x04, 0x08, 0x08, 0x08, 0x08,
0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x04, 0x01, 0x01, 0x04, 0x04,
0x04, 0x08, 0x08, 0x08, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01,
0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x01, 0x01, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x08, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x08, 0x08, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08, 0x08, 0x04,
0x01, 0x01, 0x01, 0x01, 0x08, 0x08, 0x08, 0x08, 0x04, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x06,
0x06, 0x07, 0x06, 0x06, 0x01, 0x01, 0x01, 0x04, 0x06, 0x06, 0x07, 0x06,
0x01, 0x01, 0x01, 0x01, 0x04, 0x06, 0x06, 0x07, 0x01, 0x01, 0x01, 0x01,
0x04, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x04,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x07, 0x07,
0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06,
0x07, 0x07, 0x06, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04,
0x01, 0x04, 0x04, 0x06, 0x06, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x04,
0x04, 0x04, 0x01, 0x01, 0x06, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x06, 0x06,
0x06, 0x06, 0x07, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06,
0x06, 0x06, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04,
0x01, 0x01, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06,
0x06, 0x04, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x01,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04, 0x01,
0x04, 0x06, 0x06, 0x04, 0x04, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x04, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x08, 0x08,
0x01, 0x01, 0x01, 0x01, 0x04, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x04,
0x08, 0x08, 0x08, 0x08, 0x01, 0x01, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08,
0x01, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x01, 0x01,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x01, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x08, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x08, 0x08, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08, 0x08, 0x04,
0x01, 0x01, 0x01, 0x01, 0x08, 0x08, 0x08, 0x08, 0x04, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x01, 0x01, 0x01, 0x01,
0x01, 0x04, 0x09, 0x09, 0x01, 0x01, 0x01, 0x04, 0x04, 0x09, 0x09, 0x09,
0x01, 0x01, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01, 0x01, 0x04, 0x09,
0x09, 0x09, 0x09, 0x09, 0x01, 0x01, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09,
0x01, 0x04, 0x09, 0x09, 0x09, 0x08, 0x08, 0x09, 0x04, 0x09, 0x09, 0x09,
0x08, 0x09, 0x09, 0x09, 0x04, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x09, 0x09, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x09, 0x09, 0x04,
0x01, 0x01, 0x01, 0x01, 0x09, 0x09, 0x09, 0x04, 0x01, 0x04, 0x01, 0x01,
0x09, 0x09, 0x09, 0x09, 0x04, 0x09, 0x04, 0x01, 0x09, 0x08, 0x09, 0x09,
0x09, 0x09, 0x09, 0x04, 0x09, 0x09, 0x08, 0x09, 0x09, 0x09, 0x09, 0x04,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x04, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x04, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x09, 0x09,
0x01, 0x01, 0x01, 0x04, 0x04, 0x09, 0x09, 0x09, 0x01, 0x01, 0x04, 0x09,
0x09, 0x09, 0x09, 0x09, 0x01, 0x01, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09,
0x01, 0x01, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01, 0x04, 0x09, 0x09,
0x09, 0x08, 0x08, 0x09, 0x04, 0x09, 0x09, 0x09, 0x08, 0x09, 0x09, 0x09,
0x04, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x09, 0x04, 0x01,
0x01, 0x01, 0x01, 0x01, 0x09, 0x09, 0x09, 0x04, 0x01, 0x01, 0x01, 0x01,
0x09, 0x09, 0x09, 0x04, 0x01, 0x04, 0x01, 0x01, 0x09, 0x09, 0x09, 0x09,
0x04, 0x09, 0x04, 0x01, 0x09, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x04,
0x09, 0x09, 0x08, 0x09, 0x09, 0x09, 0x09, 0x04, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04,
0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x09, 0x09, 0x01, 0x01, 0x01, 0x04,
0x04, 0x09, 0x09, 0x09, 0x01, 0x01, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09,
0x01, 0x01, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01, 0x01, 0x04, 0x09,
0x09, 0x09, 0x09, 0x09, 0x01, 0x04, 0x09, 0x09, 0x09, 0x08, 0x08, 0x09,
0x04, 0x09, 0x09, 0x09, 0x08, 0x09, 0x09, 0x09, 0x04, 0x04, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x09, 0x09, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01,
0x09, 0x09, 0x09, 0x04, 0x01, 0x01, 0x01, 0x01, 0x09, 0x09, 0x09, 0x04,
0x01, 0x04, 0x01, 0x01, 0x09, 0x09, 0x09, 0x09, 0x04, 0x09, 0x04, 0x01,
0x09, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x04, 0x09, 0x09, 0x08, 0x09,
0x09, 0x09, 0x09, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x04,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x04,
0x01, 0x01, 0x01, 0x01, 0x04, 0x09, 0x09, 0x09, 0x01, 0x01, 0x01, 0x04,
0x09, 0x09, 0x09, 0x09, 0x01, 0x01, 0x01, 0x09, 0x09, 0x09, 0x09, 0x09,
0x01, 0x04, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09, 0x04, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x01, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x04, 0x01, 0x01, 0x04,
0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x04, 0x09, 0x04, 0x01, 0x01, 0x01,
0x09, 0x04, 0x09, 0x09, 0x04, 0x01, 0x01, 0x01, 0x09, 0x09, 0x09, 0x09,
0x04, 0x01, 0x04, 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x04, 0x09, 0x04,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x04, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x04, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const unsigned short map [] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008,
0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0012, 0x0014, 0x0014, 0x0015, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008,
0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001d,
0x001e, 0x001f, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0012, 0x0014, 0x0014, 0x0015, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001d,
0x001e, 0x001f, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0001, 0x0002, 0x0000, 0x0000, 0x0003, 0x0004, 0x0000,
0x0000, 0x0001, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000c, 0x000d,
0x0000, 0x0000, 0x000e, 0x000f, 0x0000, 0x0000, 0x000c, 0x000d, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031,
0x0032, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0017, 0x0018, 0x0019,
0x001a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0037,
0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003e, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0000, 0x0000,
0x0005, 0x0006, 0x0005, 0x0006, 0x0005, 0x0006, 0x0005, 0x0006, 0x0005,
0x0006, 0x0005, 0x0006, 0x0005, 0x0006, 0x0005, 0x0006, 0x0005, 0x0006,
0x0005, 0x0006, 0x0005, 0x0006, 0x0005, 0x0006, 0x0005, 0x0006, 0x0005,
0x0006, 0x0005, 0x0006, 0x0005, 0x0006, 0x0010, 0x0011, 0x0010, 0x0011,
0x0010, 0x0011, 0x0010, 0x0011, 0x0010, 0x0011, 0x0010, 0x0011, 0x0010,
0x0011, 0x0010, 0x0011, 0x0010, 0x0011, 0x0010, 0x0011, 0x0010, 0x0011,
0x0010, 0x0011, 0x0010, 0x0011, 0x0010, 0x0011, 0x0010, 0x0011, 0x0010,
0x0011, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
};
const unsigned short bg_palette [] = {
0x7c1f, 0x7e4b, 0x0539, 0x1e7f, 0x0000, 0x5aff, 0x7fff, 0x7ee7, 0x02a0,
0x0b50, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x7c1f, 0x0000, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000
};
const unsigned int kulTiles[512] __attribute__((aligned(4)))=
{
0x22222222,0x22222222,0x22222222,0x22222222,0x08222222,0x08080808,0x071B2222,0x07070707,
0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,
0x22222222,0x22222222,0x22222222,0x22222222,0x08080808,0x08080808,0x07070707,0x07070707,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x22222222,0x22222222,0x22222222,0x22222222,0x08080808,0x08080808,0x07070707,0x07070707,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x22222222,0x22222222,0x22222222,0x22222222,0x08080808,0x08080808,0x07070707,0x07070707,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x22222222,0x22222222,0x22222222,0x22222222,0x08080808,0x08080808,0x07070707,0x07070707,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x22222222,0x22222222,0x22222222,0x22222222,0x08080808,0x08080808,0x07070707,0x07070707,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x22222222,0x22222222,0x22222222,0x22222222,0x08080808,0x08080808,0x07070707,0x07070707,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x22222222,0x22222222,0x22222222,0x22222222,0x08080808,0x08080808,0x07070707,0x07070707,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,
0x1C152222,0x281F1C1C,0x1C152222,0x1228131C,0x1C152222,0x1214131C,0x1C152222,0x1214131C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x281C1C14,0x2A143E14,0x12164C20,0x34120C06,0x49124117,0x19124141,0x2F12340B,0x19123804,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x2A140D1C,0x140D1C1C,0x2712360D,0x12362514,0x0F212D0D,0x4E1D2514,0x0F212D0D,0x4E1D2514,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C2A,0x1414142A,0x251C2A06,0x12121206,0x421C2A19,0x12121227,0x421C2A19,0x32241227,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x141A1414,0x141A1C1A,0x12160B12,0x124F1C24,0x12243712,0x12241C2C,0x12303232,0x12241C2C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C3E283E,0x14143E52,0x143B1247,0x35401232,0x26494A4D,0x2F311211,0x33444F18,0x2C301236,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x28141428,0x0D282A1A,0x12121212,0x27123D3F,0x12121212,0x1212063F,0x3A260912,0x12120F2A,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x0D141A1C,0x1C1C1C1C,0x1E12180D,0x1C1C1C1C,0x05122F14,0x1C1C1C1C,0x05121833,0x1C1C1C1C,
0x1C152222,0x1214131C,0x1C152222,0x1214131C,0x1C152222,0x1214131C,0x1C152222,0x1214131C,
0x1C152222,0x1214131C,0x1C152222,0x1214131C,0x1C152222,0x1E0D1C1C,0x1C152222,0x1C1C1C1C,
0x0E401212,0x19123825,0x330B1212,0x19123845,0x34122112,0x1912511C,0x0B121D40,0x35443A1D,
0x123C4840,0x1240324D,0x12320D10,0x12462D49,0x111A5238,0x38522633,0x1C1C1C1C,0x1C1C1C1C,
0x0F212D0D,0x4E1D2514,0x0F212D0D,0x4E1D2514,0x0F212D0D,0x4E1D2514,0x18120C28,0x4E1D252A,
0x2C123750,0x0B1D421C,0x32201212,0x0B1D2E2E,0x1C484B16,0x1D28131C,0x1C1C1C1C,0x1C1C1C1C,
0x421C2A19,0x18061227,0x421C2A19,0x12121227,0x421C2A19,0x27401227,0x2E1C1427,0x1C1D1227,
0x30122112,0x21441206,0x09121212,0x12121206,0x0A363636,0x36363641,0x1C1C1C1C,0x1C1C1C1C,
0x12303818,0x12241C2C,0x12304612,0x12241C2C,0x12302D27,0x12161C46,0x1224521C,0x12310D0F,
0x12322B21,0x0B124712,0x49251212,0x40121212,0x2A2E3636,0x2A1E1643,0x1C1C1C1C,0x1C1C1C1C,
0x4D121D2F,0x46331224,0x50123916,0x240A3B27,0x12372816,0x16143412,0x12271A46,0x4F2E1812,
0x12090D38,0x4F452412,0x122D1313,0x30421D49,0x33141313,0x26132A38,0x1C1C1C1C,0x1C1C1C1C,
0x0F2F4712,0x12121848,0x12121212,0x2012181D,0x35191012,0x2C121826,0x13453312,0x26121845,
0x124E1212,0x23123518,0x12121212,0x41122931,0x36363633,0x1433413A,0x1C1C1C1C,0x1C1C1C1C,
0x05121947,0x1C1C1C1C,0x05124012,0x1C1C1C1C,0x2D121220,0x1C1C1C1C,0x2D121235,0x1C1C1C1C,
0x2D122B1E,0x1C1C1C1C,0x05123B52,0x1C1C1C1C,0x4C1E412E,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,
0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,0x1C152222,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,0x1C1C1C1C,
};
const unsigned int piskel2Tiles[64] __attribute__((aligned(4)))=
{
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x03030000,0x03000000,0x00000303,
0x03000000,0x00000000,0x03030000,0x00020200,0x03030000,0x02000000,0x03030000,0x02000200,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000003,0x00000000,0x00000300,0x00000000,
0x03030300,0x00000000,0x03000202,0x00000000,0x03000000,0x00000000,0x03000200,0x00000000,
0x03000000,0x00000200,0x03000000,0x02020203,0x00000000,0x03030303,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x03030202,0x00000000,0x00030302,0x00000000,0x00000303,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
};
const unsigned int piskelTiles[64] __attribute__((aligned(4)))=
{
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000100,0x00000000,0x01010100,0x00000000,0x00000100,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
};

33
src/main.cpp Normal file
View File

@ -0,0 +1,33 @@
#include <engine/Scene.h>
#include <engine/gba_engine.h>
#include <engine/background/text.h>
#include <engine/background/text_stream.h>
#include <engine/palette_manager.h>
#include <engine/allocator.h>
#include "kul.h"
#include "flying_stuff_scene.h"
int main() {
GBAEngine engine;
TextStream::instance() << "abc123 sup";
// shared palette extracted from grit
// ./../grit piskel.png piskel2.png kul.png -ftc -pS -gB8 -O shared.c
// assumes 8bpp sprites
ForegroundPaletteManager fgPalette(sharedPal, sizeof(sharedPal));
BackgroundPaletteManager bgPalette(bg_palette, sizeof(bg_palette));
fgPalette.persist();
bgPalette.persist();
FlyingStuffScene flyingStuffScene;
engine.setScene(flyingStuffScene);
while (true) {
engine.render();
//engine.delay(1000);
}
return 0;
}

12
test/CMakeLists.txt Normal file
View File

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.10)
project(Unittest)
SET(GTEST_LIBRARY "/Users/jefklak/CLionProjects/googletest-release-1.8.0/googletest")
# reset linker flags; ARM + GTest doesn't work
SET(CMAKE_EXE_LINKER_FLAGS "${BASE_CMAKE_LINK_FLAGS}")
add_definitions(-DCODE_COMPILED_AS_PART_OF_TEST)
include_directories(${GTEST_LIBRARY}/include)
add_executable(unittest maintest.cpp gbatest.cpp spritetest.cpp ../src/engine/sprites/sprite.cpp ../src/engine/allocator.cpp scenetest.cpp allocatortest.cpp)
target_link_libraries(unittest ${GTEST_LIBRARY}/build/libgtest.a ${GTEST_LIBRARY}/build/libgtest_main.a)

81
test/allocatortest.cpp Normal file
View File

@ -0,0 +1,81 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#include <engine/Scene.h>
#include <engine/sprites/sprite_builder.h>
#include <gtest/gtest.h>
#include <engine/allocator.h>
#include "gtest/gtest.h"
#include <iostream>
#include <engine/background/text.h>
#include <kul.h>
using namespace std;
class AllocatorSuite : public ::testing::Test {
protected:
virtual void TearDown() {
}
virtual void SetUp() {
Allocator::free();
}
};
TEST_F(AllocatorSuite, Scenario_Text_And_Real_Bg_Size) {
auto allocatedText = Allocator::allocateObjectTiles(sizeof(text_data));
auto allocatedBg = Allocator::allocateObjectTiles(sizeof(background_data));
ASSERT_EQ(0, allocatedText.getTileLocation());
ASSERT_EQ(192, allocatedBg.getTileLocation());
}
TEST_F(AllocatorSuite, GetAllocatedSizeDefaultZero) {
ASSERT_EQ(0, Allocator::getAllocatedSprites());
}
TEST_F(AllocatorSuite, Allocate_Increases_Allocated_Size_By_One) {
Allocator::allocateObjectTiles(10);
ASSERT_EQ(1, Allocator::getAllocatedSprites());
}
TEST_F(AllocatorSuite, Free_Resets_Current_Ptr) {
u32 ptr1 = Allocator::getCurrentSpriteIndex();
auto allocated1 = Allocator::allocateObjectTiles(10);
auto allocated2 = Allocator::allocateObjectTiles(3395 * 8);
Allocator::free();
u32 ptr2 = Allocator::getCurrentSpriteIndex();
ASSERT_EQ(ptr1, ptr2);
}
TEST_F(AllocatorSuite, Allocate_Both_Different_Ptr) {
u32 ptr1 = Allocator::getCurrentSpriteIndex();
auto allocated1 = Allocator::allocateObjectTiles(10);
auto allocated2 = Allocator::allocateObjectTiles(3395 * 8);
u32 ptr2 = Allocator::getCurrentSpriteIndex();
ASSERT_NE(allocated1.pointer(), allocated2.pointer());
ASSERT_NE(ptr1, ptr2);
}
TEST_F(AllocatorSuite, Allocate_Sprite_Pointers_Reservers_Some_Tile_Space) {
auto prev = Allocator::getCurrentSpriteIndex();
auto allocated = Allocator::allocateObjectTiles(10);
auto curr = Allocator::getCurrentSpriteIndex();
auto diff = curr - prev;
auto allocated2 = Allocator::allocateObjectTiles(10);
auto curr2 = Allocator::getCurrentSpriteIndex();
auto diff2 = curr2 - curr;
cout << "prev: " << prev << " - curr: " << curr << " (diff: " << diff << ")" << " and " << curr2 << endl;
ASSERT_EQ(prev, allocated.currentAddress);
ASSERT_EQ(curr, allocated2.currentAddress);
ASSERT_EQ(10, allocated.size);
ASSERT_EQ(10, diff);
ASSERT_EQ(10, diff2);
ASSERT_TRUE(curr > prev);
}

16
test/gbatest.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "gtest/gtest.h"
class GBASuite : public ::testing::Test {
protected:
protected:
virtual void TearDown() {
}
virtual void SetUp() {
}
};
TEST_F(GBASuite, AssertionWorks) {
ASSERT_TRUE(true);
}

6
test/maintest.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "gtest/gtest.h"
int main(int argc, char *argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

55
test/scenetest.cpp Normal file
View File

@ -0,0 +1,55 @@
//
// Created by Wouter Groeneveld on 28/07/18.
//
#include <engine/Scene.h>
#include <engine/sprites/sprite_builder.h>
#include "gtest/gtest.h"
class SceneSuite : public ::testing::Test {
protected:
protected:
virtual void TearDown() {
}
virtual void SetUp() {
}
};
class SomeScene : public Scene {
private:
std::unique_ptr<Sprite> someSprite1;
std::unique_ptr<Sprite> someSprite2;
public:
std::vector<Sprite *> sprites() override {
return {
someSprite1.get(), someSprite2.get()
};
}
std::vector<Background *> backgrounds() override {
return std::vector<Background *>();
}
void tick() override {
}
void load() override {
someSprite1 = SpriteBuilder<Sprite>()
.withLocation(1, 1)
.buildPtr();
someSprite2 = SpriteBuilder<Sprite>()
.withLocation(2, 2)
.buildPtr();
}
};
TEST_F(SceneSuite, GetSpritesReturnsPointersOfBuiltSprites) {
SomeScene scene;
scene.load();
auto sprites = scene.sprites();
ASSERT_EQ(2, sprites.size());
ASSERT_EQ(1, sprites.at(0)->getX());
ASSERT_EQ(2, sprites.at(1)->getX());
}

223
test/spritetest.cpp Normal file
View File

@ -0,0 +1,223 @@
#include <engine/sprites/sprite.h>
#include <engine/sprites/sprite_builder.h>
#include "gtest/gtest.h"
const u32 kul_data [] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02,
0x01, 0x01, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x05, 0x06,
0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06,
0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06,
0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06,
0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06,
0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06,
0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x07, 0x08,
0x01, 0x01, 0x05, 0x06, 0x06, 0x09, 0x08, 0x0A, 0x01, 0x01, 0x05, 0x06,
0x06, 0x09, 0x0B, 0x0A, 0x01, 0x01, 0x05, 0x06, 0x06, 0x09, 0x0B, 0x0A,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0B, 0x06, 0x06, 0x08,
0x0B, 0x0C, 0x0B, 0x0D, 0x0E, 0x0F, 0x10, 0x0A, 0x11, 0x12, 0x0A, 0x13,
0x14, 0x15, 0x0A, 0x16, 0x15, 0x15, 0x0A, 0x17, 0x18, 0x13, 0x0A, 0x19,
0x1A, 0x1B, 0x0A, 0x17, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x1C, 0x0B, 0x0D, 0x06, 0x06, 0x1C, 0x0B, 0x1C, 0x1D, 0x0A, 0x1E,
0x0B, 0x1F, 0x1D, 0x0A, 0x1C, 0x20, 0x21, 0x22, 0x0B, 0x1F, 0x23, 0x24,
0x1C, 0x20, 0x21, 0x22, 0x0B, 0x1F, 0x23, 0x24, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x0D, 0x06, 0x06, 0x06, 0x0D, 0x0B, 0x0B, 0x0B,
0x11, 0x0D, 0x06, 0x1F, 0x11, 0x0A, 0x0A, 0x0A, 0x17, 0x0D, 0x06, 0x25,
0x1E, 0x0A, 0x0A, 0x0A, 0x17, 0x0D, 0x06, 0x25, 0x1E, 0x0A, 0x26, 0x27,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0B, 0x0B, 0x28, 0x0B,
0x28, 0x06, 0x28, 0x0B, 0x0A, 0x18, 0x10, 0x0A, 0x26, 0x06, 0x29, 0x0A,
0x0A, 0x2A, 0x26, 0x0A, 0x2B, 0x06, 0x26, 0x0A, 0x27, 0x27, 0x2C, 0x0A,
0x2B, 0x06, 0x26, 0x0A, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x0C, 0x08, 0x0C, 0x06, 0x2D, 0x0C, 0x0B, 0x0B, 0x2E, 0x0A, 0x2F, 0x0B,
0x27, 0x0A, 0x30, 0x31, 0x32, 0x33, 0x16, 0x34, 0x35, 0x0A, 0x36, 0x19,
0x37, 0x29, 0x38, 0x39, 0x1D, 0x0A, 0x2C, 0x2B, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x08, 0x0B, 0x0B, 0x08, 0x28, 0x0D, 0x08, 0x1C,
0x0A, 0x0A, 0x0A, 0x0A, 0x3A, 0x3B, 0x0A, 0x1E, 0x0A, 0x0A, 0x0A, 0x0A,
0x3A, 0x11, 0x0A, 0x0A, 0x0A, 0x3C, 0x34, 0x3D, 0x0D, 0x22, 0x0A, 0x0A,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x28, 0x0B, 0x1C,
0x06, 0x06, 0x06, 0x06, 0x1C, 0x37, 0x0A, 0x3E, 0x06, 0x06, 0x06, 0x06,
0x0B, 0x19, 0x0A, 0x3F, 0x06, 0x06, 0x06, 0x06, 0x39, 0x37, 0x0A, 0x3F,
0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06, 0x06, 0x09, 0x0B, 0x0A,
0x01, 0x01, 0x05, 0x06, 0x06, 0x09, 0x0B, 0x0A, 0x01, 0x01, 0x05, 0x06,
0x06, 0x09, 0x0B, 0x0A, 0x01, 0x01, 0x05, 0x06, 0x06, 0x09, 0x0B, 0x0A,
0x01, 0x01, 0x05, 0x06, 0x06, 0x09, 0x0B, 0x0A, 0x01, 0x01, 0x05, 0x06,
0x06, 0x09, 0x0B, 0x0A, 0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x1C, 0x3E,
0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0A, 0x0A, 0x30, 0x40,
0x1F, 0x1B, 0x0A, 0x17, 0x0A, 0x0A, 0x18, 0x39, 0x41, 0x1B, 0x0A, 0x17,
0x0A, 0x21, 0x0A, 0x13, 0x06, 0x42, 0x0A, 0x17, 0x30, 0x23, 0x0A, 0x18,
0x23, 0x3D, 0x38, 0x31, 0x30, 0x43, 0x44, 0x0A, 0x32, 0x27, 0x30, 0x0A,
0x45, 0x1C, 0x27, 0x0A, 0x16, 0x20, 0x46, 0x0A, 0x1B, 0x2D, 0x28, 0x35,
0x39, 0x34, 0x2D, 0x1B, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x1C, 0x20, 0x21, 0x22, 0x0B, 0x1F, 0x23, 0x24, 0x1C, 0x20, 0x21, 0x22,
0x0B, 0x1F, 0x23, 0x24, 0x1C, 0x20, 0x21, 0x22, 0x0B, 0x1F, 0x23, 0x24,
0x08, 0x12, 0x0A, 0x37, 0x0D, 0x1F, 0x23, 0x24, 0x47, 0x2A, 0x0A, 0x2B,
0x06, 0x25, 0x23, 0x18, 0x0A, 0x0A, 0x0E, 0x27, 0x48, 0x48, 0x23, 0x18,
0x10, 0x49, 0x43, 0x06, 0x06, 0x09, 0x08, 0x23, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x17, 0x0D, 0x06, 0x25, 0x1E, 0x0A, 0x11, 0x37,
0x17, 0x0D, 0x06, 0x25, 0x1E, 0x0A, 0x0A, 0x0A, 0x17, 0x0D, 0x06, 0x25,
0x1E, 0x0A, 0x30, 0x1E, 0x1E, 0x0B, 0x06, 0x48, 0x1E, 0x0A, 0x23, 0x06,
0x0A, 0x21, 0x0A, 0x2C, 0x11, 0x0A, 0x38, 0x21, 0x0A, 0x0A, 0x0A, 0x3C,
0x11, 0x0A, 0x0A, 0x0A, 0x1D, 0x1D, 0x1D, 0x4A, 0x15, 0x1D, 0x1D, 0x1D,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x37, 0x1B, 0x2C, 0x0A,
0x2B, 0x06, 0x26, 0x0A, 0x0A, 0x46, 0x2C, 0x0A, 0x2B, 0x06, 0x26, 0x0A,
0x1E, 0x20, 0x2C, 0x0A, 0x46, 0x06, 0x10, 0x0A, 0x06, 0x2D, 0x26, 0x0A,
0x22, 0x1C, 0x36, 0x0A, 0x21, 0x4B, 0x27, 0x0A, 0x0A, 0x2E, 0x0A, 0x18,
0x0A, 0x0A, 0x1F, 0x16, 0x0A, 0x0A, 0x0A, 0x30, 0x1D, 0x1D, 0x48, 0x0D,
0x4C, 0x10, 0x3E, 0x0D, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x19, 0x23, 0x0A, 0x32, 0x26, 0x0A, 0x39, 0x46, 0x10, 0x4D, 0x0A, 0x47,
0x1E, 0x2F, 0x4A, 0x26, 0x10, 0x08, 0x2A, 0x0A, 0x0A, 0x13, 0x0B, 0x10,
0x46, 0x28, 0x1E, 0x0A, 0x0A, 0x37, 0x48, 0x29, 0x1B, 0x1C, 0x3C, 0x0A,
0x0A, 0x26, 0x41, 0x29, 0x09, 0x09, 0x20, 0x0A, 0x16, 0x23, 0x25, 0x2C,
0x09, 0x09, 0x0B, 0x39, 0x1B, 0x0D, 0x09, 0x34, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x0A, 0x2E, 0x19, 0x22, 0x43, 0x37, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x23, 0x37, 0x0A, 0x0E, 0x0A, 0x45, 0x17, 0x31,
0x34, 0x37, 0x0A, 0x2B, 0x0A, 0x39, 0x41, 0x09, 0x41, 0x37, 0x0A, 0x34,
0x0A, 0x0A, 0x24, 0x0A, 0x37, 0x31, 0x0A, 0x4E, 0x0A, 0x0A, 0x0A, 0x0A,
0x36, 0x4F, 0x0A, 0x15, 0x39, 0x1D, 0x1D, 0x1D, 0x3D, 0x15, 0x39, 0x0B,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x2E, 0x17, 0x0A, 0x3F,
0x06, 0x06, 0x06, 0x06, 0x0A, 0x30, 0x0A, 0x3F, 0x06, 0x06, 0x06, 0x06,
0x0E, 0x0A, 0x0A, 0x20, 0x06, 0x06, 0x06, 0x06, 0x31, 0x0A, 0x0A, 0x20,
0x06, 0x06, 0x06, 0x06, 0x3E, 0x4B, 0x0A, 0x20, 0x06, 0x06, 0x06, 0x06,
0x2D, 0x2F, 0x0A, 0x3F, 0x06, 0x06, 0x06, 0x06, 0x48, 0x15, 0x3E, 0x0F,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06,
0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06,
0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06,
0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06,
0x01, 0x01, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x05, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
};
class SpriteSuite : public ::testing::Test {
protected:
protected:
virtual void TearDown() {
}
virtual void SetUp() {
}
};
TEST_F(SpriteSuite, CollidesWith_B_Right_Of_A_Does_Not_Collide) {
auto a = SpriteBuilder<Sprite>().withLocation(10, 10).withSize(SIZE_16_16).build();
auto b = SpriteBuilder<Sprite>().withLocation(40, 10).withSize(SIZE_16_16).build();
ASSERT_FALSE(a.collidesWith(b));
}
TEST_F(SpriteSuite, CollidesWith_B_Half_In_A_On_X_Axis_Collides) {
auto a = SpriteBuilder<Sprite>().withLocation(10, 10).withSize(SIZE_16_16).build();
auto b = SpriteBuilder<Sprite>().withLocation(20, 10).withSize(SIZE_16_16).build();
ASSERT_TRUE(a.collidesWith(b));
}
TEST_F(SpriteSuite, BuildingWithSize_SetsWidthAndHeight) {
auto s = SpriteBuilder<Sprite>().withSize(SIZE_64_32).build();
ASSERT_EQ(64, s.getWidth());
ASSERT_EQ(32, s.getHeight());
}
TEST_F(SpriteSuite, SpriteBuilderFillsSpriteWithData) {
auto sprite = SpriteBuilder<Sprite>()
.withData(kul_data, sizeof(kul_data))
.withLocation(10, 20)
.withSize(SIZE_32_64)
.build();
ASSERT_EQ(32, sprite.getWidth());
ASSERT_EQ(64, sprite.getHeight());
ASSERT_EQ(10, sprite.getX());
ASSERT_EQ(20, sprite.getY());
}