; Windowless renderer used by EblanStudio. Same Render3DScene and overlays as game. ; Fixed wire layout is mirrored by editor/src/preview_protocol.h. .data previewHandle dd 0 previewMemory dd 0 previewParent dd 0 previewTextureRevision dd -1 .code TryEnginePreview PROC uses ebx ecx edx esi edi mov esi, OFFSET startupMapPath mov edi, OFFSET previewPrefix mov ecx, 10 repe cmpsb jne preview_not_requested invoke OpenFileMappingA, 6, 0, esi ; FILE_MAP_READ | FILE_MAP_WRITE test eax, eax jz preview_exit_error mov previewHandle, eax invoke MapViewOfFile, eax, 6, 0, 0, 1357792 test eax, eax jz preview_exit_error mov previewMemory, eax mov ebx, eax cmp DWORD PTR [ebx], 56504245h jne preview_exit_error cmp DWORD PTR [ebx+4], 1 jne preview_exit_error invoke OpenProcess, 00100000h, 0, DWORD PTR [ebx+12] ; SYNCHRONIZE test eax, eax jz preview_exit_error mov previewParent, eax call InitMathTables call GenerateDefaultTextures preview_wait: invoke WaitForSingleObject, previewParent, 0 test eax, eax jz preview_exit_ok mov ebx, previewMemory cmp DWORD PTR [ebx+8], 3 je preview_exit_ok cmp DWORD PTR [ebx+8], 1 je preview_render invoke Sleep, 1 jmp preview_wait preview_render: ; Treat IPC as untrusted: bounds before touching engine buffers. mov eax, [ebx+16] cmp eax, 2048 jae preview_exit_error mov playerX, eax mov eax, [ebx+20] cmp eax, 2048 jae preview_exit_error mov playerY, eax mov eax, [ebx+24] and eax, 511 mov playerAngle, eax mov eax, [ebx+28] mov mapCeilingColor, eax mov eax, [ebx+32] mov mapFloorColor, eax mov eax, [ebx+36] cmp eax, MAX_SPRITES ja preview_exit_error mov spriteCount, eax lea esi, [ebx+128] mov edi, OFFSET gameMap mov ecx, 1024/4 rep movsd push esi mov esi, OFFSET gameMap mov ecx, MAP_SIZE preview_cell_check: lodsb cmp al, 15 ja preview_exit_error loop preview_cell_check pop esi mov edi, OFFSET spriteList mov ecx, 32*sizeof SpriteStruct/4 rep movsd ; Validate every sprite, including unsaved inspector edits. mov esi, OFFSET spriteList mov ecx, spriteCount preview_sprite_check: test ecx, ecx jz preview_textures cmp DWORD PTR [esi].SpriteStruct.textureId, MAX_TEXTURES jae preview_exit_error cmp DWORD PTR [esi].SpriteStruct.x, 2048 jae preview_exit_error cmp DWORD PTR [esi].SpriteStruct.y, 2048 jae preview_exit_error cmp DWORD PTR [esi].SpriteStruct.scale, 1048576 ja preview_exit_error add esi, sizeof SpriteStruct dec ecx jmp preview_sprite_check preview_textures: mov eax, [ebx+48] cmp eax, previewTextureRevision je preview_scene mov previewTextureRevision, eax lea esi, [ebx+2016] mov edi, OFFSET textureBuffer mov ecx, MAX_TEXTURES*TEX_SIZE_BYTES/4 rep movsd preview_scene: call Render3DScene mov ebx, previewMemory cmp DWORD PTR [ebx+40], 0 je preview_copy_frame mov cutsceneSubtitle, -1 cmp BYTE PTR [ebx+1920], 0 je preview_overlay lea esi, [ebx+1920] mov edi, OFFSET cutsceneStrings mov ecx, 96/4 rep movsd mov BYTE PTR [cutsceneStrings+95], 0 mov cutsceneStringCount, 1 mov cutsceneSubtitle, 0 preview_overlay: call RenderCutsceneOverlay mov ebx, previewMemory mov eax, [ebx+44] cmp eax, 16 ja preview_exit_error mov cutsceneFade, eax call ApplyCutsceneFade preview_copy_frame: mov esi, OFFSET screenBuffer mov ebx, previewMemory lea edi, [ebx+1050592] mov ecx, FRAME_BUFFER_SIZE/4 rep movsd mov eax, 2 xchg eax, [ebx+8] ; Publish complete frame (full memory barrier). jmp preview_wait preview_exit_ok: invoke UnmapViewOfFile, previewMemory invoke CloseHandle, previewParent invoke CloseHandle, previewHandle invoke ExitProcess, 0 preview_exit_error: invoke ExitProcess, 2 preview_not_requested: ret TryEnginePreview ENDP