Skip to content

Commit

Permalink
Fix TOH/TOT parser
Browse files Browse the repository at this point in the history
- Updated unknown fields
- Fixed incomplete string display in TOH strref field if overridden
string consists of multiple segments
- Fixed an incorrectly interpreted TOT offset value that caused NI to
freeze or crash under certain circumstances

Fixes NearInfinityBrowser#177
  • Loading branch information
Argent77 committed Apr 6, 2024
1 parent 019e351 commit 2767993
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 11 deletions.
13 changes: 7 additions & 6 deletions src/org/infinity/resource/to/StrRefEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@

import java.nio.ByteBuffer;

import org.infinity.datatype.DecNumber;
import org.infinity.datatype.Flag;
import org.infinity.datatype.HexNumber;
import org.infinity.datatype.ResourceRef;
import org.infinity.datatype.StringRef;
import org.infinity.datatype.Unknown;
import org.infinity.gui.StringEditor;
import org.infinity.resource.AbstractStruct;
import org.infinity.util.io.StreamUtils;

public class StrRefEntry extends AbstractStruct {
// TOH/StrrefEntry-specific field labels
public static final String TOH_STRREF = "StrRef entry";
public static final String TOH_STRREF_OVERRIDDEN = "Overridden strref";
public static final String TOH_STRREF_SOUND = "Associated sound";
public static final String TOH_STRREF_OFFSET_TOT_STRING = "TOT string offset";

public StrRefEntry() throws Exception {
Expand All @@ -35,10 +36,10 @@ public StrRefEntry(AbstractStruct superStruct, String name, ByteBuffer buffer, i
@Override
public int read(ByteBuffer buffer, int offset) throws Exception {
addField(new StringRef(buffer, offset, TOH_STRREF_OVERRIDDEN));
addField(new Unknown(buffer, offset + 4, 4));
addField(new Unknown(buffer, offset + 8, 4));
addField(new Unknown(buffer, offset + 12, 4));
addField(new ResourceRef(buffer, offset + 16, TOH_STRREF_SOUND, "WAV"));
addField(new Flag(buffer, offset + 4, 4, StringEditor.TLK_FLAGS, StringEditor.FLAGS));
addField(new ResourceRef(buffer, offset + 8, StringEditor.TLK_SOUND, "WAV"));
addField(new DecNumber(buffer, offset + 16, 4, StringEditor.TLK_VOLUME));
addField(new DecNumber(buffer, offset + 20, 4, StringEditor.TLK_PITCH));
addField(new HexNumber(buffer, offset + 24, 4, TOH_STRREF_OFFSET_TOT_STRING));
return offset + 28;
}
Expand Down
2 changes: 1 addition & 1 deletion src/org/infinity/resource/to/StringEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public int read(ByteBuffer buffer, int offset) throws Exception {
addField(new HexNumber(buffer, offset, 4, TOT_STRING_OFFSET_FREE_REGION));
addField(new HexNumber(buffer, offset + 4, 4, TOT_STRING_OFFSET_PREV_ENTRY));
addField(new TextEdit(buffer, offset + 8, 512, TOT_STRING_TEXT));
addField(new HexNumber(buffer, offset + 520, 4, TOT_STRING_OFFSET_NEXT_ENTRY));
addField(new HexNumber(buffer, offset + 520, 4, TOT_STRING_OFFSET_NEXT_ENTRY)); // Note: offset value is relative to structure base offset
return offset + 524;
}
}
16 changes: 13 additions & 3 deletions src/org/infinity/resource/to/TohResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,20 @@ public static String getOverrideString(TohResource toh, TotResource tot, int str
if (strrefEntry != null) {
int v = ((IsNumeric) strrefEntry.getAttribute(StrRefEntry.TOH_STRREF_OVERRIDDEN)).getValue();
if (v == strref) {
// string entry may consist of multiple segments
retVal = "";
int sofs = ((IsNumeric) strrefEntry.getAttribute(StrRefEntry.TOH_STRREF_OFFSET_TOT_STRING)).getValue();
StringEntry se = (StringEntry) tot.getAttribute(sofs, false);
if (se != null) {
retVal = se.getAttribute(StringEntry.TOT_STRING_TEXT).toString();
while (sofs >= 0) {
StringEntry se = (StringEntry) tot.getAttribute(sofs, false);
if (se != null) {
retVal += se.getAttribute(StringEntry.TOT_STRING_TEXT).toString();
sofs = ((IsNumeric) se.getAttribute(StringEntry.TOT_STRING_OFFSET_NEXT_ENTRY)).getValue();
if (sofs >= 0) {
sofs += se.getOffset();
}
} else {
sofs = -1;
}
}
break;
}
Expand Down
3 changes: 2 additions & 1 deletion src/org/infinity/resource/to/TotResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ public int read(ByteBuffer buffer, int offset) throws Exception {
int ofsNextEntry = ((IsNumeric) stringEntry.getAttribute(StringEntry.TOT_STRING_OFFSET_NEXT_ENTRY))
.getValue();
if (ofsNextEntry >= 0) {
stringEntry = new StringEntry(this, buffer, ofsNextEntry, idx);
// Note: next entry offset is relative to structure base offset
stringEntry = new StringEntry(this, buffer, stringEntry.getOffset() + ofsNextEntry, idx);
} else {
stringEntry = null;
}
Expand Down

0 comments on commit 2767993

Please sign in to comment.