Part 8: Tile System
Bu işleme şunda yer alıyor:
		
							ebeveyn
							
								
									02a911ef9f
								
							
						
					
					
						işleme
						1096c7eac2
					
				| 
						 | 
				
			
			@ -19,3 +19,5 @@ if (ret != ESP_OK) {
 | 
			
		|||
	* `IDF_TOOLS_PATH` is the path to the toolchain
 | 
			
		||||
* `source export.sh`
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											İkili dosya gösterilmiyor.
										
									
								
							| 
		 Sonra Genişlik: | Yükseklik: | Boyut: 1.3 KiB  | 
										
											İkili dosya gösterilmiyor.
										
									
								
							| 
		 Sonra Genişlik: | Yükseklik: | Boyut: 1.3 KiB  | 
										
											İkili dosya gösterilmiyor.
										
									
								
							| 
		 Sonra Genişlik: | Yükseklik: | Boyut: 1.3 KiB  | 
										
											İkili dosya gösterilmiyor.
										
									
								
							| 
		 Sonra Genişlik: | Yükseklik: | Boyut: 1.3 KiB  | 
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
JASC-PAL
 | 
			
		||||
0100
 | 
			
		||||
4
 | 
			
		||||
255 255 255
 | 
			
		||||
171 171 171
 | 
			
		||||
84 84 84
 | 
			
		||||
0 0 0
 | 
			
		||||
										
											İkili dosya gösterilmiyor.
										
									
								
							
										
											İkili dosya gösterilmiyor.
										
									
								
							
										
											İkili dosya gösterilmiyor.
										
									
								
							
										
											İkili dosya gösterilmiyor.
										
									
								
							
							
								
								
									
										276
									
								
								game/src/main.c
								
								
								
								
							
							
						
						
									
										276
									
								
								game/src/main.c
								
								
								
								
							| 
						 | 
				
			
			@ -15,6 +15,139 @@ 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();
 | 
			
		||||
| 
						 | 
				
			
			@ -23,113 +156,63 @@ void app_main(void)
 | 
			
		|||
	Odroid_InitializeBatteryReader();
 | 
			
		||||
	Odroid_InitializeAudio();
 | 
			
		||||
 | 
			
		||||
	// Load sprite
 | 
			
		||||
	uint16_t* sprite = (uint16_t*)malloc(64 * 64 * sizeof(uint16_t));
 | 
			
		||||
	{
 | 
			
		||||
		FILE* spriteFile = fopen("/sdcard/key", "r");
 | 
			
		||||
		assert(spriteFile);
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < 64; ++i)
 | 
			
		||||
		{
 | 
			
		||||
			for (int j = 0; j < 64; ++j)
 | 
			
		||||
			{
 | 
			
		||||
				fread(sprite, sizeof(uint16_t), 64 * 64, spriteFile);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fclose(spriteFile);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Load sound effect
 | 
			
		||||
	uint16_t* soundBuffer;
 | 
			
		||||
	int soundEffectLength = 1441;
 | 
			
		||||
	{
 | 
			
		||||
		FILE* soundFile = fopen("/sdcard/jump", "r");
 | 
			
		||||
		assert(soundFile);
 | 
			
		||||
 | 
			
		||||
		uint8_t* soundEffect = malloc(soundEffectLength);
 | 
			
		||||
		assert(soundEffect);
 | 
			
		||||
 | 
			
		||||
		soundBuffer = malloc(soundEffectLength*2);
 | 
			
		||||
		assert(soundBuffer);
 | 
			
		||||
 | 
			
		||||
		fread(soundEffect, soundEffectLength, 1, soundFile);
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < soundEffectLength; ++i)
 | 
			
		||||
		{
 | 
			
		||||
			// 16 bits required but only MSB is actually sent to the DAC
 | 
			
		||||
			soundBuffer[i] = (soundEffect[i] << 8u);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	ESP_LOGI(LOG_TAG, "Odroid initialization complete - entering main loop");
 | 
			
		||||
 | 
			
		||||
	int x = 0;
 | 
			
		||||
	int y = 0;
 | 
			
		||||
 | 
			
		||||
	uint16_t color = 0xffff;
 | 
			
		||||
 | 
			
		||||
	int lastState = 0;
 | 
			
		||||
	uint8_t frameIndex = 0;
 | 
			
		||||
	char snapFilename[20];
 | 
			
		||||
	int xLeft = 0;
 | 
			
		||||
 | 
			
		||||
	for (;;)
 | 
			
		||||
	{
 | 
			
		||||
		memset(gFramebuffer, 0, 320 * 240 * 2);
 | 
			
		||||
		memset(gFramebuffer, 0xff, 320*240*2);
 | 
			
		||||
 | 
			
		||||
		Odroid_Input input = Odroid_PollInput();
 | 
			
		||||
 | 
			
		||||
		if (input.left) { x -= 20; }
 | 
			
		||||
		else if (input.right) { x += 20; }
 | 
			
		||||
 | 
			
		||||
		if (input.up) { y -= 20; }
 | 
			
		||||
		else if (input.down) { y += 20; }
 | 
			
		||||
 | 
			
		||||
		if (input.a) { color = SWAP_ENDIAN_16(RGB565(0xff, 0, 0)); }
 | 
			
		||||
		else if (input.b) { color = SWAP_ENDIAN_16(RGB565(0, 0xff, 0)); }
 | 
			
		||||
		else if (input.start) { color = SWAP_ENDIAN_16(RGB565(0, 0, 0xff)); }
 | 
			
		||||
		else if (input.select) { color = SWAP_ENDIAN_16(RGB565(0xff, 0xff, 0xff)); }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		int thisState = input.volume;
 | 
			
		||||
 | 
			
		||||
		if ((thisState == 1) && (thisState != lastState))
 | 
			
		||||
		if (input.left)
 | 
			
		||||
		{
 | 
			
		||||
			Odroid_PlayAudio(soundBuffer, soundEffectLength*2);
 | 
			
		||||
		}
 | 
			
		||||
			xLeft -= 1;
 | 
			
		||||
 | 
			
		||||
		lastState = thisState;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		DrawText(gFramebuffer, "The Quick Brown Fox", 19, 0, 5, SWAP_ENDIAN_16(RGB565(0xFF, 0, 0)));
 | 
			
		||||
		DrawText(gFramebuffer, "Jumped Over The:", 16, 0, 6, SWAP_ENDIAN_16(RGB565(0, 0xFF, 0)));
 | 
			
		||||
		DrawText(gFramebuffer, "Lazy Dog?!", 10, 0, 7, SWAP_ENDIAN_16(RGB565(0, 0, 0xFF)));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		int spriteRow = 0;
 | 
			
		||||
		int spriteCol = 0;
 | 
			
		||||
 | 
			
		||||
		for (int row = y; row < y + 64; ++row)
 | 
			
		||||
		{
 | 
			
		||||
			spriteCol = 0;
 | 
			
		||||
 | 
			
		||||
			for (int col = x; col < x + 64; ++col)
 | 
			
		||||
			if (xLeft < 0)
 | 
			
		||||
			{
 | 
			
		||||
				uint16_t pixelColor = sprite[64 * spriteRow + spriteCol];
 | 
			
		||||
 | 
			
		||||
				if (pixelColor != 0)
 | 
			
		||||
				{
 | 
			
		||||
					gFramebuffer[row * LCD_WIDTH + col] = color;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				++spriteCol;
 | 
			
		||||
				xLeft = 39;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			++spriteRow;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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)
 | 
			
		||||
		{
 | 
			
		||||
			const char* snapFilename = "/sdcard/framebuf";
 | 
			
		||||
			snprintf(snapFilename, 20, "/sdcard/frame%02d", frameIndex);
 | 
			
		||||
 | 
			
		||||
			ESP_LOGI(LOG_TAG, "Writing snapshot to %s", snapFilename);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -139,19 +222,8 @@ void app_main(void)
 | 
			
		|||
			fwrite(gFramebuffer, 1, LCD_WIDTH * LCD_HEIGHT * sizeof(gFramebuffer[0]), snapFile);
 | 
			
		||||
 | 
			
		||||
			fclose(snapFile);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		uint32_t batteryLevel = Odroid_ReadBatteryLevel();
 | 
			
		||||
		ESP_LOGI(LOG_TAG, "Battery level: %u\n", batteryLevel);
 | 
			
		||||
 | 
			
		||||
		if (batteryLevel < 3600)
 | 
			
		||||
		{
 | 
			
		||||
			Odroid_EnableBatteryLight();
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			Odroid_DisableBatteryLight();
 | 
			
		||||
			++frameIndex;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,8 +8,8 @@ static const int MAX_GLYPHS_PER_COL = LCD_HEIGHT / GLYPH_HEIGHT;
 | 
			
		|||
 | 
			
		||||
void DrawText(uint16_t* framebuffer, char* string, int length, int x, int y, uint16_t color)
 | 
			
		||||
{
 | 
			
		||||
	assert(x + length < MAX_GLYPHS_PER_ROW);
 | 
			
		||||
	assert(y < MAX_GLYPHS_PER_COL);
 | 
			
		||||
	assert(x + length <= MAX_GLYPHS_PER_ROW);
 | 
			
		||||
	assert(y <= MAX_GLYPHS_PER_COL);
 | 
			
		||||
 | 
			
		||||
	for (int charIndex = 0; charIndex < length; ++charIndex)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,5 +4,7 @@ project(tools)
 | 
			
		|||
 | 
			
		||||
set(CMAKE_C_FLAGS "-Wall -Werror")
 | 
			
		||||
 | 
			
		||||
add_executable(font_generator src/font_generator.c)
 | 
			
		||||
add_executable(font_processor src/font_processor.c)
 | 
			
		||||
add_executable(palette_processor src/palette_processor.c)
 | 
			
		||||
add_executable(tile_processor src/tile_processor.c)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,105 @@
 | 
			
		|||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv)
 | 
			
		||||
{
 | 
			
		||||
	if (argc != 3)
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(stderr, "Usage: %s <input palette> <output header>\n", argv[0]);
 | 
			
		||||
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char* inFilename = argv[1];
 | 
			
		||||
	const char* outFilename = argv[2];
 | 
			
		||||
 | 
			
		||||
	// Read the file
 | 
			
		||||
	uint16_t* palette;
 | 
			
		||||
	int paletteSize;
 | 
			
		||||
	{
 | 
			
		||||
		FILE* inFile = fopen(inFilename, "r");
 | 
			
		||||
		assert(inFile);
 | 
			
		||||
 | 
			
		||||
		char* line;
 | 
			
		||||
		size_t len = 0;
 | 
			
		||||
 | 
			
		||||
		getline(&line, &len, inFile);
 | 
			
		||||
		assert(strncmp(line, "JASC-PAL", 8) == 0);
 | 
			
		||||
 | 
			
		||||
		getline(&line, &len, inFile);
 | 
			
		||||
		assert(strncmp(line, "0100", 4) == 0);
 | 
			
		||||
 | 
			
		||||
		getline(&line, &len, inFile);
 | 
			
		||||
		paletteSize = atoi(line);
 | 
			
		||||
 | 
			
		||||
		palette = malloc(sizeof(*palette) * paletteSize);
 | 
			
		||||
		assert(palette);
 | 
			
		||||
 | 
			
		||||
		// Each line is of form R G B
 | 
			
		||||
		for (int i = 0; i < paletteSize; ++i)
 | 
			
		||||
		{
 | 
			
		||||
			getline(&line, &len, inFile);
 | 
			
		||||
 | 
			
		||||
			char* tok = strtok(line, " ");
 | 
			
		||||
			int red = atoi(tok);
 | 
			
		||||
 | 
			
		||||
			tok = strtok(NULL, " ");
 | 
			
		||||
			int green = atoi(tok);
 | 
			
		||||
 | 
			
		||||
			tok = strtok(NULL, " ");
 | 
			
		||||
			int blue = atoi(tok);
 | 
			
		||||
 | 
			
		||||
			uint16_t rgb565 =
 | 
			
		||||
				  ((red >> 3u) << 11u)
 | 
			
		||||
				| ((green >> 2u) << 5u)
 | 
			
		||||
				| (blue >> 3u);
 | 
			
		||||
 | 
			
		||||
			uint16_t endianSwap = ((rgb565 & 0xFFu) << 8u) | (rgb565 >> 8u);
 | 
			
		||||
 | 
			
		||||
			palette[i] = endianSwap;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fclose(inFile);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	printf("Input: %s\n", inFilename);
 | 
			
		||||
	printf("Output: %s\n", outFilename);
 | 
			
		||||
	printf("Palette Size: %d\n", paletteSize);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// Output to the file
 | 
			
		||||
	{
 | 
			
		||||
		FILE* outFile = fopen(outFilename, "w");
 | 
			
		||||
		assert(outFile);
 | 
			
		||||
 | 
			
		||||
		fprintf(outFile, "// AUTOMATICALLY GENERATED. DO NOT EDIT.\n");
 | 
			
		||||
		fprintf(outFile, "\n");
 | 
			
		||||
		fprintf(outFile, "#pragma once\n");
 | 
			
		||||
		fprintf(outFile, "\n");
 | 
			
		||||
		fprintf(outFile, "\n");
 | 
			
		||||
 | 
			
		||||
		fprintf(outFile, "uint16_t palette[%d] =\n", paletteSize);
 | 
			
		||||
		fprintf(outFile, "{\n");
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < paletteSize; ++i)
 | 
			
		||||
		{
 | 
			
		||||
			fprintf(outFile, "	0x%04X,\n", palette[i]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fprintf(outFile, "};\n");
 | 
			
		||||
		fprintf(outFile, "\n");
 | 
			
		||||
 | 
			
		||||
		fclose(outFile);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	printf("\n");
 | 
			
		||||
	printf("DONE\n");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,132 @@
 | 
			
		|||
#include <assert.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv)
 | 
			
		||||
{
 | 
			
		||||
	if (argc != 3)
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(stderr, "Usage: %s <input image> <output header>\n", argv[0]);
 | 
			
		||||
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char* inFilename = argv[1];
 | 
			
		||||
	const char* outFilename = argv[2];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	int tileWidth;
 | 
			
		||||
	int tileHeight;
 | 
			
		||||
	uint8_t* tileBuffer;
 | 
			
		||||
	{
 | 
			
		||||
		FILE* inFile = fopen(inFilename, "rb");
 | 
			
		||||
		assert(inFile);
 | 
			
		||||
 | 
			
		||||
		#pragma pack(push,1)
 | 
			
		||||
		struct BmpHeader
 | 
			
		||||
		{
 | 
			
		||||
			char magic[2];
 | 
			
		||||
			uint32_t totalSize;
 | 
			
		||||
			uint32_t reserved;
 | 
			
		||||
			uint32_t offset;
 | 
			
		||||
			uint32_t headerSize;
 | 
			
		||||
			int32_t width;
 | 
			
		||||
			int32_t height;
 | 
			
		||||
			uint16_t planes;
 | 
			
		||||
			uint16_t depth;
 | 
			
		||||
			uint32_t compression;
 | 
			
		||||
			uint32_t imageSize;
 | 
			
		||||
			int32_t horizontalResolution;
 | 
			
		||||
			int32_t verticalResolution;
 | 
			
		||||
			uint32_t paletteColorCount;
 | 
			
		||||
			uint32_t importantColorcount;
 | 
			
		||||
		} bmpHeader;
 | 
			
		||||
		#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
		// Read the BMP header so we know where the image data is located
 | 
			
		||||
		fread(&bmpHeader, 1, sizeof(bmpHeader), inFile);
 | 
			
		||||
		assert(bmpHeader.magic[0] == 'B' && bmpHeader.magic[1] == 'M');
 | 
			
		||||
		assert(bmpHeader.depth == 8);
 | 
			
		||||
		assert(bmpHeader.headerSize == 40);
 | 
			
		||||
 | 
			
		||||
		// Go to location in file of image data
 | 
			
		||||
		fseek(inFile, bmpHeader.offset, SEEK_SET);
 | 
			
		||||
 | 
			
		||||
		// Read in the image data
 | 
			
		||||
		tileBuffer = malloc(bmpHeader.imageSize);
 | 
			
		||||
		assert(tileBuffer);
 | 
			
		||||
		fread(tileBuffer, 1, bmpHeader.imageSize, inFile);
 | 
			
		||||
 | 
			
		||||
		tileWidth = bmpHeader.width;
 | 
			
		||||
		tileHeight = bmpHeader.height;
 | 
			
		||||
 | 
			
		||||
		fclose(inFile);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	printf("Input: %s\n", inFilename);
 | 
			
		||||
	printf("Output: %s\n", outFilename);
 | 
			
		||||
	printf("Width: %d\n", tileWidth);
 | 
			
		||||
	printf("Height: %d\n", tileHeight);
 | 
			
		||||
 | 
			
		||||
	FILE* outFile = fopen(outFilename, "w");
 | 
			
		||||
	assert(outFile);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// Generate the preamble
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(outFile, "// AUTOMATICALLY GENERATED. DO NOT EDIT.\n");
 | 
			
		||||
		fprintf(outFile, "\n");
 | 
			
		||||
		fprintf(outFile, "#pragma once\n");
 | 
			
		||||
		fprintf(outFile, "\n");
 | 
			
		||||
		fprintf(outFile, "#include <stdint.h>\n");
 | 
			
		||||
		fprintf(outFile, "\n");
 | 
			
		||||
		fprintf(outFile, "\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// Generate the font map with the calculated glyph bytes
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(outFile, "static const uint8_t tile[%d][%d] =\n", tileHeight, tileWidth);
 | 
			
		||||
		fprintf(outFile, "{\n");
 | 
			
		||||
		fprintf(outFile, "	");
 | 
			
		||||
 | 
			
		||||
		int count = 0;
 | 
			
		||||
 | 
			
		||||
		for (int row = 0; row < tileHeight; ++row)
 | 
			
		||||
		{
 | 
			
		||||
			for (int col = 0; col < tileWidth; ++col)
 | 
			
		||||
			{
 | 
			
		||||
				// BMP is laid out bottom-to-top, but we want top-to-bottom (0-indexed)
 | 
			
		||||
				int y =  tileHeight - row - 1;
 | 
			
		||||
 | 
			
		||||
				uint8_t paletteIndex = tileBuffer[y * tileWidth + col];
 | 
			
		||||
 | 
			
		||||
				fprintf(outFile, "%d,", paletteIndex);
 | 
			
		||||
				++count;
 | 
			
		||||
 | 
			
		||||
				// Put a newline after sixteen values to keep it orderly
 | 
			
		||||
				if ((count % 16) == 0)
 | 
			
		||||
				{
 | 
			
		||||
					fprintf(outFile, "\n");
 | 
			
		||||
					fprintf(outFile, "	");
 | 
			
		||||
 | 
			
		||||
					count = 0;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fprintf(outFile, "};\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fclose(outFile);
 | 
			
		||||
 | 
			
		||||
	printf("\n");
 | 
			
		||||
	printf("DONE\n");
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
		Yükleniyor…
	
		Yeni konuda referans