Jump to content

WED file corruption ( PST )


aqrit

Recommended Posts

With the Widescreen Mod, Planescape: Torment crashes fairly consistently upon entering small areas.

 

It seems...

That the Widescreen Mod adds tiles to the background overlay but does not add new WallGroups

This can cause the game to interpret data beyond the end of the WallGroup entry list as a WallGroup entry.

Which seems a likely cause of crashing.

 

See:

http://iesdp.gibberlings3.net/file_formats/ie_formats/wed_v1.3.htm#wedV1_3_WallGroup

 

a tile is 64x64 so each Wallgroup covers 640x480

Taking a look at how AR0608.WED ( art gallery ) is changed by the widescreen mod ( 1440x900 )

before - 20x22 with 6 wall groups

after - 25x22 with 6 wall groups... ( when it should have 8? wallgroups )

 

 

Here are some disassembly notes if anyone is interested.

// 4CDv1.1
loc_5D772A:
var_44 = ( area_width_px / 640 + ( !! ( area_width_px % 640 ) );
var_60 = ( area_height_px / 480 + ( !! ( area_height_px % 480 ) );

loc_5D779A:
for( int i = 0; i < 5; i++ ) var_3C[i] = -1;

loc_5D77BF:
var_98 = lprcSrc2->left / 640;
var_94 = lprcSrc2->top / 480;
var_90 = lprcSrc2->right / 640;
var_8C = lprcSrc2->bottom / 480;

loc_5D7819:
for( int row = var_94; ( row <= var_8C ) && ( row < var_60 ); row++ )
{
	for( int col = var_98; ( col <= var_90 ) && ( col < var_44 ); col++ )
	{
		var_4C = ( row * var_44 ) + col;
		wall_group_number_of_polygons = some_wed_struct + ( var_4C * 4 ) + 2;
		for( int i = 0; i < wall_group_number_of_polygons, i++ )
		{
loc_5D78AD:
			...
loc_5D7995:
			rcSrc1.left = wed_poly.MinX;
			rcSrc1.top = wed_poly.MinY;
			rcSrc1.right = wed_poly.MaxX;
			rcSrc1.bottom = wed_poly.MaxY;
			if( IntersectRect( &rcDest, &rcSrc1, lprcSrc2 ) )
			{
				if( wed_poly.impassability == FALSE )
				{
				// 005D7A01
					...
				}
				loc_5D7B89:
				....
				// loc_5D7DAA end
			}
		}
	}
}

 

edit: Clarified { x,y } as { area_width_px, area_height_px }

Link to comment

Copying the wallgroup table to the end of the file and changing the offset in the secondary header causes NearInfinity to throw an error

 

What am I missing?

 

Here is the code I was trying to use in patch_wed.tra

COPY_EXISTING ~%source_res%.wed~ ~override~
tis_idx = cnt
READ_LONG 0x10 overlay_off
READ_SHORT overlay_off      curWidth
READ_SHORT overlay_off + 2  curHeight
READ_LONG  overlay_off + 16 tile_off
READ_LONG  overlay_off + 20 look_off

//
SET origWidth = curWidth
SET origHeight = curHeight
//

loo_idx = 0
FOR (j = 0; j < curWidth * curHeight; j += 1) BEGIN
	READ_SSHORT tile_off + 10 * (j)     idx
	READ_SSHORT tile_off + 10 * (j) + 2 cnt
	i = idx + cnt
	loo_idx = ((loo_idx < i) ? i : loo_idx)
END
FOR (j = yMaxWed; j < yReq; j += 1) BEGIN
	LAUNCH_PATCH_MACRO ~add_one_row~
END
FOR (j = xMaxWed; j < xReq; j += 1) BEGIN
	LAUNCH_PATCH_MACRO ~add_one_col~		
END

//
// move wall group table to end of the file to keep fixups minimal
// add wall groups for the new tiles that were added to the background overlay

SET orig_wg_cols = ((( origWidth * 64 ) + 639 ) / 640 )
SET orig_wg_rows = ((( origHeight * 64 ) + 479 ) / 480 )
SET orig_wg_size = orig_wg_cols * orig_wg_rows * 4
SET orig_wg_stride = orig_wg_cols * 4

SET new_wg_cols = ((( curWidth * 64 ) + 639 ) / 640 )
SET new_wg_rows = ((( curHeight * 64 ) + 479 ) / 480 )
SET new_wg_size = new_wg_cols * new_wg_rows * 4
SET new_wg_stride = new_wg_cols * 4

PATCH_IF( orig_wg_size != new_wg_size ) BEGIN
	READ_LONG 0x14 secondary_header_offset
	READ_LONG ( secondary_header_offset + 0x0C ) orig_wg_offset
	SET new_wg_offset = BUFFER_LENGTH // todo: make sure dword aligned

	WRITE_LONG ( secondary_header_offset + 0x0C ) new_wg_offset
	INSERT_BYTES new_wg_offset new_wg_size

	PATCH_IF( orig_wg_stride == new_wg_stride ) BEGIN
		READ_ASCII orig_wg_offset wgtbl (orig_wg_size)
		WRITE_ASCIIE new_wg_offset ~%wgtbl%~ (orig_wg_size)
	END
	ELSE BEGIN
		FOR( j = 0; j < orig_wg_rows; j += 1 ) BEGIN
			READ_ASCII (orig_wg_offset + (j * orig_wg_stride)) wgtbl (orig_wg_stride)
			WRITE_ASCIIE (new_wg_offset + (j * new_wg_stride)) ~%wgtbl%~ (orig_wg_stride)
		END
	END
END
//		

 

edit: added "PATCH_IF( orig_wg_size != new_wg_size )"

Link to comment

NearInfinity is bugged. ( limecat is not amused )

int countWallgroups = (findNextOffset(offsets, offsetWallgroups).getValue() -
					   offsetWallgroups.getValue()) /
					  4;

 

I think this is ready for human testing. ( be sure to make a full-backup )

This does not solve the crashing when entering small areas ( apparently )

 

But it is mostly targeted at the crashing when walking around in the Art Gallery.

http://www.gog.com/forum/planescape_torment/yvana_art_gallery_crashes/page1

( I currently don't have a save to test, so I don't know if it works :p )

 

All the hard work tracking down this bug was done by Scient.

I just jumped in at the end to steal some of his thunder.

Link to comment

As one of the unlucky people who has been plagued by constant crashes when entering small areas (maybe because I have a large 2560 x 1440 monitor?), is there a known fix for those? I saw the one from scient here, but I saw it makes people float above everything, which is also undesirable (but obviously preferable to crashing).

 

I've wanted to play PST for years, but every time I try it out on a new computer I always run into so many crashes that I end up just giving up. :(

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...