BrawlCrate v0.41
Wii File Editor
Loading...
Searching...
No Matches
Classes | Public Member Functions | Public Attributes | Static Public Attributes | Properties | List of all members
BrawlLib.SSBB.ResourceNodes.RELNode Class Reference
Inheritance diagram for BrawlLib.SSBB.ResourceNodes.RELNode:
BrawlLib.SSBB.ResourceNodes.ARCEntryNode BrawlLib.SSBB.ResourceNodes.ModuleNode BrawlLib.SSBB.ResourceNodes.U8EntryNode BrawlLib.SSBB.ResourceNodes.ResourceNode

Public Member Functions

void UpdateItemIDs ()
 
void SaveItems ()
 
override void Dispose ()
 
override bool OnInitialize ()
 
override void OnPopulate ()
 
void ApplyRelocations ()
 
void GenerateImports ()
 
override int OnCalculateSize (bool force)
 
override void OnRebuild (VoidPtr address, int length, bool force)
 
- Public Member Functions inherited from BrawlLib.SSBB.ResourceNodes.ARCEntryNode
bool isModelData ()
 
bool isTextureData ()
 
void UpdateName ()
 
override void Initialize (ResourceNode parent, DataSource origSource, DataSource uncompSource)
 
override bool OnInitialize ()
 
- Public Member Functions inherited from BrawlLib.SSBB.ResourceNodes.ResourceNode
void OnRenamed ()
 
List< ResourceNodeGetChildrenRecursive ()
 Used primarily to get bone lists. Kept for all resource nodes for utility. More...
 
virtual void SignalPropertyChange ()
 
virtual void Dispose ()
 
void SelectChildAtIndex (int index)
 
void UpdateProperties ()
 
void UpdateCurrentControl ()
 
virtual bool MoveUp ()
 
virtual bool MoveDown ()
 
virtual void OnMoved ()
 
virtual void DoMoveDown ()
 
virtual void DoMoveDown (bool select)
 
virtual void DoMoveUp ()
 
virtual void DoMoveUp (bool select)
 
virtual bool AddUp ()
 
virtual bool AddDown ()
 
virtual bool ToParent ()
 
void Populate (int levels=-1)
 
virtual void OnPopulate ()
 
void Initialize (ResourceNode parent, FileMap source)
 
void Initialize (ResourceNode parent, VoidPtr address, int length)
 
void Initialize (ResourceNode parent, DataSource origSource)
 
virtual void Initialize (ResourceNode parent, DataSource origSource, DataSource uncompSource)
 
virtual bool OnInitialize ()
 
virtual void Restore ()
 
virtual void Remove ()
 
virtual void RemoveChild (ResourceNode child)
 
virtual void AddChild (ResourceNode child)
 
virtual void AddChild (ResourceNode child, bool change)
 
virtual void InsertChild (ResourceNode child, int index)
 
virtual void InsertChild (ResourceNode child, bool change, int index)
 
void SetSizeInternal (int size)
 
virtual void Replace (string fileName)
 
virtual void Replace (ResourceNode node)
 
virtual void Replace (string fileName, FileMapProtect prot, FileOptions options)
 
virtual void ReplaceRaw (VoidPtr address, int length)
 
virtual void ReplaceRaw (FileMap map)
 
virtual void Export (string outPath)
 
void Export (FileStream outStream)
 
virtual void ExportUncompressed (string outPath)
 
void ExportUncompressed (FileStream outStream)
 
virtual void Rebuild ()
 
virtual void Rebuild (bool force)
 
virtual void Rebuild (VoidPtr address, int length, bool force)
 
virtual void OnRebuild (VoidPtr address, int length, bool force)
 
virtual int CalculateSize (bool force)
 
virtual int OnCalculateSize (bool force)
 
void Merge ()
 
void Merge (bool forceBuild)
 
ResourceNode FindChildByType (string path, bool searchChildren, params ResourceType[] types)
 
ResourceNode FindChildByType (string path, bool searchChildren, StringComparison compare, params ResourceType[] types)
 
ResourceNode FindChild (string path)
 
ResourceNode FindChild (string path, bool searchChildren)
 
ResourceNode FindChild (string path, StringComparison compare)
 
ResourceNode FindChild (string path, bool searchChildren, StringComparison compare)
 
ResourceNode[] FindChildrenByClassType (string path, Type type)
 
ResourceNode[] FindChildrenByType (string path, ResourceType type)
 
ResourceNode[] FindChildrenByTypeInGroup (string path, ResourceType type, byte group)
 
ResourceNode[] FindChildrenByName (string name)
 
unsafe string FindName (string name)
 
ResourceNode FindEmbeddedIndex (int index)
 
virtual unsafe byte[] MD5 ()
 Find the MD5 checksum of this node's data. If this node doesn't have any data (BRESGroupNode, for example), this method will return null. More...
 
string MD5Str ()
 Get the result of the MD5() function as a string of hexadecimal digits. If MD5() returns null, this method will return an empty string. More...
 
ResourceNode PrevSibling ()
 
ResourceNode NextSibling ()
 
override string ToString ()
 
virtual void SortChildren ()
 

Public Attributes

ModuleSectionNode[] _sections
 
uint _id
 
int _linkNext
 
int _linkPrev
 
uint _numSections
 
uint _infoOffset
 
uint _nameOffset
 
uint _nameSize
 
uint _version
 
uint _bssSize
 
uint _relOffset
 
uint _impOffset
 
uint _impSize
 
byte _prologSection
 
byte _epilogSection
 
byte _unresolvedSection
 
byte _bssSection
 
