private boolean read(){
  int magic=endianSwap32(read32());
  if (magic != RCO_MAGIC) {
    log.warn(String.format("Invalid RCO magic 0x%08X",magic));
    return false;
  }
  int version=read32();
  if (log.isDebugEnabled()) {
    log.debug(String.format("RCO version 0x%X",version));
  }
  skip32();
  int compression=read32();
  int umdFlag=compression & 0x0F;
  int headerCompression=(compression & 0xF0) >> 4;
  if (log.isDebugEnabled()) {
    log.debug(String.format("umdFlag=0x%X, headerCompression=0x%X",umdFlag,headerCompression));
  }
  int pMainTable=read32();
  pVSMXTable=read32();
  int pTextTable=read32();
  int pSoundTable=read32();
  int pModelTable=read32();
  int pImgTable=read32();
  skip32();
  int pFontTable=read32();
  int pObjTable=read32();
  int pAnimTable=read32();
  pTextData=read32();
  lTextData=read32();
  pLabelData=read32();
  lLabelData=read32();
  int pEventData=read32();
  int lEventData=read32();
  int pTextPtrs=read32();
  int lTextPtrs=read32();
  int pImgPtrs=read32();
  int lImgPtrs=read32();
  int pModelPtrs=read32();
  int lModelPtrs=read32();
  int pSoundPtrs=read32();
  int lSoundPtrs=read32();
  int pObjPtrs=read32();
  int lObjPtrs=read32();
  int pAnimPtrs=read32();
  int lAnimPtrs=read32();
  pImgData=read32();
  lImgData=read32();
  int pSoundData=read32();
  int lSoundData=read32();
  int pModelData=read32();
  int lModelData=read32();
  skip32();
  skip32();
  skip32();
  if (log.isDebugEnabled()) {
    log.debug(String.format("pMainTable=0x%X, pVSMXTable=0x%X, pTextTable=0x%X, pSoundTable=0x%X, pModelTable=0x%X, pImgTable=0x%X, pFontTable=0x%X, pObjTable=0x%X, pAnimTable=0x%X",pMainTable,pVSMXTable,pTextTable,pSoundTable,pModelTable,pImgTable,pFontTable,pObjTable,pAnimTable));
    log.debug(String.format("TextData=0x%X[0x%X], LabelData=0x%X[0x%X], EventData=0x%X[0x%X]",pTextData,lTextData,pLabelData,lLabelData,pEventData,lEventData));
    log.debug(String.format("TextPtrs=0x%X[0x%X], ImgPtrs=0x%X[0x%X], ModelPtrs=0x%X[0x%X], SoundPtrs=0x%X[0x%X], ObjPtrs=0x%X[0x%X], AnimPtrs=0x%X[0x%X]",pTextPtrs,lTextPtrs,pImgPtrs,lImgPtrs,pModelPtrs,lModelPtrs,pSoundPtrs,lSoundPtrs,pObjPtrs,lObjPtrs,pAnimPtrs,lAnimPtrs));
    log.debug(String.format("ImgData=0x%X[0x%X], SoundData=0x%X[0x%X], ModelData=0x%X[0x%X]",pImgData,lImgData,pSoundData,lSoundData,pModelData,lModelData));
  }
  if (headerCompression != 0) {
    int lenPacked=read32();
    int lenUnpacked=read32();
    int lenLongestText=read32();
    byte[] packedBuffer=readBytes(lenPacked);
    byte[] unpackedBuffer=new byte[lenUnpacked];
    int result;
    if (headerCompression == RCO_DATA_COMPRESSION_RLZ) {
      result=LZR.decompress(unpackedBuffer,lenUnpacked,packedBuffer);
    }
 else {
      log.warn(String.format("Unimplemented compression %d",headerCompression));
      result=-1;
    }
    if (log.isTraceEnabled()) {
      log.trace(String.format("Unpack header longestText=0x%X, result=0x%X: %s",lenLongestText,result,Utilities.getMemoryDump(unpackedBuffer,0,lenUnpacked)));
    }
    if (pTextData != RCO_NULL_PTR && lTextData > 0) {
      seek(pTextData);
      int nextOffset;
      do {
        int textLang=read16();
        skip16();
        nextOffset=read32();
        int textLenPacked=read32();
        int textLenUnpacked=read32();
        byte[] textPackedBuffer=readBytes(textLenPacked);
        byte[] textUnpackedBuffer=new byte[textLenUnpacked];
        if (headerCompression == RCO_DATA_COMPRESSION_RLZ) {
          result=LZR.decompress(textUnpackedBuffer,textLenUnpacked,textPackedBuffer);
        }
 else {
          log.warn(String.format("Unimplemented compression %d",headerCompression));
          result=-1;
        }
        if (log.isTraceEnabled()) {
          log.trace(String.format("Unpack text lang=%d, result=0x%X: %s",textLang,result,Utilities.getMemoryDump(textUnpackedBuffer,0,textLenUnpacked)));
        }
        if (result >= 0) {
          compressedTextDataOffset=extend(compressedTextDataOffset,textLang + 1);
          compressedTextDataOffset[textLang]=unpackedBuffer.length + RCO_HEADER_SIZE;
          unpackedBuffer=append(unpackedBuffer,textUnpackedBuffer);
        }
        if (nextOffset == 0) {
          break;
        }
        skip(nextOffset - 16 - textLenPacked);
      }
 while (nextOffset != 0);
    }
    if (result >= 0) {
      buffer=append(buffer,RCO_HEADER_SIZE,unpackedBuffer);
    }
  }
  events=new HashMap<Integer,String>();
  if (pEventData != RCO_NULL_PTR && lEventData > 0) {
    seek(pEventData);
    while (tell() < pEventData + lEventData) {
      int index=tell() - pEventData;
      String s=readString();
      if (s != null && s.length() > 0) {
        events.put(index,s);
      }
    }
  }
  entries=new HashMap<Integer,RCO.RCOEntry>();
  images=new HashMap<Integer,BufferedImage>();
  objects=new HashMap<Integer,BaseObject>();
  mainTable=readRCOEntry(pMainTable);
  if (log.isDebugEnabled()) {
    log.debug(String.format("mainTable: %s",mainTable));
  }
  if (pObjPtrs != RCO_NULL_PTR) {
    seek(pObjPtrs);
    for (int i=0; i < lObjPtrs; i+=4) {
      int objPtr=read32();
      if (objPtr != 0 && !objects.containsKey(objPtr)) {
        log.warn(String.format("Object 0x%X not read",objPtr));
      }
    }
  }
  if (pImgPtrs != RCO_NULL_PTR) {
    seek(pImgPtrs);
    for (int i=0; i < lImgPtrs; i+=4) {
      int imgPtr=read32();
      if (imgPtr != 0 && !images.containsKey(imgPtr)) {
        log.warn(String.format("Image 0x%X not read",imgPtr));
      }
    }
  }
  RCOContext context=new RCOContext(null,0,events,images,objects);
  for (  BaseObject object : objects.values()) {
    object.init(context);
  }
  return true;
}

