コード例 #1
0
ファイル: rcowriter.c プロジェクト: Gatz85/RCOMage
uint32_t
write_text_hash_table (rRCOFile_writehelper * rcoH, rRCOEntry * entry,
    rRCOFile * rco)
{
  uint32_t num = ((rRCOTextEntry *) entry->extra)->numIndexes;

  if (!num)
    return 0;

  uint32_t *hashTable = (uint32_t *) malloc (num * sizeof (uint32_t));

  memset (hashTable, 0, num * sizeof (uint32_t));
  uint32_t i;

  for (i = 0; i < num; i++) {
    RCOTextIndex *ti = &(((rRCOTextEntry *) entry->extra)->indexes[i]);

    if (ti->labelOffset != RCO_NULL_PTR) {
      uint32_t *hashPtr =
	  &hashTable[calc_hash (rco->labels + ti->labelOffset, hashTable, num)];
      *hashPtr =
	  entry->offset + sizeof (RCOEntry) + sizeof (RCOTextEntry) +
	  i * sizeof (RCOTextIndex);
      if (rco->eSwap)
	*hashPtr = ENDIAN_SWAP (*hashPtr);
    }
  }

  // write it
  rco_fwrite (rcoH, hashTable, num * sizeof (uint32_t));

  free (hashTable);
  return num;
}
コード例 #2
0
ファイル: loader_ani.c プロジェクト: Limsik/e17
static MsChunk*
ani_load_chunk(MsAni *ani)
{
  DATA32   chunk_id, chunk_size, dummy;
  MsChunk *chunk;

  if (ani->cp >= ani->data_size + 8)
    return NULL;

  ani->cp += ani_read_int32(ani->fp, &chunk_id, 1);

  while (chunk_id == 0x5453494C)
    {
      D("Skipping LIST chunk header ...\n");
      ani->cp += ani_read_int32(ani->fp, &dummy, 1);
      ani->cp += ani_read_int32(ani->fp, &dummy, 1);
      ani->cp += ani_read_int32(ani->fp, &chunk_id, 1);
    }

  ani->cp += ani_read_int32(ani->fp, &chunk_size, 1);

  /* Pad it up to word length */
  if (chunk_size % 2)
    chunk_size += (2 - (chunk_size % 2));

  chunk = (MsChunk*) calloc(1, sizeof(MsChunk*) + 2 * sizeof(DATA32) + chunk_size);

  if (!chunk)
    {
      D("Warning, failed to allocate ANI chunk of size %d\n", sizeof(MsChunk*)
		      + 2 * sizeof(DATA32) + chunk_size);
      return NULL;
    }

  chunk->chunk_id = chunk_id;
  chunk->chunk_size = chunk_size;

  chunk_id = ENDIAN_SWAP(chunk_id);

  D("Loaded chunk with ID '%c%c%c%c' and length %i\n",
    ((char*)&chunk_id)[0], ((char*)&chunk_id)[1],
    ((char*)&chunk_id)[2], ((char*)&chunk_id)[3], chunk_size);
  
  ani->cp += ani_read_int8(ani->fp, &chunk->data, chunk_size);
  
  return chunk;
}
コード例 #3
0
ファイル: loader_ani.c プロジェクト: Limsik/e17
static int
ani_read_int32 (FILE     *fp,
		DATA32   *data,
		int       count)
{
  int i, total;

  total = count;
  if (count > 0)
    {
      ani_read_int8 (fp, (DATA8*) data, count * 4);
      for (i = 0; i < count; i++)
         data[i] = ENDIAN_SWAP(data[i]);
    }

  return total * 4;
}
コード例 #4
0
ファイル: rcowriter.c プロジェクト: Gatz85/RCOMage
void
do_hashing (rRCOEntry * entry, rRCOFile * rco, uint8_t recurse,
    uint32_t * hashTable, uint32_t hashTableSize)
{
  if (entry->labelOffset != RCO_NULL_PTR) {
    uint32_t *hashPtr =
	&hashTable[calc_hash (rco->labels + entry->labelOffset, hashTable,
	    hashTableSize)];

    *hashPtr = entry->offset;
    if (rco->eSwap)
      *hashPtr = ENDIAN_SWAP (*hashPtr);
  }
  if (recurse) {
    rRCOEntry *rcoNode;

    for (rcoNode = entry->firstChild; rcoNode; rcoNode = rcoNode->next)
      do_hashing (rcoNode, rco, recurse, hashTable, hashTableSize);
  }
}
コード例 #5
0
      SRC_REL(ABSOLUTE),
      SRC_SEL_X(SQ_SEL_X),
      MEGA_FETCH_COUNT(16)),
    VTX_DWORD1_GPR(DST_GPR(0),
      DST_REL(0),
      DST_SEL_X(SQ_SEL_X),
      DST_SEL_Y(SQ_SEL_Y),
      DST_SEL_Z(SQ_SEL_Z),
      DST_SEL_W(SQ_SEL_W),
      USE_CONST_FIELDS(0),
      DATA_FORMAT(FMT_32_32_32_32_FLOAT),
      NUM_FORMAT_ALL(SQ_NUM_FORMAT_SCALED),
      FORMAT_COMP_ALL(SQ_FORMAT_COMP_SIGNED),
      SRF_MODE_ALL(SRF_MODE_ZERO_CLAMP_MINUS_ONE)),
    VTX_DWORD2(OFFSET(0),
      ENDIAN_SWAP(SQ_ENDIAN_NONE),
      CONST_BUF_NO_STRIDE(0),
      MEGA_FETCH(1)),
    VTX_DWORD_PAD
};