uint _prologOffset
 
uint _epilogOffset
 
uint _unresolvedOffset
 
uint _moduleAlign = 32
 
uint _bssAlign = 8
 
uint _fixSize
 
byte? _stageID
 
byte[] _itemIDs
 
SortedDictionary< uint, List< RELLink > > _imports = new SortedDictionary<uint, List<RELLink>>()
 
- Public Attributes inherited from BrawlLib.SSBB.ResourceNodes.ARCEntryNode
ResourceType _resourceType = ResourceType.ARCEntry
 
- Public Attributes inherited from BrawlLib.SSBB.ResourceNodes.U8EntryNode
int _u8Parent
 
int _u8FirstNotChild
 
int _u8Type
 
int _u8Index
 
- Public Attributes inherited from BrawlLib.SSBB.ResourceNodes.ResourceNode
Form _mainForm
 
string _name
 
string _origPath
 
ResourceNode _parent
 
List< ResourceNode_children = new List<ResourceNode>()
 
int _calcSize
 
EventHandler UpdateControl
 
MoveEventHandler MovedDown
 
ResourceEventHandler Renamed
 
ResourceEventHandler PropertyChanged
 
ResourceEventHandler Replaced
 
ResourceEventHandler Restored
 
ResourceChildEventHandler ChildRemoved
 
bool _isPopulating
 
bool _replaced
 

Static Public Attributes

static Dictionary< uint, RELNode_files = new Dictionary<uint, RELNode>()
 
static SortedList< uint, string > _idNames
 

Properties

override ResourceType ResourceFileType [get]
 
ModuleSectionNode[] Sections [get]
 
uint ModuleID [get, set]
 
new uint ID [get, set]
 
string ModuleName [get]
 
uint NameOffset [get, set]
 
uint NameSize [get, set]
 
uint Version [get]
 
uint PrologSection [get]
 
uint EpilogSection [get]
 
uint UnresolvedSection [get]
 
uint BSSSection [get]
 
uint ModuleAlign [get]
 
uint BSSAlign [get]
 
uint FixSize [get]
 
string[] ImportedModules [get]
 
int? StageID [get, set]
 
byte? ItemID1 [get, set]
 
byte? ItemID2 [get, set]
 
byte? ItemID3 [get, set]
 
byte? ItemID4 [get, set]
 
- Properties inherited from BrawlLib.SSBB.ResourceNodes.ARCEntryNode
override ResourceType ResourceFileType [get]
 
override string Compression [get, set]
 
ARCFileType FileType [get, set]
 
short FileIndex [get, set]
 
byte GroupID [get, set]
 
int AbsoluteIndex [get]
 
short RedirectIndex [get, set]
 
string RedirectTargetName [get]
 
string RedirectTarget [get, set]
 
ResourceNode RedirectNode [get]
 
- Properties inherited from BrawlLib.SSBB.ResourceNodes.U8EntryNode
int ParentIndex [get]
 
int ChildEndIndex [get]
 
int Type [get]
 
int ID [get]
 
- Properties inherited from BrawlLib.SSBB.ResourceNodes.ResourceNode
string FilePath [get]
 
string FileName [get]
 
string DirectoryName [get]
 
ResourceNode RootNode [get]
 
DataSource OriginalSource [get]
 
DataSource UncompressedSource [get]
 
DataSource WorkingSource [get]
 
DataSource WorkingUncompressed [get]
 
virtual bool HasChildren [get]
 
virtual ResourceType ResourceFileType [get]
 
string NodeType [get]
 
virtual string TreePathAbsolute [get]
 
virtual string TreePath [get]
 
virtual int Level [get]
 
virtual int MaxNameLength [get]
 
virtual bool AllowDuplicateNames [get]
 
virtual bool AllowNullNames [get]
 
virtual string Name [get, set]
 
ResourceNode Parent [get, set]
 
List< ResourceNodeChildren [get]
 
int Index [get]
 
int HexIndex [get]
 
bool IsCompressed [get]
 
bool HasChanged [get, set]
 
bool IsBranch [get]
 
bool HasMerged [get]
 
virtual bool AllowSaving [get, set]
 
virtual bool IsDirty [get, set]
 
virtual uint UncompressedSize [get]
 
virtual Type[] AllowedChildTypes [get]
 
virtual string Compression [get, set]
 
virtual bool RetainChildrenOnReplace [get]
 
virtual bool supportsCompression [get]
 
static MD5CryptoServiceProvider MD5Provider [get]
 
- Properties inherited from BrawlLib.SSBB.ResourceNodes.ModuleNode
uint ID [get, set]
 
ModuleSectionNode[] Sections [get]
 

Additional Inherited Members

- Static Public Member Functions inherited from BrawlLib.SSBB.ResourceNodes.ResourceNode
static ResourceNode[] FindAllSubNodes (ResourceNode root)
 
static ResourceNode FindNode (ResourceNode root, string path, bool searchChildren, StringComparison compare)
 
- Protected Member Functions inherited from BrawlLib.SSBB.ResourceNodes.ARCEntryNode
virtual string GetName ()
 
virtual string GetName (string fileType)
 
- Protected Member Functions inherited from BrawlLib.SSBB.ResourceNodes.ResourceNode
void ForceReplacedEvent ()
 
virtual void MergeInternal ()
 
- Protected Attributes inherited from BrawlLib.SSBB.ResourceNodes.ARCEntryNode
ResourceNode redirectTargetNode
 
- Events inherited from BrawlLib.SSBB.ResourceNodes.ResourceNode
SelectEventHandler SelectChild
 
