#include "odroid/audio.h" #include "odroid/battery.h" #include "odroid/display.h" #include "odroid/input.h" #include "odroid/sdcard.h" #include "macros.h" #include "text.h" #include #include #include #include static const char* LOG_TAG = "Main"; static uint16_t gFramebuffer[LCD_WIDTH * LCD_HEIGHT]; static const uint16_t palette[4] = { 0xFFFF, 0x55AD, 0xAA52, 0x0000, }; static const uint8_t tiles[][16*16] = { // White { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }, // Light Grey { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }, // Dark Grey { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }, // Black { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,3,3,3,3,3,3,3,3,3,3,3,0,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, 0,0,3,3,3,3,3,3,3,3,3,3,3,3,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }, }; static int tileBuffer[15][40] = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0}, {0, 0, 3, 0, 0, 0, 3, 3, 3, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0}, {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, }; void DrawTile(int index, int x, int y) { int startX = x * 16; int startY = y * 16; for (int row = 0; row < 16; ++row) { for (int col = 0; col < 16; ++col) { uint8_t paletteIndex = tiles[index][row * 16 + col]; int screenY = startY + row; int screenX = startX + col; uint16_t color = palette[paletteIndex]; gFramebuffer[screenY * LCD_WIDTH + screenX] = color; } } } void app_main(void) { Odroid_InitializeInput(); Odroid_InitializeDisplay(); Odroid_InitializeSdcard(); Odroid_InitializeBatteryReader(); Odroid_InitializeAudio(); ESP_LOGI(LOG_TAG, "Odroid initialization complete - entering main loop"); uint8_t frameIndex = 0; char snapFilename[20]; int xLeft = 0; for (;;) { memset(gFramebuffer, 0xff, 320*240*2); Odroid_Input input = Odroid_PollInput(); if (input.left) { xLeft -= 1; if (xLeft < 0) { xLeft = 39; } } else if (input.right) { xLeft += 1; if (xLeft > 39) { xLeft = 0; } } for (int tileY = 0; tileY < 15; ++tileY) { for (int tileX = xLeft; tileX < xLeft + 20; ++tileX) { int tile = tileX % 40; int tileIndex = tileBuffer[tileY][tile]; DrawTile(tileIndex, tileX - xLeft, tileY); } } char string[5]; snprintf(string, 5, "%02d", xLeft); DrawText(gFramebuffer, string, 2, 0, 0, palette[3]); int tileRight = (xLeft + 20) % 40; snprintf(string, 5, "%02d", tileRight); DrawText(gFramebuffer, string, 2, 18, 0, palette[3]); if (input.menu) { snprintf(snapFilename, 20, "/sdcard/frame%02d", frameIndex); ESP_LOGI(LOG_TAG, "Writing snapshot to %s", snapFilename); FILE* snapFile = fopen(snapFilename, "wb"); assert(snapFile); fwrite(gFramebuffer, 1, LCD_WIDTH * LCD_HEIGHT * sizeof(gFramebuffer[0]), snapFile); fclose(snapFile); ++frameIndex; } Odroid_DrawFrame(gFramebuffer); } // Should never get here esp_restart(); }