From b197b6d457d9b8f2b498b42c8ba0d8963a796787 Mon Sep 17 00:00:00 2001 From: "local-model/engine-L2-grok-4.5" Date: Sat, 19 Sep 2026 13:20:59 +0200 Subject: [PATCH] engine-c: richer procedural building silhouettes (snapshot+sprites) --- engine-c/src/snapshot.c | 127 ++++++++++++++++++++++++++++------------ engine-c/src/sprites.c | 127 ++++++++++++++++++++++++++++------------ 2 files changed, 178 insertions(+), 76 deletions(-) diff --git a/engine-c/src/snapshot.c b/engine-c/src/snapshot.c index 5bbf035..552a73c 100644 --- a/engine-c/src/snapshot.c +++ b/engine-c/src/snapshot.c @@ -373,60 +373,111 @@ static void draw_bld(Building *b, int sx, int sy) { switch (b->type) { case BT_BASE: - fill_rect(sx + 5, sy + 5, W - 10, H - 10, ok, og, ob); - fill_rect(sx + 7, sy + 7, W - 14, H - 14, br, bg, bb); - disc(sx + W/2, sy + H/2, W/4, lr, lg, lb); - disc(sx + W/2, sy + H/2, W/6, 255, 250, 180); - line(sx + W/2, sy + H/2, sx + W/2, sy + 4, 220, 210, 80); - fill_rect(sx + W/2 - 2, sy + 4, 4, H/3, 200, 180, 60); + /* multi-wing HQ: side wings + centre block + dome + mast */ + fill_rect(sx + 4, sy + 18, 18, 28, ok, og, ob); + fill_rect(sx + 6, sy + 20, 14, 24, br, bg, bb); + fill_rect(sx + W - 22, sy + 18, 18, 28, ok, og, ob); + fill_rect(sx + W - 20, sy + 20, 14, 24, br, bg, bb); + fill_rect(sx + 16, sy + 10, W - 32, H - 20, ok, og, ob); + fill_rect(sx + 18, sy + 12, W - 36, H - 24, br, bg, bb); + fill_rect(sx + 20, sy + 14, W - 40, 8, lr, lg, lb); /* roof band */ + disc(sx + W/2, sy + H/2 - 2, 12, ok, og, ob); + disc(sx + W/2, sy + H/2 - 2, 10, lr, lg, lb); + disc(sx + W/2, sy + H/2 - 2, 5, 255, 250, 180); /* command dome */ + fill_rect(sx + W/2 - 2, sy + 4, 4, H/2 - 8, 200, 180, 60); /* mast */ + fill_rect(sx + W/2 - 5, sy + 4, 10, 3, 220, 210, 80); /* antenna tip */ + fill_rect(sx + W/2 - 6, sy + H - 14, 12, 6, 40, 38, 34); /* entry */ break; case BT_WARFACTORY: - fill_rect(sx + 5, sy + 5, W - 10, H - 10, ok, og, ob); - fill_rect(sx + 7, sy + 7, W - 14, H - 14, br, bg, bb); - fill_rect(sx + 10, sy + 10, W - 20, 12, lr, lg, lb); - fill_rect(sx + 10, sy + H - 24, W - 20, 12, lr, lg, lb); - fill_rect(sx + W/2 - 4, sy + 8, 8, H - 16, 35, 35, 40); + /* hangar shell + ridge vents + dark bay door */ + fill_rect(sx + 4, sy + 6, W - 8, H - 12, ok, og, ob); + fill_rect(sx + 6, sy + 8, W - 12, H - 16, br, bg, bb); + fill_rect(sx + 8, sy + 10, W - 16, 10, lr, lg, lb); /* roof ridge */ + fill_rect(sx + 10, sy + 12, 6, 6, 55, 50, 42); /* vent */ + fill_rect(sx + W/2 - 3, sy + 12, 6, 6, 55, 50, 42); + fill_rect(sx + W - 16, sy + 12, 6, 6, 55, 50, 42); + fill_rect(sx + 10, sy + H - 28, W - 20, 18, ok, og, ob); + fill_rect(sx + 12, sy + H - 26, W - 24, 14, 35, 35, 40); /* bay */ + line(sx + W/2, sy + H - 26, sx + W/2, sy + H - 12, 70, 68, 60); + fill_rect(sx + 8, sy + H - 10, W - 16, 4, 50, 48, 42); /* ramp lip */ break; case BT_REFINERY: - disc(sx + W/2, sy + H/2, W/4 + 2, ok, og, ob); - disc(sx + W/2, sy + H/2, W/4, 200, 165, 85); - ring(sx + W/2, sy + H/2, W/4 - 3, 3, 90, 70, 45); - fill_rect(sx + 8, sy + H - 14, W - 16, 8, 140, 110, 55); + /* twin silos + pipe/conveyor slab + hopper */ + disc(sx + 18, sy + H/2 - 2, 14, ok, og, ob); + disc(sx + 18, sy + H/2 - 2, 12, 200, 165, 85); + ring(sx + 18, sy + H/2 - 2, 9, 2, 90, 70, 45); + disc(sx + W - 18, sy + H/2 - 2, 14, ok, og, ob); + disc(sx + W - 18, sy + H/2 - 2, 12, 190, 155, 75); + ring(sx + W - 18, sy + H/2 - 2, 9, 2, 90, 70, 45); + fill_rect(sx + 14, sy + H - 16, W - 28, 10, ok, og, ob); + fill_rect(sx + 16, sy + H - 14, W - 32, 6, 140, 110, 55); /* conveyor */ + line(sx + 18, sy + H/2 + 8, sx + W - 18, sy + H - 12, 110, 90, 50); + line(sx + 18, sy + H/2 + 10, sx + W - 18, sy + H - 10, 110, 90, 50); + fill_rect(sx + W/2 - 6, sy + 8, 12, 14, ok, og, ob); + fill_rect(sx + W/2 - 4, sy + 10, 8, 10, br, bg, bb); /* hopper */ break; case BT_POWER: - disc(sx + W/2, sy + H/2, W/3 + 1, ok, og, ob); - disc(sx + W/2, sy + H/2, W/3, 100, 160, 210); + /* cooling towers + reactor core + steam cross */ + disc(sx + W/2 - 6, sy + H/2 + 2, 8, ok, og, ob); + disc(sx + W/2 - 6, sy + H/2 + 2, 6, 100, 160, 210); + disc(sx + W/2 + 6, sy + H/2 + 2, 8, ok, og, ob); + disc(sx + W/2 + 6, sy + H/2 + 2, 6, 90, 150, 200); + fill_rect(sx + 6, sy + 6, W - 12, 10, ok, og, ob); + fill_rect(sx + 8, sy + 7, W - 16, 7, 70, 120, 170); /* reactor slab */ + disc(sx + W/2, sy + 10, 4, 250, 252, 255); line(sx + W/2, sy + 4, sx + W/2, sy + H - 4, 230, 245, 255); - line(sx + 4, sy + H/2, sx + W - 4, sy + H/2, 230, 245, 255); - disc(sx + W/2, sy + H/2, 4, 250, 252, 255); + line(sx + 4, sy + H/2, sx + W - 4, sy + H/2, 200, 230, 250); + fill_rect(sx + W/2 - 2, sy + H - 8, 4, 5, 55, 50, 42); /* base stub */ break; case BT_TURRET: - fill_rect(sx + 4, sy + H - 10, W - 8, 8, 55, 50, 42); - disc(sx + W/2, sy + H/2, W/3 + 1, ok, og, ob); - disc(sx + W/2, sy + H/2, W/3, br, bg, bb); - disc(sx + W/2, sy + H/2, W/5, lr, lg, lb); - line(sx + W/2, sy + H/2, sx + W/2 + 14, sy + H/2 - 14, 30, 28, 24); - disc(sx + W/2 + 12, sy + H/2 - 12, 2, 255, 200, 80); + /* bunker base + cupola + thick barrel */ + fill_rect(sx + 3, sy + H - 12, W - 6, 10, ok, og, ob); + fill_rect(sx + 5, sy + H - 10, W - 10, 7, 55, 50, 42); + disc(sx + W/2, sy + H/2 + 1, W/3 + 2, ok, og, ob); + disc(sx + W/2, sy + H/2 + 1, W/3, br, bg, bb); + disc(sx + W/2, sy + H/2 + 1, W/5, lr, lg, lb); + disc(sx + W/2, sy + H/2 - 1, 3, 40, 38, 32); /* hatch */ + line(sx + W/2, sy + H/2, sx + W/2 + 13, sy + H/2 - 12, 30, 28, 24); + line(sx + W/2 + 1, sy + H/2 + 1, sx + W/2 + 13, sy + H/2 - 11, 50, 45, 35); + disc(sx + W/2 + 12, sy + H/2 - 11, 2, 255, 200, 80); break; case BT_WALL: + /* battlement blocks + ridge + shadow seam */ fill_rect(sx + 1, sy + 1, W - 2, H - 2, ok, og, ob); - fill_rect(sx + 2, sy + 2, W - 4, H - 4, 175, 155, 120); - fill_rect(sx + 3, sy + 3, W - 6, 5, 210, 190, 150); - line(sx + 2, sy + 2, sx + W - 2, sy + H - 2, 60, 52, 42); + fill_rect(sx + 2, sy + 6, W - 4, H - 8, 175, 155, 120); + fill_rect(sx + 2, sy + 2, 7, 8, 195, 175, 140); /* merlon */ + fill_rect(sx + 12, sy + 2, 7, 8, 195, 175, 140); + fill_rect(sx + 22, sy + 2, 7, 8, 195, 175, 140); + fill_rect(sx + 3, sy + 10, W - 6, 4, 210, 190, 150); /* ridge */ + line(sx + 2, sy + H/2, sx + W - 2, sy + H/2, 60, 52, 42); + line(sx + W/2, sy + 6, sx + W/2, sy + H - 2, 70, 60, 48); break; case BT_REPAIR: - fill_rect(sx + 7, sy + 7, W - 14, H - 14, ok, og, ob); - fill_rect(sx + 9, sy + 9, W - 18, H - 18, br, bg, bb); - ring(sx + W/2, sy + H/2, W/4, 3, 120, 220, 120); - line(sx + W/2 - 12, sy + H/2, sx + W/2 + 12, sy + H/2, 120, 220, 120); - line(sx + W/2, sy + H/2 - 12, sx + W/2, sy + H/2 + 12, 120, 220, 120); + /* garage bay + crane arm + green service mark */ + fill_rect(sx + 5, sy + 8, W - 10, H - 14, ok, og, ob); + fill_rect(sx + 7, sy + 10, W - 14, H - 18, br, bg, bb); + fill_rect(sx + 10, sy + H - 26, W - 20, 14, 40, 38, 34); /* bay floor */ + fill_rect(sx + 12, sy + H - 24, W - 24, 10, 55, 52, 48); + fill_rect(sx + W - 18, sy + 8, 10, 6, ok, og, ob); /* crane mast */ + fill_rect(sx + W - 16, sy + 10, 6, 22, 90, 85, 70); + line(sx + W - 13, sy + 12, sx + 14, sy + 18, 120, 110, 90); /* jib */ + line(sx + W - 13, sy + 13, sx + 14, sy + 19, 100, 90, 70); + ring(sx + W/2 - 4, sy + H/2 + 2, 8, 2, 120, 220, 120); + line(sx + W/2 - 10, sy + H/2 + 2, sx + W/2 + 2, sy + H/2 + 2, 120, 220, 120); + line(sx + W/2 - 4, sy + H/2 - 4, sx + W/2 - 4, sy + H/2 + 8, 120, 220, 120); break; case BT_RESEARCH: - fill_rect(sx + 7, sy + 7, W - 14, H - 14, ok, og, ob); - fill_rect(sx + 9, sy + 9, W - 18, H - 18, br, bg, bb); - disc(sx + W/2, sy + H/2, W/5, 210, 180, 80); - line(sx + W/2, sy + 6, sx + W/2, sy + H - 6, 230, 230, 160); - line(sx + 6, sy + H/2, sx + W - 6, sy + H/2, 230, 230, 160); + /* lab block + dish + instrument stubs */ + fill_rect(sx + 6, sy + 14, W - 12, H - 20, ok, og, ob); + fill_rect(sx + 8, sy + 16, W - 16, H - 24, br, bg, bb); + fill_rect(sx + 10, sy + 18, W - 20, 8, lr, lg, lb); + disc(sx + W/2 + 6, sy + 14, 12, ok, og, ob); + disc(sx + W/2 + 6, sy + 14, 10, 210, 180, 80); /* dish */ + ring(sx + W/2 + 6, sy + 14, 7, 2, 180, 150, 60); + disc(sx + W/2 + 6, sy + 14, 3, 255, 240, 160); + fill_rect(sx + 12, sy + H - 18, 6, 8, 230, 230, 160); /* stub */ + fill_rect(sx + 22, sy + H - 20, 5, 10, 230, 230, 160); + line(sx + W/2 + 6, sy + 4, sx + W/2 + 6, sy + 14, 200, 190, 120); break; default: break; diff --git a/engine-c/src/sprites.c b/engine-c/src/sprites.c index 6f41c7e..1a1f1ce 100644 --- a/engine-c/src/sprites.c +++ b/engine-c/src/sprites.c @@ -273,60 +273,111 @@ SDL_Texture *sprites_make_bld(SDL_Renderer *r, BuildingType t, Faction f) { switch (t) { case BT_BASE: - fill_rect(s, 5, 5, W - 10, H - 10, ok, og, ob, 255); - fill_rect(s, 7, 7, W - 14, H - 14, base.r, base.g, base.b, 255); - disc(s, W/2, H/2, W/4, lite.r, lite.g, lite.b, 255); - disc(s, W/2, H/2, W/6, 255, 250, 180, 255); - line(s, W/2, H/2, W/2, 4, 220, 210, 80, 255); - fill_rect(s, W/2 - 2, 4, 4, H/3, 200, 180, 60, 255); /* antenna mast */ + /* multi-wing HQ: side wings + centre block + dome + mast (parity draw_bld) */ + fill_rect(s, 4, 18, 18, 28, ok, og, ob, 255); + fill_rect(s, 6, 20, 14, 24, base.r, base.g, base.b, 255); + fill_rect(s, W - 22, 18, 18, 28, ok, og, ob, 255); + fill_rect(s, W - 20, 20, 14, 24, base.r, base.g, base.b, 255); + fill_rect(s, 16, 10, W - 32, H - 20, ok, og, ob, 255); + fill_rect(s, 18, 12, W - 36, H - 24, base.r, base.g, base.b, 255); + fill_rect(s, 20, 14, W - 40, 8, lite.r, lite.g, lite.b, 255); + disc(s, W/2, H/2 - 2, 12, ok, og, ob, 255); + disc(s, W/2, H/2 - 2, 10, lite.r, lite.g, lite.b, 255); + disc(s, W/2, H/2 - 2, 5, 255, 250, 180, 255); + fill_rect(s, W/2 - 2, 4, 4, H/2 - 8, 200, 180, 60, 255); + fill_rect(s, W/2 - 5, 4, 10, 3, 220, 210, 80, 255); + fill_rect(s, W/2 - 6, H - 14, 12, 6, 40, 38, 34, 255); break; case BT_WARFACTORY: - fill_rect(s, 5, 5, W - 10, H - 10, ok, og, ob, 255); - fill_rect(s, 7, 7, W - 14, H - 14, base.r, base.g, base.b, 255); - fill_rect(s, 10, 10, W - 20, 12, lite.r, lite.g, lite.b, 255); - fill_rect(s, 10, H - 24, W - 20, 12, lite.r, lite.g, lite.b, 255); - fill_rect(s, W/2 - 4, 8, 8, H - 16, 35, 35, 40, 255); /* bay door */ + /* hangar shell + ridge vents + dark bay door */ + fill_rect(s, 4, 6, W - 8, H - 12, ok, og, ob, 255); + fill_rect(s, 6, 8, W - 12, H - 16, base.r, base.g, base.b, 255); + fill_rect(s, 8, 10, W - 16, 10, lite.r, lite.g, lite.b, 255); + fill_rect(s, 10, 12, 6, 6, 55, 50, 42, 255); + fill_rect(s, W/2 - 3, 12, 6, 6, 55, 50, 42, 255); + fill_rect(s, W - 16, 12, 6, 6, 55, 50, 42, 255); + fill_rect(s, 10, H - 28, W - 20, 18, ok, og, ob, 255); + fill_rect(s, 12, H - 26, W - 24, 14, 35, 35, 40, 255); + line(s, W/2, H - 26, W/2, H - 12, 70, 68, 60, 255); + fill_rect(s, 8, H - 10, W - 16, 4, 50, 48, 42, 255); break; case BT_REFINERY: - disc(s, W/2, H/2, W/4 + 2, ok, og, ob, 255); - disc(s, W/2, H/2, W/4, 200, 165, 85, 255); - ring(s, W/2, H/2, W/4 - 3, 3, 90, 70, 45, 255); - fill_rect(s, 8, H - 14, W - 16, 8, 140, 110, 55, 255); /* base slab */ + /* twin silos + pipe/conveyor slab + hopper */ + disc(s, 18, H/2 - 2, 14, ok, og, ob, 255); + disc(s, 18, H/2 - 2, 12, 200, 165, 85, 255); + ring(s, 18, H/2 - 2, 9, 2, 90, 70, 45, 255); + disc(s, W - 18, H/2 - 2, 14, ok, og, ob, 255); + disc(s, W - 18, H/2 - 2, 12, 190, 155, 75, 255); + ring(s, W - 18, H/2 - 2, 9, 2, 90, 70, 45, 255); + fill_rect(s, 14, H - 16, W - 28, 10, ok, og, ob, 255); + fill_rect(s, 16, H - 14, W - 32, 6, 140, 110, 55, 255); + line(s, 18, H/2 + 8, W - 18, H - 12, 110, 90, 50, 255); + line(s, 18, H/2 + 10, W - 18, H - 10, 110, 90, 50, 255); + fill_rect(s, W/2 - 6, 8, 12, 14, ok, og, ob, 255); + fill_rect(s, W/2 - 4, 10, 8, 10, base.r, base.g, base.b, 255); break; case BT_POWER: - disc(s, W/2, H/2, W/3 + 1, ok, og, ob, 255); - disc(s, W/2, H/2, W/3, 100, 160, 210, 255); + /* cooling towers + reactor core + steam cross */ + disc(s, W/2 - 6, H/2 + 2, 8, ok, og, ob, 255); + disc(s, W/2 - 6, H/2 + 2, 6, 100, 160, 210, 255); + disc(s, W/2 + 6, H/2 + 2, 8, ok, og, ob, 255); + disc(s, W/2 + 6, H/2 + 2, 6, 90, 150, 200, 255); + fill_rect(s, 6, 6, W - 12, 10, ok, og, ob, 255); + fill_rect(s, 8, 7, W - 16, 7, 70, 120, 170, 255); + disc(s, W/2, 10, 4, 250, 252, 255, 255); line(s, W/2, 4, W/2, H - 4, 230, 245, 255, 255); - line(s, 4, H/2, W - 4, H/2, 230, 245, 255, 255); - disc(s, W/2, H/2, 4, 250, 252, 255, 255); + line(s, 4, H/2, W - 4, H/2, 200, 230, 250, 255); + fill_rect(s, W/2 - 2, H - 8, 4, 5, 55, 50, 42, 255); break; case BT_TURRET: - fill_rect(s, 4, H - 10, W - 8, 8, 55, 50, 42, 255); - disc(s, W/2, H/2, W/3 + 1, ok, og, ob, 255); - disc(s, W/2, H/2, W/3, base.r, base.g, base.b, 255); - disc(s, W/2, H/2, W/5, lite.r, lite.g, lite.b, 255); - line(s, W/2, H/2, W/2 + 14, H/2 - 14, 30, 28, 24, 255); - disc(s, W/2 + 12, H/2 - 12, 2, 255, 200, 80, 255); /* barrel tip */ + /* bunker base + cupola + thick barrel */ + fill_rect(s, 3, H - 12, W - 6, 10, ok, og, ob, 255); + fill_rect(s, 5, H - 10, W - 10, 7, 55, 50, 42, 255); + disc(s, W/2, H/2 + 1, W/3 + 2, ok, og, ob, 255); + disc(s, W/2, H/2 + 1, W/3, base.r, base.g, base.b, 255); + disc(s, W/2, H/2 + 1, W/5, lite.r, lite.g, lite.b, 255); + disc(s, W/2, H/2 - 1, 3, 40, 38, 32, 255); + line(s, W/2, H/2, W/2 + 13, H/2 - 12, 30, 28, 24, 255); + line(s, W/2 + 1, H/2 + 1, W/2 + 13, H/2 - 11, 50, 45, 35, 255); + disc(s, W/2 + 12, H/2 - 11, 2, 255, 200, 80, 255); break; case BT_WALL: + /* battlement blocks + ridge + shadow seam */ fill_rect(s, 1, 1, W - 2, H - 2, ok, og, ob, 255); - fill_rect(s, 2, 2, W - 4, H - 4, 175, 155, 120, 255); - fill_rect(s, 3, 3, W - 6, 5, 210, 190, 150, 255); - line(s, 2, 2, W - 2, H - 2, 60, 52, 42, 255); + fill_rect(s, 2, 6, W - 4, H - 8, 175, 155, 120, 255); + fill_rect(s, 2, 2, 7, 8, 195, 175, 140, 255); + fill_rect(s, 12, 2, 7, 8, 195, 175, 140, 255); + fill_rect(s, 22, 2, 7, 8, 195, 175, 140, 255); + fill_rect(s, 3, 10, W - 6, 4, 210, 190, 150, 255); + line(s, 2, H/2, W - 2, H/2, 60, 52, 42, 255); + line(s, W/2, 6, W/2, H - 2, 70, 60, 48, 255); break; case BT_REPAIR: - fill_rect(s, 7, 7, W - 14, H - 14, ok, og, ob, 255); - fill_rect(s, 9, 9, W - 18, H - 18, base.r, base.g, base.b, 255); - ring(s, W/2, H/2, W/4, 3, 120, 220, 120, 255); - line(s, W/2 - 12, H/2, W/2 + 12, H/2, 120, 220, 120, 255); - line(s, W/2, H/2 - 12, W/2, H/2 + 12, 120, 220, 120, 255); + /* garage bay + crane arm + green service mark */ + fill_rect(s, 5, 8, W - 10, H - 14, ok, og, ob, 255); + fill_rect(s, 7, 10, W - 14, H - 18, base.r, base.g, base.b, 255); + fill_rect(s, 10, H - 26, W - 20, 14, 40, 38, 34, 255); + fill_rect(s, 12, H - 24, W - 24, 10, 55, 52, 48, 255); + fill_rect(s, W - 18, 8, 10, 6, ok, og, ob, 255); + fill_rect(s, W - 16, 10, 6, 22, 90, 85, 70, 255); + line(s, W - 13, 12, 14, 18, 120, 110, 90, 255); + line(s, W - 13, 13, 14, 19, 100, 90, 70, 255); + ring(s, W/2 - 4, H/2 + 2, 8, 2, 120, 220, 120, 255); + line(s, W/2 - 10, H/2 + 2, W/2 + 2, H/2 + 2, 120, 220, 120, 255); + line(s, W/2 - 4, H/2 - 4, W/2 - 4, H/2 + 8, 120, 220, 120, 255); break; case BT_RESEARCH: - fill_rect(s, 7, 7, W - 14, H - 14, ok, og, ob, 255); - fill_rect(s, 9, 9, W - 18, H - 18, base.r, base.g, base.b, 255); - disc(s, W/2, H/2, W/5, 210, 180, 80, 255); - line(s, W/2, 6, W/2, H - 6, 230, 230, 160, 255); - line(s, 6, H/2, W - 6, H/2, 230, 230, 160, 255); + /* lab block + dish + instrument stubs */ + fill_rect(s, 6, 14, W - 12, H - 20, ok, og, ob, 255); + fill_rect(s, 8, 16, W - 16, H - 24, base.r, base.g, base.b, 255); + fill_rect(s, 10, 18, W - 20, 8, lite.r, lite.g, lite.b, 255); + disc(s, W/2 + 6, 14, 12, ok, og, ob, 255); + disc(s, W/2 + 6, 14, 10, 210, 180, 80, 255); + ring(s, W/2 + 6, 14, 7, 2, 180, 150, 60, 255); + disc(s, W/2 + 6, 14, 3, 255, 240, 160, 255); + fill_rect(s, 12, H - 18, 6, 8, 230, 230, 160, 255); + fill_rect(s, 22, H - 20, 5, 10, 230, 230, 160, 255); + line(s, W/2 + 6, 4, W/2 + 6, 14, 200, 190, 120, 255); break; default: (void)dark;