EventHandler UpdateProps
 
MoveEventHandler MovedUp
 
ResourceEventHandler Disposing
 
ResourceChildEventHandler ChildAdded
 
ResourceChildInsertEventHandler ChildInserted
 

Member Function Documentation

◆ ApplyRelocations()

void BrawlLib.SSBB.ResourceNodes.RELNode.ApplyRelocations ( )
inline
503 {
504 foreach (ModuleSectionNode r in Sections)
505 {
506 r._manager.ClearCommands();
507 }
508
509 int offset = 0;
510 int i = 0;
511 foreach (uint x in _imports.Keys)
512 {
513 List<RELLink> cmds = _imports[x];
514 ModuleSectionNode section = null;
515 foreach (RELLink link in cmds)
516 {
517 if (link._type == RELLinkType.Section)
518 {
519 offset = 0;
520 section = Sections[link._section];
521 }
522 else
523 {
524 offset += link._prevOffset;
525
526 if (link._type == RELLinkType.End || link._type == RELLinkType.IncrementOffset)
527 {
528 continue;
529 }
530
531 if (link._type == RELLinkType.MrkRef)
532 {
533 Console.WriteLine("Mark Ref");
534 continue;
535 }
536
537 section?._manager.SetCommand(offset.RoundDown(4) / 4, new RelCommand(x, section, link));
538 }
539 }
540
541 i++;
542 }
543
544 ModuleDataNode s;
545
547 offset = (int) _prologOffset;
548 //_prologReloc = s.GetRelocationAtOffset(offset);
549 //if (_prologReloc != null)
550 // _prologReloc._prolog = true;
551
552
554 offset = (int) _epilogOffset;
555
556 //_epilogReloc = s.GetRelocationAtOffset(offset);
557 //if (_epilogReloc != null)
558 // _epilogReloc._epilog = true;
559
560
562 offset = (int) _unresolvedOffset;
563
564 //_unresReloc = s.GetRelocationAtOffset(offset);
565 //if (_unresReloc != null)
566 // _unresReloc._unresolved = true;
567 }
uint _unresolvedOffset
Definition: RELNode.cs:59
ModuleSectionNode[] Sections
Definition: RELNode.cs:23
byte _unresolvedSection
Definition: RELNode.cs:54
byte _prologSection
Definition: RELNode.cs:52
uint _epilogOffset
Definition: RELNode.cs:58
ModuleSectionNode[] _sections
Definition: RELNode.cs:35
byte _epilogSection
Definition: RELNode.cs:53
SortedDictionary< uint, List< RELLink > > _imports
Definition: RELNode.cs:371
uint _prologOffset
Definition: RELNode.cs:57
RELLinkType
Definition: REL.cs:151

◆ Dispose()

override void BrawlLib.SSBB.ResourceNodes.RELNode.Dispose ( )
inlinevirtual

Reimplemented from BrawlLib.SSBB.ResourceNodes.ResourceNode.

299 {
300 while (!_populated)
301 {
302 // Do nothing until population is complete, fixing API enumeration errors
303 }
304 _files.Remove(ModuleID);
305 base.Dispose();
306 }
static Dictionary< uint, RELNode > _files
Definition: RELNode.cs:817
uint ModuleID
Definition: RELNode.cs:70

◆ GenerateImports()

void BrawlLib.SSBB.ResourceNodes.RELNode.GenerateImports ( )
inline
576 {
577 _imports.Clear();
578 Dictionary<uint, ImportData> tempImports = new Dictionary<uint, ImportData>();
579 foreach (ModuleSectionNode s in _sections)
580 {
581 foreach (ImportData e in tempImports.Values)
582 {
583 e._newSection = true;
584 e._lastOffset = 0;
585 }
586
587 uint offset = 0;
588 List<RELLink> links;
589
590 //Iterate through each command in the section
591 KeyValuePair<int, RelCommand>[] commands = s._manager.GetCommands();
592 foreach (KeyValuePair<int, RelCommand> r in commands)
593 {
594 RelCommand command = r.Value;
595 int index = r.Key;
596
597 ImportData impData;
598 uint moduleID = command._moduleID;
599
600 //Check if an import has been created for the target module.
601 if (_imports.ContainsKey(moduleID))
602 {
603 //An import already exists, so we'll add to it.
604 links = _imports[moduleID];
605 impData = tempImports[moduleID];
606 }
607 else
608 {
609 //An import does not exist, so it must be made.
610 _imports.Add(moduleID, links = new List<RELLink>());
611
612 //Create new temporary import data
613 tempImports.Add(moduleID, impData = new ImportData {_newSection = true, _lastOffset = 0});
614 }
615
616 //This is true when a new section is being evaluated.
617 if (impData._newSection)
618 {
619 links.Add(new RELLink {_type = RELLinkType.Section, _section = (byte) s.Index});
620 impData._newSection = false;
621 }
622
623 //Get the offset of the command within the section.
624 offset = (uint) index * 4 + (command.IsHalf ? 2u : 0);
625
626 //Get the offset to this address relative to the last written link offset.
627 uint diff = offset - impData._lastOffset;
628
629 //If the difference is greater than ushort allows,
630 //add increment links until the difference works
631 while (diff > 0xFFFF)
632 {
633 impData._lastOffset += 0xFFFF;
634 diff = offset - impData._lastOffset;
635
636 links.Add(new RELLink
637 {_type = RELLinkType.IncrementOffset, _section = 0, _value = 0, _prevOffset = 0xFFFF});
638 }
639
640 //Gather the link information
641 byte targetSection = (byte) command._targetSectionId;
642 RELLinkType type = (RELLinkType) command._command;
643 uint val = command._addend;
644
645 //Write command link
646 links.Add(new RELLink
647 {_type = type, _section = targetSection, _value = val, _prevOffset = (ushort) diff});
648
649 //Don't bother adding the difference,
650 //just set the exact offset as the last offset
651 impData._lastOffset = offset;
652 }
653 }
654
655 foreach (List<RELLink> cmds in _imports.Values)
656 {
657 cmds.Add(new RELLink {_type = RELLinkType.End});
658 }
659 }

