
    UHjk@              	         d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
mZ ddlmZ  ee      j                         j                   d   Zedz  Zed	z  Zd
ZddgZdZdZdZdZdZdZdZdZdZdZddddddZ dddd d!d"d#d$d%Z!dd&d'd(Z"d6d)Z#d7d*Z$d8d+Z%d8d,Z&d8d-Z'd9d.Z(d:d/Z)edfd;d0Z*d<d1Z+d<d2Z,efd=d3Z-d>d4Z.e/d5k(  r e.        yy)?zKSummarize the original executable's DirectDraw setup and presentation flow.    )annotationsN)Path)read_sectionsva_to_offset)parse_imports   outzHwanse2.exei]C iVA iVA ivF ivF ivF ivF ivF ivF ivF ivF ivF iثU CreateClipperCreatePaletteCreateSurfaceSetCooperativeLevelSetDisplayMode)         P   T   ReleaseBltFastBltBltBatchFlipGetAttachedSurface
SetClipper
SetPalette)   r   r   r   ,   0   p   |   
GetEntries
SetEntries)r   r   r   c                    | y d| dS )N0x08x )values    6/home/exedev/hwanse/tools/summarize_directdraw_flow.pyhex32r)   :   s    }c{    c                ^    t        ||      }|t        dt        |       d      | |||z    S )NzVA z is outside raw sections)r   
ValueErrorr)   )exesectionsvasizeoffsets        r(   read_atr2   @   s=    (B'F~3uRyk)ABCCv&&r*   c                $    t        | ||d      d   S )Nr   r   )r2   )r-   r.   r/   s      r(   read_u8r4   G   s    3"a(++r*   c           	         t        | ||      }|dk7  rt        dt        |             t        j                  dt        | ||dz   d            d   }|dz   |z   S )N   zexpected near call at z<ir      r      )r4   r,   r)   structunpackr2   )r-   r.   r/   opcoderels        r(   rel32_targetr=   K   s`    S(B'F~1%)=>>
--gc8R!VQ?
@
CC6C<r*   c                f    t        | ||d      }|d d dk7  rt        dt        |             |d   S )N      s   Pz&expected call DWORD PTR [eax+imm8] at )r2   r,   r)   )r-   r.   r/   bodys       r(   vtable_call_offsetrB   S   s@    3"a(DBQx;A%)MNN7Nr*   c                    | j                  d      xs g D ]I  }|j                  d      xs g D ]/  }|j                  d      |k(  sd|j                  d      i|c c S  K t        d| d      )Nimports	functionsnamedllzimport z
 not found)getr,   )rD   rF   rG   fns       r(   find_importrJ   Z   sz    {{9%+ 5''+&," 	5Bvvf~%swwu~444	55 wtfJ/
00r*   c                   g d}t         t        t        ddid}g }|D ]c  \  }}}}}	t        | ||      }
|j	                  t        |      |d|
dd|d|j                  |i       j                  |
d      ||	|
|k(  d       e |S )	N))i`VA IDirectDrawr   z$windowed cooperative level candidatezflags 0x00000008)iVA rL   r   z&exclusive fullscreen cooperative levelzflags 0x00000011)iVA rL   r   zfullscreen display mode	640x480x8)ifWA rL   r   z"primary flipping surface candidatez*DDSD_CAPS|DDSD_BACKBUFFERCOUNT, caps 0x218)iWA rL   r   z simple primary surface candidatezDDSD_CAPS, caps 0x200)i6XA IDirectDrawSurfacer   attached backbuffer lookupcaps 0x00000004)iXA rL   r   #offscreen 640x480 surface candidate)DDSD_CAPS|HEIGHT|WIDTH, caps include 0x40)ioYA rN   r   rO   rP   )iZA rL   r   rQ   rR   )iZA rL   r   zwindowed clipper creationzout 0x004676c8)iZA IDirectDrawClipper    zclipper SetHWnd candidatezhwnd 0x004676f0)i[A rN   r   zprimary SetClipper candidatezclipper 0x004676c8)i.eA rL   r   zpalette creationz256-entry palette buffer)iUeA rN   r    zprimary SetPalettepalette 0x004676c4)ifA rN   r    zrefresh primary SetPaletterU   )iIfA IDirectDrawPaletter   r"   writes changed palette range)igA rV   r   r"   rW   )iVhA rV   r   r!   zreads palette range)ivA rN   r   r   zfullscreen/page-flip path)i"wA rN   r   r   copy/update path)iKxA rN   r   r   rX   )i8yA rN   r   r   rX   )iK{A rN   r   r   windowed/scaled copy path)i{A rN   r   r   rY   )i{A rN   r   r   rY   rT   SetHWnd)rL   rN   rV   rS   r$   02xunknown)vaHex	interfacevtableOffsetHexexpectedOffsetHexmethodrolenotesverified)DDRAW_METHODSSURFACE_METHODSPALETTE_METHODSrB   appendr)   rH   )r-   r.   rowsmethodsoutputr/   r^   expected_offsetrb   rc   actual_offsets              r(   known_vtable_callsrn   b   s    D8 %--#Y/	G F7; 
3Ie*3"=r&%'c':#;')/#)>%?!++i488	R)_<		

 Mr*   c                F   | j                         }t        |      }|xs t        |       }t        |d      }t        D cg c]  }t        |||       }}t        ||      }t        ||dd      j                  d      t        ||dd      j                  d      t        ||dd      j                  d      d}	t        ||d	d      j                  d      t        ||d
d      j                  d      d}
|j                  d      dk(  t        d |D              t        ||dd      dk(  t        ||dd      dk(  |	d   dk(  xr |	d   dk(  xr |	d   dk(  |
d   dk(  xr |
d   dk(  t        d |D              t        d |D              d k\  t        d! |D              xr t        d" |D              d#	}t        |       |j                  d$      t        |j                  d            t        t              t        D cg c]  }t        |       c}|D cg c]  }t        |       c}t        t               t        t"              t        t$              t        t&              t        t(              d%
|D cg c]  }|d&   d'k(  s| c}t+        d( |D              d)d*d+|	d,t        t,              d-d.d/d0d1d2d3d0d4d5d6d0g|D cg c]  }|d&   d7k(  s| c}|D cg c]  }|d8   d9k(  r
|d&   d:k7  r| c}d;t        t.              t        t0              t        t2              d<|
|D cg c]  }|d&   d=v r| c}d>d?|D cg c]  }|d&   d@k(  s| c}|D cg c]  }|d&   dAk(  s| c}dBdC||dDg dEdF
}|S c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w )GNDirectDrawCreateiVA r@    iVA r8   iVA )bppPush
heightPush	widthPushiX\A ib\A    )versionWrite
countWriteiatVaitZ c              3  .   K   | ]  }|t         k(    y w)N)DIRECTDRAW_CREATE_WRAPPER).0targets     r(   	<genexpr>z build_summary.<locals>.<genexpr>   s     0pY_;T1T0p   iUA s   hvF iVA s   jrr   z6a 08rs   z68 e0 01 00 00rt   z68 80 02 00 00rv   z66 c7 00 00 03rw   z66 c7 40 02 00 01c              3  &   K   | ]	  }|d      yw)rd   Nr&   r{   rows     r(   r}   z build_summary.<locals>.<genexpr>   s     )Rc#j/)R   c              3  2   K   | ]  }|d    dk(  sd  yw)ra   r   r   Nr&   r   s     r(   r}   z build_summary.<locals>.<genexpr>   s     -lC3x=\kKka-l   r7   c              3  ,   K   | ]  }|d    dk(    yw)ra   r   Nr&   r   s     r(   r}   z build_summary.<locals>.<genexpr>   s     @CH'@   c              3  ,   K   | ]  }|d    dk(    yw)ra   r   Nr&   r   s     r(   r}   z build_summary.<locals>.<genexpr>   s     CsCMU*Cr   )	directDrawCreateImportMatches!directDrawCreateCallsReachWrapperdirectDrawOutputGlobalMatcheshardwareDeviceBranchPushes2displayModeIs640x480x8paletteHeaderIs256EntriesallKnownVtableOffsetsMatchcreateSurfaceCallCountAtLeast4presentationHasFlipAndBltrG   )
rG   iatVaHexwrapperVaHex	callSitescallTargetsoutputGlobalHexerrorGlobalHexflagGlobalHexdisplayModeGlobalHexhwndGlobalHexra   r   c              3  2   K   | ]  }|d    dk(  s|  yw)ra   r   Nr&   r   s     r(   r}   z build_summary.<locals>.<genexpr>   s     &hsc(mWgFgs&hr   i  i  r   )setCooperativeLevelCallssetDisplayModeCallwidthheightbppbytesr   
0x0055abd8zprimary/front surface wrapper)slotwrapperGlobalHexrb   r   
0x0055abdczoffscreen/back surface wrapper   
0x0055aed4zattached backbuffer wrapperr   r^   rN   r   )surfaceTableBaseHexprimarySurfaceSlotscreateSurfaceCallssurfaceCallSamples   >   r!   r"   r   r   )paletteGlobalHexbufferGlobalHexentriesGlobalHex
entryCountheaderBytescallsz&directdraw-640x480x8-paletted-surfacesr   r   zThe web runtime should preserve 640x480 indexed-image assumptions, then present through canvas scaling rather than inventing a higher-resolution native layout.)classification	flipCallsbltCallsimplicationzrender-pipeline-grounded)zQExact draw-order and dirty-rectangle rules still require deeper renderer tracing.zThe static vtable labels assume DirectDraw 1 era COM layouts, which match the import shape but are not symbol names from the binary.z:Event and route promotion are not affected by this report.)
sourcedirectDrawCreatedisplayModesurfacespalettepresentationvtableCallsverificationpromotionStatusopenQuestions)
read_bytesr   r   rJ   DIRECTDRAW_CREATE_CALLSr=   rn   r2   hexrH   allsumanystrr)   rz   DIRECTDRAW_GLOBALERROR_GLOBALFLAGS_GLOBALDISPLAY_MODE_GLOBALHWND_GLOBALnextSURFACE_TABLEPALETTE_GLOBALPALETTE_BUFFER_GLOBALPALETTE_ENTRIES_GLOBAL)exe_pathexe_importsr-   r.   rD   directdraw_creater/   call_targetsvtable_callsdisplay_mode_bytespalette_header_bytesr   r|   r   summarys                  r(   build_summaryr      s   



CS!H4]84G#G-?@>UVLh3VLV%c84L3*a8<<SAc8Z;??DS(J:>>sC  Xz1=AA#Fc8Z;??D
 *;)>)>w)G:)U-00pco0p-p)0h
A)NRi)i'.sHj!'LP['[y)W4 D"<04DDD";/3CC !04DD J$\26II&))R\)R&R*--l<-l*lpq*q@<@@ DClCC%L, h-$((//33G<=!";<.EF%)F8DEfE&ME$%67#L1"<0$)*=$>";/
  ,)s8}@U/U) #'&hl&h"h'	
 $)#7FefFfg<Ifg$  ,#s8}/O#
 (#{#';;HQ]@] #
" !&n 5$%:; %&< =/ (x=$__ 
 G)5Q#X&9P#Q(4OH8NO }	
 $$5
{BGF NG WL GE) ## ROsM   M69M;N 1N?N>N
N
N#N<N
NN"Nc                   ddd| d    dd| d    ddddd	| d
   d    dd| d
   d    dddj                  d | d
   d   D               d| d
   d    dd| d
   d    d| d
   d    d| d
   d    ddddddd| d   d    d| d   d     d| d   d!    dd"| d   d#   d$    ddd%d&g}| d   d'   D ]&  }|j                  d(|d$    d)|d*    d+|d,    d-       ( |j                  d(| d   d#   d$    d.       |j                  dd/dd0| d1   d2    d3dd4d5g       | d1   d6   D ]&  }|j                  d7|d8    d9|d:    d+|d;    d-       ( |j                  g d<       | d1   d=   D ],  }|j                  d(|d$    d)|d*    d+|d;    d>|d,    d-	       . |j                  dd?dd@| dA   dB    dC| dA   dD    dEddFdGg       | dA   dH   D ],  }|j                  d(|d$    d)|d*    d+|d;    d>|d,    d-	       . |j                  ddIddJ| dK   dL    ddMdj                  dN | dK   dO   D              xs dP dQdj                  dR | dK   dS   D              xs dP dT| dK   dU    ddVddWdXg       | dY   j                         D ]  \  }}|j                  d(| d)| dZ        |j                  g d[       |j                  d\ | d]   D               d^j                  |      d^z   S )_Nz# DirectDraw Flow zExecutable: `r   `zPromotion status: `r   z## Import And Entryz- `DirectDrawCreate` IAT: `r   r   z- import thunk/wrapper: `r   z- call sites: z, c              3  (   K   | ]
  }d | d   yw)r   Nr&   r{   items     r(   r}   ztext_summary.<locals>.<genexpr>  s     "d4QtfA;"ds   r   z- output global: `r   z%- mode/window globals: display mode `r   z	`, hwnd `r   z
`, flags `r   zThe two call sites pass either device selector `0` or `2` based on the graphics flag at `0x004676d4`, then store the created `IDirectDraw*` in `0x004676c0`.z## Display Modez- target mode: `r   r   xr   r   z- `SetDisplayMode` call: `r   r]   z| call | method | notes |z| --- | --- | --- |r   z| `z` | `ra   z` | rc   z |z"` | `SetDisplayMode` | 640x480x8 |z## Surfacesz#Surface wrappers are indexed from `r   r   z`. The initialization path creates a primary/front wrapper, an offscreen/back wrapper, and in fullscreen flip mode an attached backbuffer wrapper.z| slot | wrapper | role |z| ---: | --- | --- |r   z| r   z | `r   rb   )r    | call | method | role | notes || --- | --- | --- | --- |r   z | z
## PalettezThe palette buffer at `r   r   zC` stores a 256-entry DirectDraw palette; the raw entries start at `r   z`.r   r   r   z## Presentationz- classification: `r   r   z- flip calls: c              3  .   K   | ]  }d |d    d   ywr   r]   Nr&   r   s     r(   r}   ztext_summary.<locals>.<genexpr>=  s     "g3Qs7|nA#6"gr~   r   -z- blt calls: c              3  .   K   | ]  }d |d    d   ywr   r&   r   s     r(   r}   ztext_summary.<locals>.<genexpr>>  s     !e#Ac'l^1"5!er~   r   z- implication: r   z## Verificationz| check | value |z| --- | --- |r   z` |)r   z## Open Questionsr   c              3  &   K   | ]	  }d |   yw)z- Nr&   r   s     r(   r}   ztext_summary.<locals>.<genexpr>M  s     B2dVBr   r   
)joinrh   extenditems)r   linesr   keyr'   s        r(   text_summaryr     s   

)*!,
g&789;


