Browse Source

feat: implement 16-variant autotiling inspired by the AI mockup

master
Matteo Benedetto 3 days ago
parent
commit
2e2c074f49
  1. 91
      build_autotiles.py
  2. 16
      src/main.c
  3. 63
      src/tiles.c

91
build_autotiles.py

@ -0,0 +1,91 @@
import os
# 0: Floor
# 1: Light Green
# 2: Dark Green
# 3: Black
floor_tile = [
"00000000",
"00010000",
"00100000",
"00000000",
"00000000",
"00000010",
"00001000",
"00000000",
]
def make_autotile(n, e, s, w):
# base is floor
t = [list("00000000") for _ in range(8)]
# define boundaries
top = 0 if n else 2
bottom = 8 if s else 6
left = 0 if w else 2
right = 8 if e else 6
# fill with dark green
for r in range(top, bottom):
for c in range(left, right):
t[r][c] = "2"
# Add highlight (1) to the top edge
if not n:
for c in range(left, right):
t[1][c] = "1"
t[2][c] = "1"
# Add shadow (3) to the bottom edge
if not s:
for c in range(left, right):
t[6][c] = "3"
t[7][c] = "3"
# Add rounded corners
if not n and not w:
t[1][2] = "0"; t[1][3] = "1"; t[2][2] = "1"
if not n and not e:
t[1][7] = "0"; t[1][6] = "1"; t[1][5] = "1"; t[2][7] = "0"; t[2][6] = "1"
if not s and not w:
t[7][2] = "0"; t[7][3] = "3"; t[6][2] = "3"
if not s and not e:
t[7][7] = "0"; t[7][6] = "3"; t[6][7] = "0"; t[6][6] = "3"
# Add some texture
if n and s and e and w:
t[3][3] = "1"; t[4][5] = "3"
return ["".join(row) for row in t]
def to_gb_format(lines):
bytes_arr = []
for line in lines:
lo = hi = 0
for i, char in enumerate(line):
val = int(char)
if val & 1: lo |= (1 << (7 - i))
if val & 2: hi |= (1 << (7 - i))
bytes_arr.append(lo)
bytes_arr.append(hi)
return bytes_arr
tiles = [floor_tile]
for mask in range(16):
n = (mask & 8) != 0
e = (mask & 4) != 0
s = (mask & 2) != 0
w = (mask & 1) != 0
tiles.append(make_autotile(n, e, s, w))
with open('src/tiles.c', 'w') as f:
f.write('#include "tiles.h"\n\n')
f.write(f'const unsigned char TileData[{len(tiles)*16}] = {{\n')
for i, t in enumerate(tiles):
f.write(f' // Tile {i} (Mask {i-1 if i>0 else "Floor"})\n')
b = to_gb_format(t)
f.write(' ' + ', '.join(f"0x{val:02X}" for val in b) + ',\n')
f.write('};\n')
print("tiles.c generated with autotiles!")

16
src/main.c

@ -54,13 +54,14 @@ void main(void) {
initrand(DIV_REG);
// Invia i dati grafici del gioco alla VRAM
set_bkg_data(0, 5, TileData); // 1 strada + 4 siepi
set_bkg_data(0, 17, TileData); // 1 strada + 16 varianti autotile
// La mappa background in memoria hardware è grande 32x32 tiles.
// Inizializziamo il "fuori mappa" con siepi solide (mask 15 = 1 + 15)
for (y = 0; y < 32; y++) {
for (x = 0; x < 32; x++) {
uint8_t rand_hedge = 1 + (rand() % 4);
set_bkg_tiles(x, y, 1, 1, &rand_hedge);
uint8_t solid_hedge = 16;
set_bkg_tiles(x, y, 1, 1, &solid_hedge);
}
}
@ -71,8 +72,13 @@ void main(void) {
for (y = 0; y < MAZE_HEIGHT; y++) {
for (x = 0; x < MAZE_WIDTH; x++) {
uint8_t tile_idx = maze[y][x];
if (tile_idx == 1) { // Se è un muro, scegli una siepe variante casuale
tile_idx = 1 + (rand() % 4);
if (tile_idx == 1) { // Se è un muro, usa autotiling
uint8_t mask = 0;
if (y > 0 && maze[y-1][x] == 1) mask |= 8; // Nord
if (x < MAZE_WIDTH-1 && maze[y][x+1] == 1) mask |= 4; // Est
if (y < MAZE_HEIGHT-1 && maze[y+1][x] == 1) mask |= 2; // Sud
if (x > 0 && maze[y][x-1] == 1) mask |= 1; // Ovest
tile_idx = 1 + mask;
}
set_bkg_tiles(x, y, 1, 1, &tile_idx);
}

63
src/tiles.c

@ -1,31 +1,38 @@
/**
* @file tiles.c
* @brief Implementazione dei dati grafici dei tile.
*/
#include "tiles.h"
// Definizione dei dati dei tile. Ogni tile su Game Boy è 8x8 pixel.
// Ogni riga del tile è rappresentata da 2 byte (planar format).
const unsigned char TileData[] = {
// Tile 0: Completamente bianco (tutti i bit a 0)
// Indica la stanza scavata e i percorsi.
0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,
0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,
// Tile 1: Siepe da giardino (variante 0)
0xC3,0xBD, 0x90,0x6F, 0x24,0xFB, 0x49,0xFE,
0x12,0xEF, 0x44,0xFB, 0x88,0x7F, 0xA3,0xDD,
// Tile 2: Siepe da giardino (variante 1)
0x8C,0x7B, 0x22,0xFD, 0x41,0xBF, 0x14,0xEF,
0x82,0xFD, 0x20,0xDF, 0x48,0xF7, 0x11,0xFE,
// Tile 3: Siepe da giardino (variante 2)
0x42,0xBF, 0x90,0xEF, 0x05,0xFB, 0x22,0xFD,
0x88,0x7F, 0x01,0xFE, 0x48,0xF7, 0x24,0xDF,
// Tile 4: Siepe da giardino (variante 3)
0x14,0xFB, 0x82,0x7F, 0x20,0xDF, 0x88,0xF7,
0x03,0xFD, 0x50,0xBF, 0x04,0xFB, 0x21,0xFE
const unsigned char TileData[272] = {
// Tile 0 (Mask Floor)
0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00,
// Tile 1 (Mask 0)
0x00, 0x00, 0x1E, 0x00, 0x3E, 0x00, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x3E, 0x3E, 0x1E, 0x1E,
// Tile 2 (Mask 1)
0x00, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0xFE, 0xFE, 0xFE, 0xFE,
// Tile 3 (Mask 2)
0x00, 0x00, 0x1E, 0x00, 0x3E, 0x00, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C,
// Tile 4 (Mask 3)
0x00, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC,
// Tile 5 (Mask 4)
0x00, 0x00, 0x1F, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x3F, 0x3F, 0x1F, 0x1F,
// Tile 6 (Mask 5)
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
// Tile 7 (Mask 6)
0x00, 0x00, 0x1F, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F,
// Tile 8 (Mask 7)
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
// Tile 9 (Mask 8)
0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x3E, 0x3E, 0x1E, 0x1E,
// Tile 10 (Mask 9)
0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0xFE, 0xFE, 0xFE, 0xFE,
// Tile 11 (Mask 10)
0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C,
// Tile 12 (Mask 11)
0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC,
// Tile 13 (Mask 12)
0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x3F, 0x3F, 0x1F, 0x1F,
// Tile 14 (Mask 13)
0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
// Tile 15 (Mask 14)
0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F,
// Tile 16 (Mask 15)
0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x10, 0xEF, 0x04, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
};

Loading…
Cancel
Save