◆ OnCalculateSize()

override int BrawlLib.SSBB.ResourceNodes.RELNode.OnCalculateSize ( bool  force)
inlinevirtual

Reimplemented from BrawlLib.SSBB.ResourceNodes.ResourceNode.

662 {
664
665 int size = RELHeader.Size + Children.Count * RELSectionEntry.Size +
666 _imports.Keys.Count * RELImportEntry.Size;
667 foreach (ModuleSectionNode s in Children)
668 {
669 //Section 4 and 5 seem to be the only ones that are aligned.
670 //I don't know the exact alignment procedure. It's not consistent
671 //if (s.Index > 3)
672 // size = size.Align(8);
673
674 int r = s.CalculateSize(true);
675 if (!s._isBSSSection)
676 {
677 size += r;
678 }
679 }
680
681 foreach (List<RELLink> s in _imports.Values)
682 {
683 size += s.Count * RELLink.Size;
684 }
685
686 return size;
687 }
void GenerateImports()
Definition: RELNode.cs:575
List< ResourceNode > Children
Definition: ResourceNode.cs:262
Definition: REL.cs:103
const int Size
Definition: REL.cs:104

◆ OnInitialize()

override bool BrawlLib.SSBB.ResourceNodes.RELNode.OnInitialize ( )
inlinevirtual

Reimplemented from BrawlLib.SSBB.ResourceNodes.U8EntryNode.

309 {
310 _id = Header->_info._id;
311 _linkNext = Header->_info._link._linkNext; //0
312 _linkPrev = Header->_info._link._linkPrev; //0
315 _nameOffset = Header->_info._nameOffset;
316 _nameSize = Header->_info._nameSize;
317 _version = Header->_info._version;
318
319 _bssSize = Header->_bssSize;
320 _relOffset = Header->_relOffset;
321 _impOffset = Header->_impOffset;
322 _impSize = Header->_impSize;
326 _bssSection = Header->_bssSection;
330
331 _moduleAlign = Header->_moduleAlign;
332 _bssAlign = Header->_bssAlign;
333 _fixSize = Header->_commandOffset;
334
335 _imports = new SortedDictionary<uint, List<RELLink>>();
336 string[] impNames = new string[Header->ImportListCount];
337
338 for (int i = 0; i < Header->ImportListCount; i++)
339 {
340 RELImportEntry* entry = &Header->Imports[i];
341 uint id = entry->_moduleId;
342 _imports.Add(id, new List<RELLink>());
343 impNames[i] = _idNames.ContainsKey(id) ? _idNames[id] : $"Module{id}";
344
345 RELLink* link = (RELLink*) (WorkingUncompressed.Address + entry->_offset);
346 do
347 {
348 _imports[id].Add(*link);
349 } while ((link++)->_type != RELLinkType.End);
350 }
351
352 ImportedModules = impNames;
353
354 if (_name == null)
355 {
356 _name = _idNames.ContainsKey(_id) ? _idNames[_id] : Path.GetFileName(_origPath);
357 }
358
359 if (!_files.ContainsKey(ModuleID))
360 {
361 _files.Add(ModuleID, this);
362 }
363 else
364 {
365 _files[ModuleID] = this;
366 }
367
368 return true;
369 }
uint _bssSize
Definition: RELNode.cs:47
uint _infoOffset
Definition: RELNode.cs:42
uint _relOffset
Definition: RELNode.cs:48
uint _moduleAlign
Definition: RELNode.cs:61
uint _bssAlign
Definition: RELNode.cs:62
uint _nameSize
Definition: RELNode.cs:44
int _linkNext
Definition: RELNode.cs:38
static SortedList< uint, string > _idNames
Definition: RELNode.cs:932
uint _fixSize
Definition: RELNode.cs:63
uint _impSize
Definition: RELNode.cs:50
string[] ImportedModules
Definition: RELNode.cs:145
uint _id
Definition: RELNode.cs:37
uint _impOffset
Definition: RELNode.cs:49
byte _bssSection
Definition: RELNode.cs:55
uint _numSections
Definition: RELNode.cs:40
uint _nameOffset
Definition: RELNode.cs:43
uint _version
Definition: RELNode.cs:45
int _linkPrev
Definition: RELNode.cs:39
string _origPath
Definition: ResourceNode.cs:139
string _name
Definition: ResourceNode.cs:139
DataSource WorkingUncompressed
Definition: ResourceNode.cs:183
VoidPtr Address
Definition: ResourceNode.cs:31
buint _nameSize
Definition: REL.cs:205
buint _numSections
Definition: REL.cs:202
buint _nameOffset
Definition: REL.cs:204
ModuleLink _link
Definition: REL.cs:201
buint _version
Definition: REL.cs:206
buint _id
Definition: REL.cs:200
buint _sectionInfoOffset
Definition: REL.cs:203
byte _prologSection
Definition: REL.cs:22
buint _unresolvedOffset
Definition: REL.cs:30
buint _prologOffset
Definition: REL.cs:28
buint _bssAlign
Definition: REL.cs:34
buint _epilogOffset
Definition: REL.cs:29
RELImportEntry * Imports
Definition: REL.cs:63
byte _bssSection
Definition: REL.cs:25
byte _epilogSection
Definition: REL.cs:23
buint _moduleAlign
Definition: REL.cs:33
buint _bssSize
Definition: REL.cs:14
buint _commandOffset
Definition: REL.cs:37
byte _unresolvedSection
Definition: REL.cs:24
int ImportListCount
Definition: REL.cs:65
buint _relOffset
Definition: REL.cs:15
ModuleInfo _info
Definition: REL.cs:11
buint _impSize
Definition: REL.cs:17
buint _impOffset
Definition: REL.cs:16
buint _moduleId
Definition: REL.cs:106
buint _offset
Definition: REL.cs:109