%g.@&A*&M%NaP
#G,>$?$O#PPQR
"d7CU;VWb;c"ddef
W%789JKLAN
/8J0KLb0c/ddmnu  wI  oJ  KZ  o[  n\  \f  gn  oA  gB  CR  gS  fT  TU  	V
 	g


7=1':;1W]=ST\=]<^^_`ghu`vw|`}_~~  	A
$W]%;<P%QRY%Z$[[\]
#-E0 }%&@A Ss3w<.c(m_DWbQRS	LL
gm$%9:7CDDfg 
LL


-gj.ABW.X-Y  Zl  	m
#  z"#89 Yr#f+d3/A+B*C4F}TVWXY	LLVWz"#78 cs3w<.c(m_DVSQTU\Q]P^^`abc	LL


!')"45F"G!H  IL  MT  U^  M_  `r  Ms  Lt  tv  	w
*#  y!'* cs3w<.c(m_DVSQTU\Q]P^^`abc	LL


gn56FGHJ
"g'.BYZeBf"ggnknop
		!eAXYcAd!eelilmn
'.1-@AB

  n-335 1
Us3%uUG3/01	LL  
 
LLB)ABB99Ud""r*   c                N    t        |       }dt        j                  |      z   dz   S )Nar  <!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>DirectDraw Flow</title>
  <style>body{font-family:system-ui,sans-serif;max-width:1100px;margin:24px auto;line-height:1.45}pre{white-space:pre-wrap;background:#f6f6f6;padding:16px;border-radius:6px}</style>
</head>
<body><pre>z</pre></body>
</html>
)r   htmlescape)r   rA   s     r(   	html_pager   Q  s3     D		 ++d

		r*   c                    |j                  dd       |dz  j                  t        j                  | dd      dz   d	       |d
z  j                  t	        |       d	       y )NT)parentsexist_okzdirectdraw_flow.jsonFr@   )ensure_asciiindentr   zutf-8)encodingdirectdraw_flow.html)mkdir
write_textjsondumpsr   )r   out_dirs     r(   write_outputsr   d  sc    MM$M.%%11

7q9D@ 2  %%11)G2Dw1Wr*   c                 T   t        j                  t              } | j                  dt        t
               | j                  dt        t               | j                         }t        |j                        }t        ||j                         t        d|j                  dz          y )N)descriptionz--exe)typedefaultz	--out-dirz!wrote DirectDraw flow summary -> r   )argparseArgumentParser__doc__add_argumentr   EXEOUT
parse_argsr   r-   r   r   print)parserargsr   s      r(   mainr  m  s    $$9F
dC8
$<DDHH%G'4<<(	-dll=S.S-T
UVr*   __main__)r'   z
int | Nonereturnz
str | None)
r-   r   r.   
list[dict]r/   intr0   r  r  r   )r-   r   r.   r  r/   r  r  r  )rD   dictrF   r   r  r  )r-   r   r.   r  r  r  )r   r   r   zdict | Noner  r  )r   r  r  r   )r   r  r   r   r  None)r  r  )0r  
__future__r   r  r   r   r9   pathlibr   probe_exe_scene_tablesr   r   summarize_exe_importsr   __file__resolver   ROOTr	  r  rz   r   r   r   CLIPPER_GLOBALr   r   r   r   r   r   r   re   rf   rg   r)   r2   r4   r=   rB   rJ   rn   r   r   r   r   r  __name__r&   r*   r(   <module>r     sG   Q "      > / H~''*
Ul
]& %z2    " #  



 






	 

',11h $'4 hVM#`& 25 XW zF r*   