brzeszczot

brzeszczot.git
git clone git://git.lenczewski.org/brzeszczot.git
Log | Files | Refs

wad_writer.c (3136B)


      1 #include "libriot/wad.h"
      2 
      3 static b32
      4 riot_wad_chunk_write(struct riot_wad_ctx *ctx, struct riot_wad_chunk *chunk, struct mem_stream *stream);
      5 
      6 b32
      7 riot_wad_write(struct riot_wad_ctx *ctx, void *data, u64 len, struct mem_stream stream) {
      8 	assert(ctx);
      9 
     10 	char magic[2] = { 'R', 'W', };
     11 	if (!mem_stream_push(&stream, magic, sizeof magic)) {
     12 		errlog("Failed to write WAD magic");
     13 		return false;
     14 	}
     15 
     16 	if (!riot_mem_stream_write_u8(&stream, 3)) {
     17 		errlog("Failed to write WAD version major");
     18 		return false;
     19 	}
     20 
     21 	if (!riot_mem_stream_write_u8(&stream, 1)) {
     22 		errlog("Failed to write WAD version minor");
     23 		return false;
     24 	}
     25 
     26 	u32 ecdsa_signature_length = 256;
     27 	u8 signature[ecdsa_signature_length];
     28 	memset(signature, 0, ecdsa_signature_length);
     29 	if (!mem_stream_push(&stream, signature, ecdsa_signature_length)) {
     30 		errlog("Failed to write v3 signature (%u bytes)", ecdsa_signature_length);
     31 		return false;
     32 	}
     33 
     34 	u64 checksum = 0;
     35 	if (!riot_mem_stream_write_u64(&stream, checksum)) {
     36 		errlog("Failed to write v3 signature checksum");
     37 		return false;
     38 	}
     39 
     40 	if (!riot_mem_stream_write_u32(&stream, ctx->wad.chunk_count)) {
     41 		errlog("Failed to write WAD chunk count");
     42 		return false;
     43 	}
     44 
     45 	for (u32 i = 0; i < ctx->wad.chunk_count; i++) {
     46 		struct riot_wad_chunk *chunk = (struct riot_wad_chunk *)ctx->chunk_pool.ptr + i;
     47 		if (!riot_wad_chunk_write(ctx, chunk, &stream)) {
     48 			errlog("Failed to write WAD chunk %u/%u", i + 1, ctx->wad.chunk_count);
     49 			return false;
     50 		}
     51 	}
     52 
     53 	if (!mem_stream_push(&stream, data, len)) {
     54 		errlog("Failed to write WAD data segment");
     55 		return false;
     56 	}
     57 
     58 	return true;
     59 }
     60 
     61 static b32
     62 riot_wad_chunk_write(struct riot_wad_ctx *ctx, struct riot_wad_chunk *chunk, struct mem_stream *stream) {
     63 	assert(ctx);
     64 	assert(chunk);
     65 	assert(stream);
     66 
     67 	if (!riot_mem_stream_write_xxh64_u64(stream, chunk->path_hash)) {
     68 		errlog("Failed to write WAD chunk path hash");
     69 		return false;
     70 	}
     71 
     72 	if (!riot_mem_stream_write_u32(stream, chunk->data_offset)) {
     73 		errlog("Failed to write WAD chunk data offset");
     74 		return false;
     75 	}
     76 
     77 	if (!riot_mem_stream_write_u32(stream, chunk->compressed_size)) {
     78 		errlog("Failed to write WAD chunk compressed data size");
     79 		return false;
     80 	}
     81 
     82 	if (!riot_mem_stream_write_u32(stream, chunk->decompressed_size)) {
     83 		errlog("Failed to write WAD chunk decompressed data size");
     84 		return false;
     85 	}
     86 
     87 	u8 sub_chunk_count_and_compression_type = 0;
     88 	sub_chunk_count_and_compression_type |= (chunk->sub_chunk_count << 4);
     89 	sub_chunk_count_and_compression_type |= (u8)chunk->compression & 0xf;
     90 	if (!riot_mem_stream_write_u8(stream, sub_chunk_count_and_compression_type)) {
     91 		errlog("Failed to write WAD chunk sub-chunk count and compression type byte");
     92 		return false;
     93 	}
     94 
     95 	if (!riot_mem_stream_write_b8(stream, chunk->duplicated)) {
     96 		errlog("Failed to write WAD chunk duplicated flag");
     97 		return false;
     98 	}
     99 
    100 	if (!riot_mem_stream_write_u16(stream, chunk->sub_chunk_start)) {
    101 		errlog("Failed to write WAD chunk sub-chunk start");
    102 		return false;
    103 	}
    104 
    105 	u64 checksum = 0;
    106 	if (!riot_mem_stream_write_u64(stream, checksum)) {
    107 		errlog("Failed to write WAD chunk checksum");
    108 		return false;
    109 	}
    110 
    111 	return true;
    112 }