/*
pixel shader

00 TEX: ADDR(2) CNT(1) VALID_PIX
      0  SAMPLE R0, v0.xy01, t0, s0
      1  SAMPLE R1, v0.xy01, t0, s1

01 EXP_DONE: PIX0, R0
コード例 #6
0
ファイル: rcowriter.c プロジェクト: Gatz85/RCOMage
// returns next entry offset (like the length, but the last entry returns zero)
//
// - doesn't really have much meaning - it's primarily used for internal
// purposes
uint32_t
write_entry (rRCOFile_writehelper * rcoH, rRCOEntry * entry,
    uint32_t parentOffset, uint32_t prevOffset, uint8_t isLastSubentry)
{
  uint32_t fPos = rcowrite_ftell (rcoH);

  entry->offset = fPos;
  RCOEntry re;

  re.typeId = (entry->id << 8) | (entry->type);
  re.blank = 0;
  re.labelOffset = entry->labelOffset;

  if (entry->type == 0 || ((entry->id == RCO_TABLE_MAIN ||
	      entry->id == RCO_TABLE_ANIM)
	  && entry->type == 1)) {
    // a "parent" entry
    re.eHeadSize = 0;
    re.entrySize = sizeof (RCOEntry);

    // anim main tables have a prevOffset though :/ (object main tables don't)
    if (entry->id == RCO_TABLE_ANIM)
      re.prevEntryOffset = prevOffset;
    else
      re.prevEntryOffset = 0;
  } else {
    re.eHeadSize = sizeof (RCOEntry);
    re.entrySize = 0;

    // not sure why, but it appears that "non-main" object/anim entries also
    // have the total size of the entry stored in entrySize; only done if the
    // entry has subentries
    if ((entry->id == RCO_TABLE_OBJ || entry->id == RCO_TABLE_ANIM)
	&& entry->numSubentries) {
      int lenNum =
	  (entry->id ==
	  RCO_TABLE_OBJ ? RCO_OBJ_EXTRA_LEN_NUM : RCO_ANIM_EXTRA_LEN_NUM);
      const int *lenArray;

      lenArray =
	  (entry->id == RCO_TABLE_OBJ ? RCO_OBJ_EXTRA_LEN : RCO_ANIM_EXTRA_LEN);
      if (entry->type <= lenNum && lenArray[entry->type] > 0)
	re.entrySize =
	    sizeof (RCOEntry) + lenArray[entry->type] * sizeof (uint32_t);
    }

    re.prevEntryOffset = prevOffset;
  }
  re.numSubentries = entry->numSubentries;
  re.parentTblOffset = fPos - parentOffset;
  re.blanks[0] = re.blanks[1] = 0;
  re.nextEntryOffset = 0;

  if (entry->rco->eSwap)
    es_rcoEntry (&re);
  rco_fwrite (rcoH, &re, sizeof (re));
  if (entry->rco->eSwap)
    es_rcoEntry (&re);

  // extra items here
  switch (entry->id) {
    case RCO_TABLE_VSMX:
      if (entry->type == 1) {
	RCOVSMXEntry rve;

	rve.offset = 0;
	rve.length = entry->srcLenUnpacked;
	if (entry->rco->eSwap)
	  es_rcoVsmxEntry (&rve);
	rco_fwrite (rcoH, &rve, sizeof (rve));

	uint32_t vsmxLen = 0;
	uint8_t *bufferVSMX = (uint8_t *) read_resource (entry, &vsmxLen);

	if (bufferVSMX) {
	  if (vsmxLen == entry->srcLenUnpacked)
	    rco_fwrite (rcoH, bufferVSMX, vsmxLen);
	  free (bufferVSMX);
	}
      }
      break;
    case RCO_TABLE_TEXT:
      if (entry->type == 1) {
	RCOTextEntry rte;
	rRCOTextEntry *src = (rRCOTextEntry *) entry->extra;
	uint32_t i;

	rte.lang = src->lang;
	rte.format = src->format;
	rte.numIndexes = src->numIndexes;
	if (entry->rco->eSwap)
	  es_rcoTextEntry (&rte);
	rco_fwrite (rcoH, &rte, sizeof (rte));

	// instead of blindly dumping src->indexes, we'll "pack" the entries
	// together (allows source file to be of a different format, ie INI)
	uint32_t entryTextOffset = rcoH->sizeText;

	for (i = 0; i < src->numIndexes; i++) {
	  RCOTextIndex rti;

	  rti.labelOffset = src->indexes[i].labelOffset;
	  rti.length = src->indexes[i].length;
	  // Sony is doing some weird stuff :|
	  if (src->indexes[i].offset == RCO_NULL_PTR)
	    rti.offset = RCO_NULL_PTR;
	  else if (rti.length) {
	    if (rcoH->tables)	// compressing - we need to make the offset
	      // relative to the section of text data
	      rti.offset = rcoH->sizeText - entryTextOffset;
	    else
	      rti.offset = rcoH->sizeText;
	  } else		// TODO: experimental (it seems that Sony likes
	    //
	    // sticking in a weird pointer for a blank text
	    // entry)
	    rti.offset = entryTextOffset - 1;

	  rcoH->sizeText += rti.length;	// doesn't have trailing null, so no +1
	  //
	  // needed
	  // align to 4 byte boundary
	  rcoH->sizeText = ALIGN_TO_4 (rcoH->sizeText);

	  if (entry->rco->eSwap)
	    es_rcoTextIndex (&rti);
	  rco_fwrite (rcoH, &rti, sizeof (rti));
	}

	if (rcoH->sizeText - entryTextOffset > rcoH->longestLangData)
	  rcoH->longestLangData = rcoH->sizeText - entryTextOffset;
      }
      break;
    case RCO_TABLE_IMG:
    case RCO_TABLE_MODEL:
      if (entry->type == 1) {
	rRCOImgModelEntry *srcExtra = (rRCOImgModelEntry *) entry->extra;
	RCOImgModelEntry rie;
	uint32_t *totalResSize =
	    (entry->id ==
	    RCO_TABLE_IMG ? &(rcoH->sizeImg) : &(rcoH->sizeModel));
	rie.format = srcExtra->format;
	// we've already got the compression info done here, so just copy it
	// over
	rie.compression = entry->srcCompression | (srcExtra->unkCompr << 8);
	rie.offset = *totalResSize;
	rie.sizeUnpacked = entry->srcLenUnpacked;
	rie.sizePacked = entry->srcLen;
	*totalResSize += rie.sizePacked;
	// align to 4 byte boundary
	*totalResSize = ALIGN_TO_4 (*totalResSize);

	if (entry->rco->eSwap)
	  es_rcoImgModelEntry (&rie);

	// we'll omit the packed length value if this is an uncompressed entry
	if (entry->rco->ps3) {	// PS3 image quirk
	  uint32_t one = ENDIAN_SWAP (1);

	  rco_fwrite (rcoH, &rie, sizeof (rie) - sizeof (uint32_t));
	  rco_fwrite (rcoH, &one, sizeof (one));
	  if (entry->srcCompression != RCO_DATA_COMPRESSION_NONE)
	    rco_fwrite (rcoH, &rie.sizeUnpacked, sizeof (rie.sizeUnpacked));
	} else {
	  rco_fwrite (rcoH, &rie,
	      sizeof (rie) - (entry->srcCompression ==
		  RCO_DATA_COMPRESSION_NONE ? sizeof (uint32_t) : 0));
	}
      }
      break;
    case RCO_TABLE_SOUND:
      if (entry->type != 0) {
	rRCOSoundEntry *srcExtra = (rRCOSoundEntry *) entry->extra;
	RCOSoundEntry rse;
	uint32_t rseOffset;

	rse.format = srcExtra->format;
	rseOffset = rse.offset = rcoH->sizeSound;
	rse.channels = srcExtra->channels;
	rse.sizeTotal = entry->srcLenUnpacked;

	rcoH->sizeSound += rse.sizeTotal;
	// align to 4 byte boundary
	rcoH->sizeSound = ALIGN_TO_4 (rcoH->sizeSound);

	if (entry->rco->eSwap)
	  es_rcoSoundEntry (&rse);
	rco_fwrite (rcoH, &rse, sizeof (rse));

	// write size/offset pairs
	uint32_t i;

	// TODO: might actually restrict this to two channels later on
	for (i = 0; i < srcExtra->channels; i++) {
	  uint32_t stuffToWrite[] = { srcExtra->channelData[i * 2],
	    srcExtra->channelData[i * 2 + 1] + rseOffset
	  };
	  if (entry->rco->eSwap) {
	    stuffToWrite[0] = ENDIAN_SWAP (stuffToWrite[0]);
	    stuffToWrite[1] = ENDIAN_SWAP (stuffToWrite[1]);
	  }
	  rco_fwrite (rcoH, stuffToWrite, sizeof (stuffToWrite));
	}
	if (srcExtra->channels < 2) {
	  // we'll write an extra blank channel, complying with how Sony's RCO
	  // tools work
	  uint32_t stuffToWrite[] = { 0, RCO_NULL_PTR };
	  uint32_t i;

	  // actually, the following is unnecessary, but we'll keep it here for
	  //
	  // reference sake
	  if (entry->rco->eSwap) {
	    stuffToWrite[0] = ENDIAN_SWAP (stuffToWrite[0]);
	    stuffToWrite[1] = ENDIAN_SWAP (stuffToWrite[1]);
	  }
	  for (i = srcExtra->channels; i < 2; i++)
	    rco_fwrite (rcoH, &stuffToWrite, sizeof (uint32_t) * 2);
	}
      }
      break;
    case RCO_TABLE_FONT:
      if (entry->type == 1) {
	RCOFontEntry rfe;
	rRCOFontEntry *srcExtra = (rRCOFontEntry *) entry->extra;

	rfe.format = srcExtra->format;
	rfe.compression = srcExtra->compression;
	rfe.unknown = srcExtra->unknown;
	rfe.unknown2 = srcExtra->unknown2;
	if (entry->rco->eSwap)
	  es_rcoFontEntry (&rfe);
	rco_fwrite (rcoH, &rfe, sizeof (rfe));
      }
      break;
    case RCO_TABLE_OBJ:
    case RCO_TABLE_ANIM:
      if (entry->type != 0) {
	int lenNum;

	lenNum =
	    (entry->id ==
	    RCO_TABLE_OBJ ? RCO_OBJ_EXTRA_LEN_NUM : RCO_ANIM_EXTRA_LEN_NUM);
	const int *lenArray;

	lenArray =
	    (entry->id ==
	    RCO_TABLE_OBJ ? RCO_OBJ_EXTRA_LEN : RCO_ANIM_EXTRA_LEN);
	// just allocate space because we need to fix this later on
	if (entry->type <= lenNum && lenArray[entry->type] > 0) {
	  uint32_t anAwesomeVariable = lenArray[entry->type];

	  while (anAwesomeVariable--)
	    rco_fwrite (rcoH, &anAwesomeVariable, sizeof (anAwesomeVariable));
	} else {
	  // TODO: do something if type is unknown
	}
      }
      break;
  }

  // subentries
  uint32_t nextOffset = 0;
  rRCOEntry *rcoNode;

  for (rcoNode = entry->firstChild; rcoNode; rcoNode = rcoNode->next) {
    nextOffset =
	write_entry (rcoH, rcoNode, fPos, nextOffset,
	(rcoNode->next ? FALSE : TRUE));
  }

  // write nextEntryOffset
  if (!isLastSubentry) {
    uint32_t curPos = rcowrite_ftell (rcoH);

    re.nextEntryOffset = curPos - fPos;
    rcowrite_fseek (rcoH, fPos);
    if (entry->rco->eSwap)
      es_rcoEntry (&re);
    rco_fwrite (rcoH, &re, sizeof (re));
    if (entry->rco->eSwap)
      es_rcoEntry (&re);
    rcowrite_fseek (rcoH, curPos);
  }
  return re.nextEntryOffset;
}
コード例 #7
0
ファイル: rcowriter.c プロジェクト: Gatz85/RCOMage
void
rco_write_fix_refs (rRCOEntry * parent, rRCOFile_writehelper * rcoH,
    rRCOFile * rco, const int *lenArray, const int lenNum, uint8_t isObj)
{
  rRCOEntry *rcoNode;

  for (rcoNode = parent->firstChild; rcoNode; rcoNode = rcoNode->next) {
    rcowrite_fseek (rcoH, rcoNode->offset + sizeof (RCOEntry));
    uint32_t j, j2;
    uint8_t *extraPtr = (uint8_t *) rcoNode->extra;

    if (rcoNode->type <= lenNum && lenArray[rcoNode->type] > 0) {
      const int *typeArray =
	  (isObj ? RCO_OBJ_EXTRA_TYPES[rcoNode->
	      type] : RCO_ANIM_EXTRA_TYPES[rcoNode->type]);
      for (j = 0, j2 = 0; (int) j < lenArray[rcoNode->type]; j++, j2++) {
	uint8_t cond;

	if (isObj)
	  cond = (RCO_OBJ_IS_REF (rcoNode->type, j2));
	else			// anim
	  cond = (RCO_ANIM_IS_REF (rcoNode->type, j2));
	// cond = (RCO_ANIM_EXTRA_REFS[rcoNode->type] && j == 0);
	if (cond) {
	  rRCORef *srcRef = (rRCORef *) extraPtr;
	  RCOReference destRef;

	  destRef.type = srcRef->type;

	  switch (destRef.type) {
	    case RCO_REF_EVENT:
	      // destRef.ptr = ((char*)(srcRef->ptr)) - rco->events;
	      destRef.ptr = srcRef->rawPtr;
	      break;
	    case RCO_REF_NONE:
	      destRef.ptr = RCO_NULL_PTR;
	      break;
	    case RCO_REF_TEXT:
	      destRef.ptr = srcRef->rawPtr;
	      break;
	    case RCO_REF_IMG:
	    case RCO_REF_MODEL:
	    case RCO_REF_FONT:
	    case RCO_REF_OBJ2:
	    case RCO_REF_ANIM:
	    case RCO_REF_OBJ:
	      if (srcRef->ptr)
		destRef.ptr = ((rRCOEntry *) (srcRef->ptr))->offset;
	      break;
	    default:
	      destRef.ptr = srcRef->rawPtr;
	  }

	  if (rco->eSwap) {
#define ENDIAN_SWAP_HALF32(x) (((x) & 0xFF) << 8 | ((x) & 0xFF00) >> 8 | ((x) & 0xFF0000) << 8 | ((x) & 0xFF000000) >> 8)
	    destRef.type = ENDIAN_SWAP_HALF32 (destRef.type);
	    destRef.ptr = ENDIAN_SWAP (destRef.ptr);
	  }
	  rco_fwrite (rcoH, &destRef, sizeof (destRef));

	  extraPtr += sizeof (rRCORef);
	  j++;
	  // if(!isObj) j2--;
	} else {
	  if (rco->eSwap && typeArray[j2] != RCO_OBJ_EXTRA_TYPE_UNK) {
	    uint32_t val = *(uint32_t *) extraPtr;

	    val = ENDIAN_SWAP (val);
	    rco_fwrite (rcoH, &val, sizeof (val));
	  } else
	    rco_fwrite (rcoH, extraPtr, sizeof (uint32_t));
	  extraPtr += sizeof (uint32_t);
	}
      }
    } else {
      // TODO: think up something for unknown object types
    }
    rco_write_fix_refs (rcoNode, rcoH, rco, lenArray, lenNum, isObj);
  }
}