Sequence studio, texture AI disclosure and MASM code comparison before arrival. Show a typed hall briefing after admission. Start the jukebox at 50% user volume on hall entry. Apply positional gain before playback to avoid a full-volume startup burst.
358 lines
9.1 KiB
PHP
358 lines
9.1 KiB
PHP
; Native-pixel, CP1251 bitmap text. Count includes newlines for typewriter timing.
|
|
; Unlike DrawString8x8's 320x240 coordinates, this uses the full 640x480 frame.
|
|
PresentationText3D PROC uses esi edi ebx x:DWORD,y:DWORD,text:DWORD,ink:DWORD,scale:DWORD,limit:DWORD
|
|
local px:DWORD,py:DWORD,row:DWORD,col:DWORD,bits:DWORD,repeatY:DWORD,repeatX:DWORD
|
|
mov esi,text
|
|
mov eax,x
|
|
mov px,eax
|
|
mov eax,y
|
|
mov py,eax
|
|
pres_text_char:
|
|
cmp limit,0
|
|
je pres_text_done
|
|
movzx eax,BYTE PTR [esi]
|
|
test eax,eax
|
|
jz pres_text_done
|
|
inc esi
|
|
dec limit
|
|
cmp eax,10
|
|
jne pres_text_glyph
|
|
mov eax,x
|
|
mov px,eax
|
|
mov eax,scale
|
|
imul eax,11
|
|
add py,eax
|
|
jmp pres_text_char
|
|
pres_text_glyph:
|
|
lea edi,font8x8[eax*8]
|
|
mov row,0
|
|
pres_text_row:
|
|
mov eax,row
|
|
movzx ebx,BYTE PTR [edi+eax]
|
|
mov bits,ebx
|
|
mov col,0
|
|
pres_text_col:
|
|
test bits,80h
|
|
jz pres_text_next_col
|
|
mov repeatY,0
|
|
pres_text_repeat_y:
|
|
mov eax,row
|
|
imul eax,scale
|
|
add eax,py
|
|
add eax,repeatY
|
|
cmp eax,SCREEN_H
|
|
jae pres_text_next_y
|
|
imul eax,SCREEN_W
|
|
mov ebx,eax
|
|
mov repeatX,0
|
|
pres_text_repeat_x:
|
|
mov eax,col
|
|
imul eax,scale
|
|
add eax,px
|
|
add eax,repeatX
|
|
cmp eax,SCREEN_W
|
|
jae pres_text_next_x
|
|
add eax,ebx
|
|
mov edx,ink
|
|
mov screenBuffer[eax*4],edx
|
|
pres_text_next_x:
|
|
inc repeatX
|
|
mov eax,repeatX
|
|
cmp eax,scale
|
|
jb pres_text_repeat_x
|
|
pres_text_next_y:
|
|
inc repeatY
|
|
mov eax,repeatY
|
|
cmp eax,scale
|
|
jb pres_text_repeat_y
|
|
pres_text_next_col:
|
|
shl bits,1
|
|
inc col
|
|
cmp col,8
|
|
jb pres_text_col
|
|
inc row
|
|
cmp row,8
|
|
jb pres_text_row
|
|
mov eax,scale
|
|
shl eax,3
|
|
add px,eax
|
|
jmp pres_text_char
|
|
pres_text_done:
|
|
ret
|
|
PresentationText3D ENDP
|
|
|
|
RenderStartupNotice3D PROC uses ebx esi edi
|
|
local lineY:DWORD,ink:DWORD
|
|
invoke DrawBox,0,0,320,240,00060912h
|
|
; Quiet terminal grid, fixed geometry: never consumes gameplay RNG.
|
|
mov ebx,12
|
|
pres_notice_grid:
|
|
invoke DrawBox,0,ebx,320,1,000C1722h
|
|
add ebx,16
|
|
cmp ebx,240
|
|
jb pres_notice_grid
|
|
invoke DrawBox,20,26,3,22,00FFCE54h
|
|
invoke DrawBox,26,26,274,1,002C6875h
|
|
invoke DrawBox,20,212,280,1,002C6875h
|
|
cmp startupPage3D,STARTUP_AI
|
|
jne pres_notice_code
|
|
invoke PresentationText3D,56,60,OFFSET presAITag,004FE5E2h,1,-1
|
|
invoke PresentationText3D,56,88,OFFSET presAIHeader,00FFDF82h,2,-1
|
|
invoke PresentationText3D,40,156,OFFSET presAIBody,00CFDCE4h,2,-1
|
|
invoke PresentationText3D,56,378,OFFSET presAIFooter,004FE5E2h,1,-1
|
|
jmp pres_notice_footer
|
|
pres_notice_code:
|
|
invoke PresentationText3D,56,64,OFFSET presCodeHeader,00FFDF82h,2,-1
|
|
invoke PresentationText3D,40,112,OFFSET presCodeSub,00CFDCE4h,2,-1
|
|
invoke DrawBoxBorder,12,80,144,90,00080F1Bh,002D7C92h,1
|
|
invoke DrawBoxBorder,164,80,144,90,00080F1Bh,003BE8CAh,1
|
|
invoke DrawBox,13,81,142,14,0017283Ch
|
|
invoke DrawBox,165,81,142,14,00143435h
|
|
invoke PresentationText3D,36,170,OFFSET presCodeLeft,00D0DDEBh,1,-1
|
|
invoke PresentationText3D,340,170,OFFSET presCodeRight,0062F3D3h,1,-1
|
|
mov esi,0
|
|
mov lineY,204
|
|
pres_code_line:
|
|
mov ink,00C9D9E8h
|
|
cmp esi,0
|
|
jne @F
|
|
mov ink,00657D92h
|
|
@@:
|
|
invoke PresentationText3D,36,lineY,presCppLines[esi*4],ink,1,-1
|
|
invoke PresentationText3D,340,lineY,presAsmLines[esi*4],ink,1,-1
|
|
add lineY,17
|
|
inc esi
|
|
cmp esi,7
|
|
jb pres_code_line
|
|
invoke PresentationText3D,24,356,OFFSET presCodeCaption,00FFDF82h,2,-1
|
|
invoke PresentationText3D,40,386,OFFSET presCodeNote,009FB8C8h,1,-1
|
|
pres_notice_footer:
|
|
invoke PresentationText3D,40,448,OFFSET presNext,006F939Fh,1,-1
|
|
; Fade the notice in, then out at its own page boundary.
|
|
mov eax,startupElapsed3D
|
|
cmp eax,300
|
|
jae pres_notice_fade_out
|
|
shl eax,8
|
|
xor edx,edx
|
|
mov ecx,300
|
|
div ecx
|
|
invoke FadeCityFrame3D,eax
|
|
ret
|
|
pres_notice_fade_out:
|
|
mov ecx,startupPage3D
|
|
mov ebx,startupDurations3D[ecx*4]
|
|
sub ebx,400
|
|
cmp eax,ebx
|
|
jb pres_notice_done
|
|
sub eax,ebx
|
|
cmp eax,400
|
|
jbe @F
|
|
mov eax,400
|
|
@@:
|
|
shl eax,8
|
|
xor edx,edx
|
|
mov ecx,400
|
|
div ecx
|
|
neg eax
|
|
add eax,256
|
|
invoke FadeCityFrame3D,eax
|
|
pres_notice_done:
|
|
ret
|
|
RenderStartupNotice3D ENDP
|
|
|
|
BeginWelcome3D PROC
|
|
mov welcomeActive3D,1
|
|
mov welcomeElapsed3D,0
|
|
mov welcomeChars3D,0
|
|
mov paused3D,0
|
|
mov interactTargetId,0
|
|
mov interactPromptPtr,0
|
|
call ClearKeys3D
|
|
call UnlockMouse3D
|
|
ret
|
|
BeginWelcome3D ENDP
|
|
|
|
CloseWelcome3D PROC
|
|
mov welcomeActive3D,0
|
|
mov paused3D,0
|
|
call ClearKeys3D
|
|
ret
|
|
CloseWelcome3D ENDP
|
|
|
|
HandleWelcome3D PROC
|
|
cmp welcomeActive3D,0
|
|
je welcome_handle_done
|
|
mov eax,deltaTime3D
|
|
add welcomeElapsed3D,eax
|
|
cmp welcomeElapsed3D,WELCOME_OPEN_MS
|
|
jb welcome_handle_done
|
|
; Once manually completed, do not rewind the typewriter on the next frame.
|
|
cmp welcomeChars3D,welcomeTextLength3D
|
|
jae welcome_input
|
|
mov eax,welcomeElapsed3D
|
|
sub eax,WELCOME_OPEN_MS
|
|
xor edx,edx
|
|
mov ecx,WELCOME_CHAR_MS
|
|
div ecx
|
|
cmp eax,welcomeTextLength3D
|
|
jbe @F
|
|
mov eax,welcomeTextLength3D
|
|
@@:
|
|
mov welcomeChars3D,eax
|
|
welcome_input:
|
|
invoke Pressed3D,0Dh
|
|
test eax,eax
|
|
jnz welcome_confirm
|
|
invoke Pressed3D,20h
|
|
test eax,eax
|
|
jnz welcome_confirm
|
|
cmp mouseClick3D,0
|
|
je welcome_handle_done
|
|
cmp mouseX3D,212
|
|
jb welcome_handle_done
|
|
cmp mouseX3D,292
|
|
jae welcome_handle_done
|
|
cmp mouseY3D,184
|
|
jb welcome_handle_done
|
|
cmp mouseY3D,198
|
|
jae welcome_handle_done
|
|
welcome_confirm:
|
|
cmp welcomeChars3D,welcomeTextLength3D
|
|
jae welcome_close
|
|
mov welcomeChars3D,welcomeTextLength3D
|
|
call ClearKeys3D
|
|
ret
|
|
welcome_close:
|
|
call CloseWelcome3D
|
|
welcome_handle_done:
|
|
ret
|
|
HandleWelcome3D ENDP
|
|
|
|
RenderWelcomeScene3D PROC
|
|
; Frozen playable hall, not a replacement screenshot or second game runtime.
|
|
call UpdateCamera3D
|
|
call RenderCeilingAndFloor
|
|
call RenderWalls
|
|
call PrepareCityDepth3D
|
|
call RenderSprites
|
|
call RenderHall3D
|
|
call RenderHUD
|
|
call RenderWelcome3D
|
|
ret
|
|
RenderWelcomeScene3D ENDP
|
|
|
|
RenderWelcome3D PROC uses ebx esi edi
|
|
local halfW:DWORD,halfH:DWORD,left:DWORD,top:DWORD,wide:DWORD,panelH:DWORD
|
|
local cursorX:DWORD,cursorY:DWORD
|
|
cmp welcomeActive3D,0
|
|
je welcome_render_done
|
|
invoke FadeCityFrame3D,90
|
|
; Two-stage deployment: point -> horizontal line -> centred panel.
|
|
mov eax,welcomeElapsed3D
|
|
cmp eax,200
|
|
jae welcome_open_vertical
|
|
imul eax,140
|
|
xor edx,edx
|
|
mov ecx,200
|
|
div ecx
|
|
inc eax
|
|
mov halfW,eax
|
|
mov halfH,1
|
|
jmp welcome_panel_bounds
|
|
welcome_open_vertical:
|
|
mov halfW,140
|
|
sub eax,200
|
|
cmp eax,400
|
|
jbe @F
|
|
mov eax,400
|
|
@@:
|
|
; Ease-out quadratic: 1 - (1-t)^2, with bounded integer operands.
|
|
neg eax
|
|
add eax,400
|
|
imul eax,eax
|
|
imul eax,81
|
|
xor edx,edx
|
|
mov ecx,160000
|
|
div ecx
|
|
neg eax
|
|
add eax,82
|
|
mov halfH,eax
|
|
welcome_panel_bounds:
|
|
mov eax,160
|
|
sub eax,halfW
|
|
mov left,eax
|
|
mov eax,120
|
|
sub eax,halfH
|
|
mov top,eax
|
|
mov eax,halfW
|
|
shl eax,1
|
|
mov wide,eax
|
|
mov eax,halfH
|
|
shl eax,1
|
|
mov panelH,eax
|
|
invoke DrawBoxBorder,left,top,wide,panelH,0008101Bh,003EE7D8h,1
|
|
mov eax,left
|
|
add eax,wide
|
|
sub eax,2
|
|
invoke DrawBox,eax,top,2,panelH,00DC4B9Bh
|
|
cmp welcomeElapsed3D,WELCOME_OPEN_MS
|
|
jb welcome_render_done
|
|
; Chamfered corners, offset signal rails and a narrow animated scan line.
|
|
invoke DrawBox,20,38,4,4,0008101Bh
|
|
invoke DrawBox,296,198,4,4,0008101Bh
|
|
invoke DrawBox,24,34,46,2,003EE7D8h
|
|
invoke DrawBox,250,205,46,2,00DC4B9Bh
|
|
invoke DrawBox,30,70,260,1,00284E62h
|
|
invoke DrawBox,30,180,260,1,00284E62h
|
|
mov eax,welcomeElapsed3D
|
|
shr eax,5
|
|
xor edx,edx
|
|
mov ecx,100
|
|
div ecx
|
|
add edx,76
|
|
invoke DrawBox,22,edx,1,2,0058FFF0h
|
|
invoke PresentationText3D,60,90,OFFSET welcomeHeader,00FFE29Ah,2,-1
|
|
invoke PresentationText3D,60,120,OFFSET welcomeTag,006C9EB0h,1,-1
|
|
invoke PresentationText3D,60,154,OFFSET welcomeBody,00CDE9E8h,1,welcomeChars3D
|
|
cmp welcomeChars3D,welcomeTextLength3D
|
|
jae welcome_cursor_done
|
|
test welcomeElapsed3D,100h
|
|
jnz welcome_cursor_done
|
|
mov cursorX,60
|
|
mov cursorY,154
|
|
mov esi,OFFSET welcomeBody
|
|
mov edi,welcomeChars3D
|
|
welcome_cursor_scan:
|
|
test edi,edi
|
|
jz welcome_cursor_draw
|
|
cmp BYTE PTR [esi],10
|
|
jne welcome_cursor_column
|
|
mov cursorX,60
|
|
add cursorY,11
|
|
jmp welcome_cursor_next
|
|
welcome_cursor_column:
|
|
add cursorX,8
|
|
welcome_cursor_next:
|
|
inc esi
|
|
dec edi
|
|
jmp welcome_cursor_scan
|
|
welcome_cursor_draw:
|
|
invoke PresentationText3D,cursorX,cursorY,OFFSET welcomeCursor3D,0058FFF0h,1,1
|
|
welcome_cursor_done:
|
|
; Blinking activity indicator; no random flicker and no gameplay RNG changes.
|
|
mov eax,welcomeElapsed3D
|
|
test eax,200h
|
|
jnz @F
|
|
invoke DrawBox,280,49,7,2,0058FFF0h
|
|
@@:
|
|
invoke DrawBoxBorder,212,184,80,14,00172A38h,003EE7D8h,1
|
|
invoke PresentationText3D,436,376,OFFSET welcomeButton,006EF4DEh,1,-1
|
|
mov eax,OFFSET welcomeTypeHint
|
|
cmp welcomeChars3D,welcomeTextLength3D
|
|
jb @F
|
|
mov eax,OFFSET welcomeDoneHint
|
|
@@:
|
|
invoke PresentationText3D,60,380,eax,008EAFBEh,1,-1
|
|
welcome_render_done:
|
|
ret
|
|
RenderWelcome3D ENDP
|