◆ OnPopulate()

override void BrawlLib.SSBB.ResourceNodes.RELNode.OnPopulate ( )
inlinevirtual

Reimplemented from BrawlLib.SSBB.ResourceNodes.ResourceNode.

377 {
378 _sections = new ModuleSectionNode[_numSections];
379 int prevOffset = RELHeader.Size + RELSectionEntry.Size * (int) _numSections;
380 int lastDataSection = -1;
381 for (int i = 0; i < _numSections; i++)
382 {
383 RELSectionEntry entry = Header->SectionInfo[i];
384 ModuleSectionNode section = _sections[i] = new ModuleSectionNode();
385
386 int dataOffset = entry.Offset, dataSize = (int) (uint) entry._size;
387
388 section._isCodeSection = entry.IsCodeSection;
389 section._dataOffset = dataOffset;
390 section._dataSize = entry._size;
391
392 // Calculate buffer
393 if (!Properties.Settings.Default.AutoCompressModules && i > 0 && dataOffset > 0)
394 {
395 _sections[i - 1]._endBufferSize = (dataOffset - prevOffset).ClampMin(0);
396 lastDataSection = i;
397 }
398
399 section.Initialize(this, WorkingUncompressed.Address + dataOffset, dataSize);
400
401 if (dataOffset > 0)
402 {
403 section._dataAlign = dataOffset - prevOffset;
404 prevOffset = dataOffset + dataSize;
405 }
406 }
407
408 if (lastDataSection != -1)
409 {
410 // Calculate buffer between last section and imports
411 RELSectionEntry entry = Header->SectionInfo[lastDataSection];
412 int dataOffset = entry.Offset, dataSize = (int) (uint) entry._size;
413 _sections[lastDataSection]._endBufferSize =
414 ((int) (_impOffset - (dataOffset + dataSize))).ClampMin(0);
415 }
416
417 //Larger modules may take slightly longer to relocate
418 //Use a background worker so the UI thread isn't suspended
419 Action<object, DoWorkEventArgs> work = (object sender, DoWorkEventArgs e) =>
420 {
421 Stopwatch watch = Stopwatch.StartNew();
422
424
425 //Scan for branches, add extra tags
426 foreach (ModuleSectionNode s in Sections)
427 {
428 if (s.HasCode)
429 {
430 PPCOpCode code;
431 buint* opPtr = s.BufferAddress;
432 for (int i = 0; i < s._dataBuffer.Length / 4; i++)
433 {
434 if ((code = (uint) *opPtr++) is PPCBranch && !(code is PPCblr || code is PPCbctr))
435 {
436 s._manager.LinkBranch(i, true);
437 }
438 }
439
440 KeyValuePair<int, RelCommand>[] cmds = s._manager.GetCommands();
441 foreach (KeyValuePair<int, RelCommand> x in cmds)
442 {
443 RelocationTarget target = x.Value.GetTargetRelocation();
444 string value = null;
445 if (target.Section != null && target._sectionID == 5 &&
446 !string.IsNullOrEmpty(value = target.Section._manager.GetString(target._index)))
447 {
448 s._manager.AddTag(x.Key, value);
449 }
450 }
451 }
452 }
453
454 Sections[5].Populate();
455
456 watch.Stop();
457 Console.WriteLine("Took {0} seconds to relocate {1} module", watch.ElapsedMilliseconds / 1000d, Name);
458 _populated = true;
459 };
460
461 using (BackgroundWorker b = new BackgroundWorker())
462 {
463 b.DoWork += new DoWorkEventHandler(work);
464 b.RunWorkerAsync();
465 }
466
467 // Stage module conversion
468 byte* bptr = (byte*) WorkingUncompressed.Address;
469 int offset = findStageIDOffset();
470 _stageID = offset < 0 ? (byte?) null : bptr[offset];
471 _itemIDOffsets = null;
472 // ReSharper disable once StringLiteralTypo (Typo is present in vBrawl)
473 if (nodeContainsString("stOnlineTrainning"))
474 {
475 // File must be online training room .rel file
476 _itemIDs = new byte[OTrainItemOffsets.Length];
477 _itemIDOffsets = OTrainItemOffsets;
478 }
479 else if (nodeContainsString("stDxGreens"))
480 {
481 _itemIDs = new byte[DxGreensItemOffsets.Length];
482 _itemIDOffsets = DxGreensItemOffsets;
483 }
484 else if (nodeContainsString("stEarth"))
485 {
486 _itemIDs = new byte[EarthItemOffsets.Length];
487 _itemIDOffsets = EarthItemOffsets;
488 }
489 else if (nodeContainsString("stVillage"))
490 {
491 _itemIDs = new byte[VillageItemOffsets.Length];
492 _itemIDOffsets = VillageItemOffsets;
493 }
494 else if (nodeContainsString("stCrayon"))
495 {
496 _itemIDs = new byte[CrayonItemOffsets.Length];
497 _itemIDOffsets = CrayonItemOffsets;
498 }
500 }
Definition: PPCOpCode.cs:906
Definition: PPCOpCode.cs:738
int _endBufferSize
Definition: RELSectionNode.cs:21
void ApplyRelocations()
Definition: RELNode.cs:502
byte? _stageID
Definition: RELNode.cs:65
byte[] _itemIDs
Definition: RELNode.cs:66
void UpdateItemIDs()
Definition: RELNode.cs:166
virtual string Name
Definition: ResourceNode.cs:223
void Populate(int levels=-1)
Definition: ResourceNode.cs:613
Definition: BigEndianTypes.cs:59
uint Value
Definition: BigEndianTypes.cs:99
RELSectionEntry * SectionInfo
Definition: REL.cs:62
Definition: REL.cs:70
bool IsCodeSection
Definition: REL.cs:77
int Offset
Definition: REL.cs:84
buint _size
Definition: REL.cs:74