private boolean read ( ) { int magic = endianSwap32 ( read32 ( ) ) ; if ( magic != RCO_MAGIC ) { log . warn ( String . format ( "Invalid RCO magic 0x%08X" , magic ) ) ; return false ; } int version = read32 ( ) ; if ( log . isDebugEnabled ( ) ) { log . debug ( String . format ( "RCO version 0x%X" , version ) ) ; } skip32 ( ) ; int compression = read32 ( ) ; int umdFlag = compression & 0x0F ; int headerCompression = ( compression & 0xF0 ) > > 4 ; if ( log . isDebugEnabled ( ) ) { log . debug ( String . format ( "umdFlag=0x%X, headerCompression=0x%X" , umdFlag , headerCompression ) ) ; } int pMainTable = read32 ( ) ; pVSMXTable = read32 ( ) ; int pTextTable = read32 ( ) ; int pSoundTable = read32 ( ) ; int pModelTable = read32 ( ) ; int pImgTable = read32 ( ) ; skip32 ( ) ; int pFontTable = read32 ( ) ; int pObjTable = read32 ( ) ; int pAnimTable = read32 ( ) ; pTextData = read32 ( ) ; lTextData = read32 ( ) ; pLabelData = read32 ( ) ; lLabelData = read32 ( ) ; int pEventData = read32 ( ) ; int lEventData = read32 ( ) ; int pTextPtrs = read32 ( ) ; int lTextPtrs = read32 ( ) ; int pImgPtrs = read32 ( ) ; int lImgPtrs = read32 ( ) ; int pModelPtrs = read32 ( ) ; int lModelPtrs = read32 ( ) ; int pSoundPtrs = read32 ( ) ; int lSoundPtrs = read32 ( ) ; int pObjPtrs = read32 ( ) ; int lObjPtrs = read32 ( ) ; int pAnimPtrs = read32 ( ) ; int lAnimPtrs = read32 ( ) ; pImgData = read32 ( ) ; lImgData = read32 ( ) ; int pSoundData = read32 ( ) ; int lSoundData = read32 ( ) ; int pModelData = read32 ( ) ; int lModelData = read32 ( ) ; skip32 ( ) ; skip32 ( ) ; skip32 ( ) ; if ( log . isDebugEnabled ( ) ) { log . debug ( String . format ( "pMainTable=0x%X, pVSMXTable=0x%X, pTextTable=0x%X, pSoundTable=0x%X, pModelTable=0x%X, pImgTable=0x%X, pFontTable=0x%X, pObjTable=0x%X, pAnimTable=0x%X" , pMainTable , pVSMXTable , pTextTable , pSoundTable , pModelTable , pImgTable , pFontTable , pObjTable , pAnimTable ) ) ; log . debug ( String . format ( "TextData=0x%X[0x%X], LabelData=0x%X[0x%X], EventData=0x%X[0x%X]" , pTextData , lTextData , pLabelData , lLabelData , pEventData , lEventData ) ) ; log . debug ( String . format ( "TextPtrs=0x%X[0x%X], ImgPtrs=0x%X[0x%X], ModelPtrs=0x%X[0x%X], SoundPtrs=0x%X[0x%X], ObjPtrs=0x%X[0x%X], AnimPtrs=0x%X[0x%X]" , pTextPtrs , lTextPtrs , pImgPtrs , lImgPtrs , pModelPtrs , lModelPtrs , pSoundPtrs , lSoundPtrs , pObjPtrs , lObjPtrs , pAnimPtrs , lAnimPtrs ) ) ; log . debug ( String . format ( "ImgData=0x%X[0x%X], SoundData=0x%X[0x%X], ModelData=0x%X[0x%X]" , pImgData , lImgData , pSoundData , lSoundData , pModelData , lModelData ) ) ; } if ( headerCompression != 0 ) { int lenPacked = read32 ( ) ; int lenUnpacked = read32 ( ) ; int lenLongestText = read32 ( ) ; byte [ ] packedBuffer = readBytes ( lenPacked ) ; byte [ ] unpackedBuffer = new byte [ lenUnpacked ] ; int result ; if ( headerCompression == RCO_DATA_COMPRESSION_RLZ ) { result = LZR . decompress ( unpackedBuffer , lenUnpacked , packedBuffer ) ; } else { log . warn ( String . format ( "Unimplemented compression %d" , headerCompression ) ) ; result = - 1 ; } if ( log . isTraceEnabled ( ) ) { log . trace ( String . format ( "Unpack header longestText=0x%X, result=0x%X: %s" , lenLongestText , result , Utilities . getMemoryDump ( unpackedBuffer , 0 , lenUnpacked ) ) ) ; } if ( pTextData != RCO_NULL_PTR && lTextData > 0 ) { seek ( pTextData ) ; int nextOffset ; do { int textLang = read16 ( ) ; skip16 ( ) ; nextOffset = read32 ( ) ; int textLenPacked = read32 ( ) ; int textLenUnpacked = read32 ( ) ; byte [ ] textPackedBuffer = readBytes ( textLenPacked ) ; byte [ ] textUnpackedBuffer = new byte [ textLenUnpacked ] ; if ( headerCompression == RCO_DATA_COMPRESSION_RLZ ) { result = LZR . decompress ( textUnpackedBuffer , textLenUnpacked , textPackedBuffer ) ; } else { log . warn ( String . format ( "Unimplemented compression %d" , headerCompression ) ) ; result = - 1 ; } if ( log . isTraceEnabled ( ) ) { log . trace ( String . format ( "Unpack text lang=%d, result=0x%X: %s" , textLang , result , Utilities . getMemoryDump ( textUnpackedBuffer , 0 , textLenUnpacked ) ) ) ; } if ( result >= 0 ) { compressedTextDataOffset = extend ( compressedTextDataOffset , textLang + 1 ) ; compressedTextDataOffset [ textLang ] = unpackedBuffer . length + RCO_HEADER_SIZE ; unpackedBuffer = append ( unpackedBuffer , textUnpackedBuffer ) ; } if ( nextOffset == 0 ) { break ; } skip ( nextOffset - 16 - textLenPacked ) ; } while ( nextOffset != 0 ) ; } if ( result >= 0 ) { buffer = append ( buffer , RCO_HEADER_SIZE , unpackedBuffer ) ; } } events = new HashMap < Integer , String > ( ) ; if ( pEventData != RCO_NULL_PTR && lEventData > 0 ) { seek ( pEventData ) ; while ( tell ( ) < pEventData + lEventData ) { int index = tell ( ) - pEventData ; String s = readString ( ) ; if ( s != null && s . length ( ) > 0 ) { events . put ( index , s ) ; } } } entries = new HashMap < Integer , RCO . RCOEntry > ( ) ; images = new HashMap < Integer , BufferedImage > ( ) ; objects = new HashMap < Integer , BaseObject > ( ) ; mainTable = readRCOEntry ( pMainTable ) ; if ( log . isDebugEnabled ( ) ) { log . debug ( String . format ( "mainTable: %s" , mainTable ) ) ; } if ( pObjPtrs != RCO_NULL_PTR ) { seek ( pObjPtrs ) ; for ( int i = 0 ; i < lObjPtrs ; i += 4 ) { int objPtr = read32 ( ) ; if ( objPtr != 0 && ! objects . containsKey ( objPtr ) ) { log . warn ( String . format ( "Object 0x%X not read" , objPtr ) ) ; } } } if ( pImgPtrs != RCO_NULL_PTR ) { seek ( pImgPtrs ) ; for ( int i = 0 ; i < lImgPtrs ; i += 4 ) { int imgPtr = read32 ( ) ; if ( imgPtr != 0 && ! images . containsKey ( imgPtr ) ) { log . warn ( String . format ( "Image 0x%X not read" , imgPtr ) ) ; } } } RCOContext context = new RCOContext ( null , 0 , events , images , objects ) ; for ( BaseObject object : objects . values ( ) ) { object . init ( context ) ; } return true ; }
read a rco file . see description of an rco file structure in https : / / github . com / kakaroto / rcomage / blob / master / src / rcofile . h
