; ============================================================================== ; EBLAN ENGINE - Texture Management & Procedural Texture Generator ; ============================================================================== .code ; ------------------------------------------------------------------------------ ; GenerateDefaultTextures: Procedurally creates 128x128 32-bit BGRA textures ; Zero external asset dependency - works out of the box on any machine! ; ------------------------------------------------------------------------------ GenerateDefaultTextures PROC uses ebx ecx edx esi edi LOCAL texBase:DWORD, px:DWORD, py:DWORD, color:DWORD ; -------------------------------------------------------------------------- ; Texture 1: Red Brick Wall ; -------------------------------------------------------------------------- mov eax, OFFSET textureBuffer add eax, 1 * TEX_SIZE_BYTES mov texBase, eax mov py, 0 brick_y_loop: mov px, 0 brick_x_loop: ; Base brick color (Dark red/brown) mov color, 00852215h ; Mortar lines horizontally every 16 pixels mov eax, py and eax, 15 cmp eax, 0 je set_mortar cmp eax, 1 je set_mortar ; Vertical mortar stagger: alternate every 16 rows mov edx, px mov eax, py and eax, 16 jz @F add edx, 16 ; shift vertical joint by 16 px on odd rows @@: and edx, 31 cmp edx, 0 je set_mortar cmp edx, 1 je set_mortar jmp apply_brick_noise set_mortar: mov color, 00555555h ; Gray mortar jmp write_brick_pixel apply_brick_noise: ; Add subtle shade variation mov eax, px xor eax, py and eax, 7 shl eax, 2 add color, eax write_brick_pixel: ; Write BGRA pixel to texture mov eax, py shl eax, 7 ; py * 128 add eax, px shl eax, 2 ; * 4 bytes mov edi, texBase add edi, eax mov edx, color mov [edi], edx inc px cmp px, TEX_W jl brick_x_loop inc py cmp py, TEX_H jl brick_y_loop ; -------------------------------------------------------------------------- ; Texture 2: Wood Planks ; -------------------------------------------------------------------------- mov eax, OFFSET textureBuffer add eax, 2 * TEX_SIZE_BYTES mov texBase, eax mov py, 0 wood_y_loop: mov px, 0 wood_x_loop: ; Base wood color (Warm brown) mov color, 00683A12h ; Plank seams every 32 horizontal pixels mov eax, px and eax, 31 cmp eax, 0 jne @F mov color, 00201005h ; Dark seam jmp write_wood_pixel @@: ; Subtle wood grain variation based on py mov eax, py and eax, 3 shl eax, 3 add color, eax write_wood_pixel: mov eax, py shl eax, 7 add eax, px shl eax, 2 mov edi, texBase add edi, eax mov edx, color mov [edi], edx inc px cmp px, TEX_W jl wood_x_loop inc py cmp py, TEX_H jl wood_y_loop ; -------------------------------------------------------------------------- ; Texture 3: Stone / Cobblestone ; -------------------------------------------------------------------------- mov eax, OFFSET textureBuffer add eax, 3 * TEX_SIZE_BYTES mov texBase, eax mov py, 0 stone_y_loop: mov px, 0 stone_x_loop: ; Base gray mov color, 00555555h ; Stone border grid (32x32 blocks) mov eax, px and eax, 31 test eax, eax jz set_stone_border mov eax, py and eax, 31 test eax, eax jz set_stone_border ; Noise mov eax, px imul eax, 3 add eax, py and eax, 15 shl eax, 2 add color, eax jmp write_stone_pixel set_stone_border: mov color, 00222222h write_stone_pixel: mov eax, py shl eax, 7 add eax, px shl eax, 2 mov edi, texBase add edi, eax mov edx, color mov [edi], edx inc px cmp px, TEX_W jl stone_x_loop inc py cmp py, TEX_H jl stone_y_loop ; -------------------------------------------------------------------------- ; Texture 4: Metal Tech / Rivets ; -------------------------------------------------------------------------- mov eax, OFFSET textureBuffer add eax, 4 * TEX_SIZE_BYTES mov texBase, eax mov py, 0 metal_y_loop: mov px, 0 metal_x_loop: ; Base metal slate (blue-gray) mov color, 00606570h ; Rivets near corners (10, 10) and (118, 118) ; Check if within 4 pixels of a rivet center mov eax, px sub eax, 10 imul eax, eax mov edx, py sub edx, 10 imul edx, edx add eax, edx cmp eax, 16 jle set_rivet mov eax, px sub eax, 118 imul eax, eax mov edx, py sub edx, 118 imul edx, edx add eax, edx cmp eax, 16 jle set_rivet jmp write_metal_pixel set_rivet: mov color, 00A0B0C0h ; Shiny rivet highlight write_metal_pixel: mov eax, py shl eax, 7 add eax, px shl eax, 2 mov edi, texBase add edi, eax mov edx, color mov [edi], edx inc px cmp px, TEX_W jl metal_x_loop inc py cmp py, TEX_H jl metal_y_loop ; -------------------------------------------------------------------------- ; Texture 5: Door ; -------------------------------------------------------------------------- mov eax, OFFSET textureBuffer add eax, 5 * TEX_SIZE_BYTES mov texBase, eax mov py, 0 door_y_loop: mov px, 0 door_x_loop: ; Door frame (outer 8 pixels) mov eax, px cmp eax, 8 jl set_door_frame cmp eax, 120 jge set_door_frame mov eax, py cmp eax, 8 jl set_door_frame ; Door body (Deep wood) mov color, 00502D15h ; Brass door knob at (px=100, py=64) mov eax, px sub eax, 100 imul eax, eax mov edx, py sub edx, 64 imul edx, edx add eax, edx cmp eax, 36 jle set_brass_knob jmp write_door_pixel set_door_frame: mov color, 00333333h jmp write_door_pixel set_brass_knob: mov color, 00FFD000h ; Gold / Brass write_door_pixel: mov eax, py shl eax, 7 add eax, px shl eax, 2 mov edi, texBase add edi, eax mov edx, color mov [edi], edx inc px cmp px, TEX_W jl door_x_loop inc py cmp py, TEX_H jl door_y_loop ; -------------------------------------------------------------------------- ; Texture 7: Pillar / Marble Mosaic ; -------------------------------------------------------------------------- mov eax, OFFSET textureBuffer add eax, 7 * TEX_SIZE_BYTES mov texBase, eax mov py, 0 pillar_y_loop: mov px, 0 pillar_x_loop: ; Vertical fluted pillar pattern mov eax, px and eax, 15 cmp eax, 8 jl set_pillar_light mov color, 00408090h ; Dark turquoise jmp write_pillar_pixel set_pillar_light: mov color, 0070B0C0h ; Light turquoise write_pillar_pixel: mov eax, py shl eax, 7 add eax, px shl eax, 2 mov edi, texBase add edi, eax mov edx, color mov [edi], edx inc px cmp px, TEX_W jl pillar_x_loop inc py cmp py, TEX_H jl pillar_y_loop ; -------------------------------------------------------------------------- ; Texture 8: Glass (framed pane with diagonal shine) ; -------------------------------------------------------------------------- mov eax, OFFSET textureBuffer add eax, 8 * TEX_SIZE_BYTES mov texBase, eax mov py, 0 glass_y_loop: mov px, 0 glass_x_loop: ; Base: dark blue-green tinted glass mov color, 00403020h ; Metal frame (outer 6 pixels) mov eax, px cmp eax, 6 jl set_glass_frame cmp eax, 122 jge set_glass_frame mov eax, py cmp eax, 6 jl set_glass_frame cmp eax, 122 jge set_glass_frame ; Diagonal shine streaks: (px + py) mod 64 in [0..3] or [24..27] mov eax, px add eax, py and eax, 63 cmp eax, 4 jl set_glass_shine cmp eax, 24 jl write_glass_pixel cmp eax, 28 jl set_glass_shine jmp write_glass_pixel set_glass_frame: mov color, 00606060h ; Steel frame jmp write_glass_pixel set_glass_shine: mov color, 00907050h ; Bright reflection streak write_glass_pixel: mov eax, py shl eax, 7 add eax, px shl eax, 2 mov edi, texBase add edi, eax mov edx, color mov [edi], edx inc px cmp px, TEX_W jl glass_x_loop inc py cmp py, TEX_H jl glass_y_loop ; -------------------------------------------------------------------------- ; Texture 9: Marble (cream slab with dark veins) ; -------------------------------------------------------------------------- mov eax, OFFSET textureBuffer add eax, 9 * TEX_SIZE_BYTES mov texBase, eax mov py, 0 marble_y_loop: mov px, 0 marble_x_loop: ; Base: cream marble mov color, 00D8D0C0h ; Veins: wandering pseudo-noise lines mov eax, px imul eax, 7 mov edx, py imul edx, 13 add eax, edx mov edx, eax shr edx, 3 add eax, edx and eax, 63 cmp eax, 2 jbe set_marble_vein cmp eax, 40 jne marble_polish ; Single-pixel hairline vein jmp set_marble_vein marble_polish: ; Subtle polish variation mov eax, px xor eax, py and eax, 3 add color, eax jmp write_marble_pixel set_marble_vein: mov color, 00555555h ; Dark gray vein write_marble_pixel: mov eax, py shl eax, 7 add eax, px shl eax, 2 mov edi, texBase add edi, eax mov edx, color mov [edi], edx inc px cmp px, TEX_W jl marble_x_loop inc py cmp py, TEX_H jl marble_y_loop ret GenerateDefaultTextures ENDP ; ------------------------------------------------------------------------------ ; LoadTexturePack: Optionally overrides procedural textures with ; assets/textures/texturepack.bin (see tools/make_texturepack.py). ; Layout: dd magic 'EBTX', dw version (1), dw slotCount, ; then slotCount * 65536 bytes (128x128 BGRA per slot, slot 0 first). ; Returns: eax = 1 if pack loaded, 0 if procedural textures stay active. ; ------------------------------------------------------------------------------ LoadTexturePack PROC uses ebx ecx edx esi edi LOCAL hFile:DWORD LOCAL bytesRead:DWORD LOCAL magic:DWORD, pkVersion:DWORD, slotCount:DWORD invoke CreateFileA, OFFSET szTexPackPath, GENERIC_READ, FILE_SHARE_READ,\ 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 mov hFile, eax cmp hFile, INVALID_HANDLE_VALUE je pack_fail ; Read 8-byte header (dd magic, dw version, dw slotCount) invoke ReadFile, hFile, ADDR magic, 4, ADDR bytesRead, 0 test eax, eax jz pack_close_fail cmp bytesRead, 4 jl pack_close_fail cmp magic, TEXPACK_MAGIC jne pack_close_fail invoke ReadFile, hFile, ADDR pkVersion, 2, ADDR bytesRead, 0 cmp bytesRead, 2 jl pack_close_fail cmp pkVersion, 1 jne pack_close_fail invoke ReadFile, hFile, ADDR slotCount, 2, ADDR bytesRead, 0 cmp bytesRead, 2 jl pack_close_fail ; Clamp slot count to engine capacity mov eax, slotCount and eax, 0FFFFh cmp eax, MAX_TEXTURES jle @F mov eax, MAX_TEXTURES @@: mov slotCount, eax test eax, eax jz pack_close_fail ; Read slotCount * TEX_SIZE_BYTES pixels straight into textureBuffer mov ecx, slotCount shl ecx, 16 ; * 65536 invoke ReadFile, hFile, OFFSET textureBuffer, ecx, ADDR bytesRead, 0 test eax, eax jz pack_close_fail mov eax, slotCount shl eax, 16 cmp bytesRead, eax jne pack_close_fail invoke CloseHandle, hFile mov texPackLoaded, 1 mov eax, 1 ret pack_close_fail: invoke CloseHandle, hFile pack_fail: xor eax, eax ret LoadTexturePack ENDP