◆ OnRebuild()

override void BrawlLib.SSBB.ResourceNodes.RELNode.OnRebuild ( VoidPtr  address,
int  length,
bool  force 
)
inlinevirtual

Reimplemented from BrawlLib.SSBB.ResourceNodes.ResourceNode.

690 {
691 RELHeader* header = (RELHeader*) address;
692
693 header->_info._id = _id;
694 header->_info._link._linkNext = 0;
695 header->_info._link._linkPrev = 0;
696 header->_info._numSections = (uint) Children.Count;
698 header->_info._nameOffset = _nameOffset;
699 header->_info._nameSize = _nameSize;
700 header->_info._version = _version;
701
708
709 header->_moduleAlign = 0x20;
710 header->_bssAlign = 0x8;
711 header->_commandOffset = 0;
712
713 header->_bssSize = 0;
714 header->_bssSection = 0;
715
716 RELSectionEntry* sections = (RELSectionEntry*) (address + RELHeader.Size);
717 VoidPtr dataAddr = address + RELHeader.Size + Children.Count * RELSectionEntry.Size;
718 foreach (ModuleSectionNode s in Children)
719 {
720 if (s._dataBuffer.Length != 0)
721 {
722 int i = s.Index;
723
724 sections[i]._size = (uint) (s._calcSize - (s.ExpandSection ? 0 : s.EndBufferSize));
725
726 //Align sections 4 and 5?
727 //if (i > 3)
728 //{
729 // int off = (int)(dataAddr - address);
730 // int aligned = off.Align(8);
731 // int diff = aligned - off;
732 // dataAddr += diff;
733 //}
734
735 if (!s._isBSSSection)
736 {
737 sections[i]._offset = (uint) (dataAddr - address);
738 sections[i].IsCodeSection = s.HasCode;
739
740 s.Rebuild(dataAddr, s._calcSize, true);
741
742 dataAddr += s._calcSize;
743 }
744 else
745 {
746 sections[i]._offset = 0;
747
748 header->_bssSection = 0; //This is always 0 it seems
749 header->_bssSize = (uint) (s._calcSize - (s.ExpandSection ? 0 : s.EndBufferSize));
750 }
751 }
752 }
753
754 RELImportEntry* imports = (RELImportEntry*) dataAddr;
755 header->_impOffset = (uint) (dataAddr - address);
756 dataAddr = (VoidPtr) imports + (header->_impSize = (uint) _imports.Keys.Count * RELImportEntry.Size);
757 header->_relOffset = (uint) (dataAddr - address);
758
759 List<uint> k = new List<uint>();
760 foreach (uint s in _imports.Keys)
761 {
762 if (s != ModuleID && s != 0)
763 {
764 k.Add(s);
765 }
766 }
767
768 k.Sort();
769
770 foreach (uint s in _imports.Keys)
771 {
772 if (s == ModuleID)
773 {
774 k.Add(s);
775 break;
776 }
777 }
778
779 foreach (uint s in _imports.Keys)
780 {
781 if (s == 0)
782 {
783 k.Add(s);
784 break;
785 }
786 }
787
788 for (int i = 0; i < k.Count; i++)
789 {
790 uint id = k[i];
791 uint offset = (uint) (dataAddr - address);
792 if (id == ModuleID)
793 {
794 header->_commandOffset = offset;
795 }
796
797 imports[i]._moduleId = id;
798 imports[i]._offset = offset;
799
800 RELLink* link = (RELLink*) dataAddr;
801 foreach (RELLink n in _imports[k[i]])
802 {
803 *link++ = n;
804 }
805
806 dataAddr = link;
807 }
808
809 // Stage module conversion
810 byte* bptr = (byte*) address;
811 if (_stageID != null)
812 {
813 bptr[findStageIDOffset()] = _stageID.Value;
814 }
815 }
Definition: VoidPtr.cs:9
Definition: REL.cs:8
const int Size
Definition: REL.cs:9
const int Size
Definition: REL.cs:71

◆ SaveItems()

void BrawlLib.SSBB.ResourceNodes.RELNode.SaveItems ( )
inline
175 {
176 if (_itemIDOffsets.Length == 0)
177 {
178 return;
179 }
180
181 ModuleSectionNode section = Sections[1];
182
184 new DynamicFileByteProvider(new UnmanagedMemoryStream((byte*) section._dataBuffer.Address,
185 section._dataBuffer.Length, section._dataBuffer.Length, FileAccess.ReadWrite))
186 { _supportsInsDel = false };
187
188 for (int i = 0; i < _itemIDOffsets.Length; i++)
189 {
190 d.WriteByte(_itemIDOffsets[i], _itemIDs[i]);
191 }
192
193 if (!d.HasChanges())
194 {
195 return;
196 }
197
198 UnsafeBuffer newBuffer = new UnsafeBuffer((int)d.Length);
199
200 int amt = Math.Min(section._dataBuffer.Length, newBuffer.Length);
201 if (amt > 0)
202 {
203 Memory.Move(newBuffer.Address, section._dataBuffer.Address, (uint)amt);
204 if (newBuffer.Length - amt > 0)
205 {
206 Memory.Fill(newBuffer.Address + amt, (uint)(newBuffer.Length - amt), 0);
207 }
208 }
209
210 d._stream?.Dispose();
211
212 d._stream = new UnmanagedMemoryStream((byte*)newBuffer.Address, newBuffer.Length, newBuffer.Length,
213 FileAccess.ReadWrite);
214
215 d.ApplyChanges();
216
217 section._dataBuffer.Dispose();
218 section._dataBuffer = newBuffer;
219 section.SignalPropertyChange();
220 d.Dispose();
221 }
Definition: Memory.cs:8
static void Move(VoidPtr dst, VoidPtr src, uint size)
Definition: Memory.cs:9
Definition: UnsafeBuffer.cs:7
VoidPtr Address
Definition: UnsafeBuffer.cs:9
int Length
Definition: UnsafeBuffer.cs:14
Implements a fully editable byte provider for file data of any size.
Definition: DynamicFileByteProvider.cs:14
long Length
See IByteProvider.Length for more information.
Definition: DynamicFileByteProvider.cs:321
void Dispose()
See IDisposable.Dispose for more information.
Definition: DynamicFileByteProvider.cs:452
Stream _stream
Definition: DynamicFileByteProvider.cs:17
void WriteByte(long index, byte value)
See IByteProvider.WriteByte for more information.
Definition: DynamicFileByteProvider.cs:112
bool HasChanges()
See IByteProvider.HasChanges for more information.
Definition: DynamicFileByteProvider.cs:326
void ApplyChanges()
See IByteProvider.ApplyChanges for more information.
Definition: DynamicFileByteProvider.cs:361

◆ UpdateItemIDs()

void BrawlLib.SSBB.ResourceNodes.RELNode.UpdateItemIDs ( )
inline
167 {
168 for (int i = 0; i < _itemIDOffsets?.Length; i++)
169 {
170 _itemIDs[i] = Sections[1]._dataBuffer[_itemIDOffsets[i], 1].Byte;
171 }
172 }
UnsafeBuffer _dataBuffer
Definition: ModuleDataNode.cs:17

Member Data Documentation

◆ _bssAlign

uint BrawlLib.SSBB.ResourceNodes.RELNode._bssAlign = 8

◆ _bssSection

byte BrawlLib.SSBB.ResourceNodes.RELNode._bssSection

◆ _bssSize

uint BrawlLib.SSBB.ResourceNodes.RELNode._bssSize

◆ _epilogOffset

uint BrawlLib.SSBB.ResourceNodes.RELNode._epilogOffset

◆ _epilogSection

byte BrawlLib.SSBB.ResourceNodes.RELNode._epilogSection

◆ _files

Dictionary<uint, RELNode> BrawlLib.SSBB.ResourceNodes.RELNode._files = new Dictionary<uint, RELNode>()
static

◆ _fixSize

uint BrawlLib.SSBB.ResourceNodes.RELNode._fixSize

◆ _id

uint BrawlLib.SSBB.ResourceNodes.RELNode._id

◆ _idNames

SortedList<uint, string> BrawlLib.SSBB.ResourceNodes.RELNode._idNames
static

◆ _impOffset

uint BrawlLib.SSBB.ResourceNodes.RELNode._impOffset

◆ _imports

SortedDictionary<uint, List<RELLink> > BrawlLib.SSBB.ResourceNodes.RELNode._imports = new SortedDictionary<uint, List<RELLink>>()

◆ _impSize

uint BrawlLib.SSBB.ResourceNodes.RELNode._impSize

◆ _infoOffset

uint BrawlLib.SSBB.ResourceNodes.RELNode._infoOffset

◆ _itemIDs

byte [] BrawlLib.SSBB.ResourceNodes.RELNode._itemIDs

◆ _linkNext

int BrawlLib.SSBB.ResourceNodes.RELNode._linkNext

◆ _linkPrev

int BrawlLib.SSBB.ResourceNodes.RELNode._linkPrev

◆ _moduleAlign

uint BrawlLib.SSBB.ResourceNodes.RELNode._moduleAlign = 32

◆ _nameOffset

uint BrawlLib.SSBB.ResourceNodes.RELNode._nameOffset

◆ _nameSize

uint BrawlLib.SSBB.ResourceNodes.RELNode._nameSize

◆ _numSections

uint BrawlLib.SSBB.ResourceNodes.RELNode._numSections

◆ _prologOffset

uint BrawlLib.SSBB.ResourceNodes.RELNode._prologOffset

◆ _prologSection

byte BrawlLib.SSBB.ResourceNodes.RELNode._prologSection

◆ _relOffset

uint BrawlLib.SSBB.ResourceNodes.RELNode._relOffset

◆ _sections

ModuleSectionNode [] BrawlLib.SSBB.ResourceNodes.RELNode._sections

◆ _stageID

byte? BrawlLib.SSBB.ResourceNodes.RELNode._stageID

◆ _unresolvedOffset

uint BrawlLib.SSBB.ResourceNodes.RELNode._unresolvedOffset

◆ _unresolvedSection

byte BrawlLib.SSBB.ResourceNodes.RELNode._unresolvedSection

◆ _version

uint BrawlLib.SSBB.ResourceNodes.RELNode._version

Property Documentation

◆ BSSAlign

uint BrawlLib.SSBB.ResourceNodes.RELNode.BSSAlign
get

◆ BSSSection

uint BrawlLib.SSBB.ResourceNodes.RELNode.BSSSection
get

◆ EpilogSection

uint BrawlLib.SSBB.ResourceNodes.RELNode.EpilogSection
get

◆ FixSize

uint BrawlLib.SSBB.ResourceNodes.RELNode.FixSize
get

◆ ID

new uint BrawlLib.SSBB.ResourceNodes.RELNode.ID
getset

Implements BrawlLib.SSBB.ResourceNodes.ModuleNode.

93 {
94 get => _id;
95 set => _id = value;
96 }

◆ ImportedModules

string [] BrawlLib.SSBB.ResourceNodes.RELNode.ImportedModules
get
145{ get; private set; }

◆ ItemID1

byte? BrawlLib.SSBB.ResourceNodes.RELNode.ItemID1
getset
226 {
227 get => _itemIDs?.Length > 0 ? _itemIDs?[0] : null;
228 set
229 {
230 // Don't try to set the item ID if there are none known
231 if (_itemIDs == null || _itemIDs.Length <= 0 || value == null)
232 {
233 return;
234 }
235
236 _itemIDs[0] = value.Value;
237 SaveItems();
238 }
239 }
void SaveItems()
Definition: RELNode.cs:174

◆ ItemID2

byte? BrawlLib.SSBB.ResourceNodes.RELNode.ItemID2
getset
244 {
245 get => _itemIDs?.Length > 1 ? _itemIDs?[1] : null;
246 set
247 {
248 // Don't try to set the item ID if there are not 2 known
249 if (_itemIDs == null || _itemIDs.Length <= 1 || value == null)
250 {
251 return;
252 }
253
254 _itemIDs[1] = value.Value;
255 SaveItems();
256 }
257 }

◆ ItemID3

byte? BrawlLib.SSBB.ResourceNodes.RELNode.ItemID3
getset
262 {
263 get => _itemIDs?.Length > 2 ? _itemIDs?[2] : null;
264 set
265 {
266 // Don't try to set the item ID if there are not 3 known
267 if (_itemIDs == null || _itemIDs.Length <= 2 || value == null)
268 {
269 return;
270 }
271
272 _itemIDs[2] = value.Value;
273 SaveItems();
274 }
275 }

◆ ItemID4

byte? BrawlLib.SSBB.ResourceNodes.RELNode.ItemID4
getset
280 {
281 get => _itemIDs?.Length > 3 ? _itemIDs?[3] : null;
282 set
283 {
284 // Don't try to set the item ID if there are not 4 known
285 if (_itemIDs == null || _itemIDs.Length <= 3 || value == null)
286 {
287 return;
288 }
289
290 _itemIDs[3] = value.Value;
291 SaveItems();
292 }
293 }

◆ ModuleAlign

uint BrawlLib.SSBB.ResourceNodes.RELNode.ModuleAlign
get

◆ ModuleID

uint BrawlLib.SSBB.ResourceNodes.RELNode.ModuleID
getset
70 {
71 get => _id;
72 set
73 {
74 if (!_files.ContainsKey(value))
75 {
76 //TODO: correct all opened modules that refer to this one via module id
77 //Now won't that be entertaining to code
78
79 _files.Remove(_id);
80 _id = value;
82 _files.Add(_id, this);
83 }
84 else
85 {
86 MessageBox.Show("");
87 }
88 }
89 }
virtual void SignalPropertyChange()
Definition: ResourceNode.cs:313

◆ ModuleName

string BrawlLib.SSBB.ResourceNodes.RELNode.ModuleName
get

◆ NameOffset

uint BrawlLib.SSBB.ResourceNodes.RELNode.NameOffset
getset
112 {
113 get => _nameOffset;
114 set
115 {
116 _nameOffset = value;
118 }
119 }

◆ NameSize

uint BrawlLib.SSBB.ResourceNodes.RELNode.NameSize
getset
123 {
124 get => _nameSize;
125 set
126 {
127 _nameSize = value;
129 }
130 }

◆ PrologSection

uint BrawlLib.SSBB.ResourceNodes.RELNode.PrologSection
get

◆ ResourceFileType

override ResourceType BrawlLib.SSBB.ResourceNodes.RELNode.ResourceFileType
get

◆ Sections

ModuleSectionNode [] BrawlLib.SSBB.ResourceNodes.RELNode.Sections
get

Implements BrawlLib.SSBB.ResourceNodes.ModuleNode.

23 {
24 get
25 {
26 if (_sections == null)
27 {
28 Populate();
29 }
30
31 return _sections;
32 }
33 }

◆ StageID

int? BrawlLib.SSBB.ResourceNodes.RELNode.StageID
getset
152 {
153 get => _stageID;
154 set
155 {
156 if (_stageID == null || value == null)
157 {
158 return;
159 }
160
161 _stageID = (byte) value;
163 }
164 }

◆ UnresolvedSection

uint BrawlLib.SSBB.ResourceNodes.RELNode.UnresolvedSection
get

◆ Version

uint BrawlLib.SSBB.ResourceNodes.RELNode.Version
get

The documentation for this class was generated from the following file: