Example #1
0
int load_module_info (struct prx *p)
{
  struct prx_modinfo *info;
  uint32 offset;
  p->modinfo = NULL;
  if (p->phnum > 0)
    offset = p->programs[0].paddr & 0x7FFFFFFF;
  else {
    error (__FILE__ ": can't find module info for PRX");
    return 0;
  }

  info = (struct prx_modinfo *) xmalloc (sizeof (struct prx_modinfo));
  p->modinfo = info;

  info->attributes = read_uint16_le (&p->data[offset]);
  info->version = read_uint16_le (&p->data[offset+2]);
  info->name = (const char *) &p->data[offset+4];
  info->gp = read_uint32_le (&p->data[offset+32]);
  info->expvaddr = read_uint32_le (&p->data[offset+36]);
  info->expvaddrbtm = read_uint32_le (&p->data[offset+40]);
  info->impvaddr = read_uint32_le (&p->data[offset+44]);
  info->impvaddrbtm = read_uint32_le (&p->data[offset+48]);

  info->imports = NULL;
  info->exports = NULL;

  if (!check_module_info (p)) return 0;

  if (!load_module_imports (p)) return 0;
  if (!load_module_exports (p)) return 0;

  return 1;
}
Example #2
0
static void parse_stat(const char *p, const char *end, ml_art **art)
{
    int header = read_sint32_le(&p, end);
    int width = read_sint16_le(&p, end);
    int height = read_sint16_le(&p, end);

    const char *line_start_offsets[512];

    const char *start = p + height * 2;

    //printf("%d %d\n", width, height);
    assert(height <= sizeof(line_start_offsets)/sizeof(line_start_offsets[0]));

    for (int i = 0; i < height; i++)
    {
        line_start_offsets[i] = start + 2 * read_uint16_le(&p, end);
    }

    int art_size = sizeof(ml_art) + 2 * width * height;

    *art = (ml_art *)malloc(art_size);

    (*art)->width = width;
    (*art)->height = height;

    uint16_t *target_data = (*art)->data;
    memset(target_data, 0, 2 * width * height);

    for (int i = 0; i < height; i++)
    {
        uint16_t *w = target_data + i * width;
        p = line_start_offsets[i];

        while (true)
        {
            int skip = read_sint16_le(&p, end);
            int length = read_sint16_le(&p, end);

            if (skip == 0 && length == 0)
            {
                break;
            }

            w += skip;
            for (int j = 0; j < length; j++)
            {
                *w = read_uint16_le(&p, end);
                // set alpha...
                if (*w) { *w |= 0x8000; }
                w += 1;
            }
        }
    }
}
Example #3
0
static void parse_cliloc(const char *p, const char *end)
{
    int a = read_uint32_le(&p, end);
    int b = read_uint16_le(&p, end);

    const char *start = p;

    // first go through it one pass to count the number of strings and total string size
    int string_count = 0;
    int total_string_size = 0;
    while(p < end)
    {
        read_uint32_le(&p, end);
        read_uint8(&p, end);
        int length = read_uint16_le(&p, end);
        p += length;
        if (length > 0)
        {
            string_count += 1;
            total_string_size += length + 1; // include null terminator
        }
    }

    // rewind
    p = start;

    cliloc_entry_count = string_count;
    cliloc_entries = (ml_cliloc_entry *)malloc(sizeof(ml_cliloc_entry) * string_count);

    int next_index = 0;
    while(p < end)
    {
        int id = read_sint32_le(&p, end);
        read_uint8(&p, end);

        int length = read_uint16_le(&p, end);
        if (length > 0)
        {
            ml_cliloc_entry *entry = &cliloc_entries[next_index];
            entry->id = id;
            char *s = (char *)malloc(length+1);
            s[length-1] = '\0';
            read_ascii_fixed(&p, end, s, length);
            entry->s = s;
            next_index += 1;
        }
    }

    for (int i = 0; i < string_count; i++)
    {
        ml_cliloc_entry *entry = &cliloc_entries[i];
        //printf("%d, %d: %s\n", i, entry->id, entry->s);
    }
}
Example #4
0
static void parse_tiledata(const char *p, const char *end)
{
    int remaining_bytes = (int)(end - p);
    int block_count = (remaining_bytes-512*32*(8+2+20)) / (4 + 32*(8+1+1+4+2+2+2+1+20));
    item_data_entry_count = 32*block_count;

    tile_datas = (ml_tile_data_entry *)malloc(512*32*sizeof(ml_tile_data_entry));
    item_datas = (ml_item_data_entry *)malloc(item_data_entry_count * sizeof(ml_item_data_entry));

    // 512*4 + 512*32*(8+2+20) bytes
    // first, 512 land data
    for (int i = 0; i < 512*32; i++)
    {
        // every 32 entries have a header of unknown use
        if (i % 32 == 0)
        {
            read_uint32_le(&p, end);
        }
        ml_tile_data_entry *tile_data = &tile_datas[i];
        tile_data->flags = read_uint64_le(&p, end);
        tile_data->texture = read_uint16_le(&p, end); // hmm can this be used instead of the rotation of land gfx?
        read_ascii_fixed(&p, end, tile_data->name, 20);

        //printf("%d: %08llx %d %s\n", i, (unsigned long long)flags, texture, name);
    }

    int i = 0;
    while (p < end)
    {
        // every 32 entries have a header of unknown use
        if (i % 32 == 0)
        {
            read_uint32_le(&p, end);
        }

        ml_item_data_entry *item_data = &item_datas[i];

        item_data->flags = read_uint64_le(&p, end);
        item_data->weight = read_uint8(&p, end);
        item_data->quality = read_uint8(&p, end);
        item_data->quantity = read_uint32_le(&p, end);
        item_data->animation = read_uint16_le(&p, end);
        read_uint16_le(&p, end);
        read_uint16_le(&p, end);
        item_data->height = read_uint8(&p, end);
        read_ascii_fixed(&p, end, item_data->name, 20);
        //printf("%d: %08llx %d %s\n", i, (unsigned long long)flags, animation, name);

        i += 1;
    }
}
Example #5
0
static
int load_module_exports (struct prx *p)
{
  uint32 i = 0, offset;
  struct prx_modinfo *info = p->modinfo;
  if (!info->expvaddr) return 1;

  info->exports = (struct prx_export *) xmalloc (info->numexports * sizeof (struct prx_export));
  memset (info->exports, 0, info->numexports * sizeof (struct prx_export));

  offset = prx_translate (p, info->expvaddr);
  for (i = 0; i < info->numexports; i++) {
    struct prx_export *exp = &info->exports[i];
    exp->namevaddr = read_uint32_le (&p->data[offset]);
    exp->flags = read_uint32_le (&p->data[offset+4]);
    exp->size = p->data[offset+8];
    exp->nvars = p->data[offset+9];
    exp->nfuncs = read_uint16_le (&p->data[offset+10]);
    exp->expvaddr = read_uint32_le (&p->data[offset+12]);

    if (!check_module_export (p, i)) return 0;

    if (exp->namevaddr)
      exp->name = (const char *) &p->data[prx_translate (p, exp->namevaddr)];
    else
      exp->name = "syslib";

    if (!load_module_export (p, exp)) return 0;
    offset += exp->size << 2;
  }
  return 1;
}
Example #6
0
static
int load_module_imports (struct prx *p)
{
  uint32 i = 0, offset;
  struct prx_modinfo *info = p->modinfo;
  if (!info->impvaddr) return 1;

  info->imports = (struct prx_import *) xmalloc (info->numimports * sizeof (struct prx_import));
  memset (info->imports, 0, info->numimports * sizeof (struct prx_import));

  offset = prx_translate (p, info->impvaddr);
  for (i = 0; i < info->numimports; i++) {
    struct prx_import *imp = &info->imports[i];
    imp->namevaddr = read_uint32_le (&p->data[offset]);
    imp->flags = read_uint32_le (&p->data[offset+4]);
    imp->size = p->data[offset+8];
    imp->nvars = p->data[offset+9];
    imp->nfuncs = read_uint16_le (&p->data[offset+10]);
    imp->nidsvaddr = read_uint32_le (&p->data[offset+12]);
    imp->funcsvaddr = read_uint32_le (&p->data[offset+16]);
    if (imp->nvars) imp->varsvaddr = read_uint32_le (&p->data[offset+20]);

    if (!check_module_import (p, i)) return 0;

    if (imp->namevaddr)
      imp->name = (const char *) &p->data[prx_translate (p, imp->namevaddr)];
    else
      imp->name = NULL;

    if (!load_module_import (p, imp)) return 0;
    offset += imp->size << 2;
  }
  return 1;
}
Example #7
0
static void parse_gump(const char *p, const char *end, int width, int height, ml_gump **g)
{
    int line_start_offsets[512];
    assert(height < sizeof(line_start_offsets)/sizeof(line_start_offsets[0]));

    const char *start = p;

    for (int i = 0; i < height; i++)
    {
        line_start_offsets[i] = read_uint32_le(&p, end);
        //printf("%d %d\n", i, line_start_offsets[i]);
    }

    int gump_size = sizeof(ml_gump) + 2 * width * height;
    *g = (ml_gump *)malloc(gump_size);
    (*g)->width = width;
    (*g)->height = height;
    uint16_t *target_data = (*g)->data;
    memset(target_data, 0, 2 * width * height);

    for (int i = 0; i < height; i++)
    {
        uint16_t *w = target_data + i * width;
        p = start + line_start_offsets[i] * 4;

        int accum_length = 0;

        while (accum_length < width)
        {
            uint16_t color = read_uint16_le(&p, end);
            int length = read_uint16_le(&p, end);

            for (int j = 0; j < length; j++)
            {
                *w = color;
                // set alpha...
                if (*w) { *w |= 0x8000; }
                w += 1;
            }


            accum_length += length;
        }
    }
}
Example #8
0
static void parse_hues(const char *p, const char *end)
{
    hues = (ml_hue *)malloc(sizeof(ml_hue)*8*375);
    for (int i = 0; i < 8*375; i++)
    {
        // every eighth hue is prepended by an unknown header
        if (i % 8 == 0)
        {
            read_uint32_le(&p, end);
        }

        ml_hue *hue = &hues[i];
        for (int j = 0; j < 32; j++)
        {
            hue->colors[j] = read_uint16_le(&p, end);
        }
        hue->start_color = read_uint16_le(&p, end);
        hue->end_color = read_uint16_le(&p, end);
        read_ascii_fixed(&p, end, hue->name, 20);
        //printf("%d: %s %04x %04x\n", i, name, start_color, end_color);
    }
}
Example #9
0
static void parse_land_block(const char *p, const char *end, ml_land_block **mb)
{
    int header = read_sint32_le(&p, end);

    *mb = (ml_land_block *)malloc(sizeof(ml_land_block));

    for (int i = 0; i < 8*8; i++)
    {
        int tile_id = read_uint16_le(&p, end);
        int z = read_sint8(&p, end);
        (*mb)->tiles[i].tile_id = tile_id;
        (*mb)->tiles[i].z       = z;
    }
}
Example #10
0
static void parse_multi(const char *p, const char *end, ml_multi **m)
{
    int num_bytes = (int)(end - p);
    int item_count = num_bytes / 16;

    int multi_size = sizeof(ml_multi) + item_count * sizeof((*m)->items[0]);
    *m = (ml_multi *)malloc(multi_size);
    (*m)->item_count = item_count;

    for (int i = 0; i < item_count; i++)
    {
        (*m)->items[i].item_id = read_uint16_le(&p, end);
        (*m)->items[i].x = read_sint16_le(&p, end);
        (*m)->items[i].y = read_sint16_le(&p, end);
        (*m)->items[i].z = read_sint16_le(&p, end);
        (*m)->items[i].visible = read_uint32_le(&p, end);
        read_uint32_le(&p, end);
    }
}
Example #11
0
static void parse_statics_block(const char *p, const char *end, ml_statics_block **sb)
{
    long size = end - p;
    int statics_count = size / 7;

    int statics_block_size = sizeof(ml_statics_block) + statics_count * sizeof((*sb)->statics[0]);

    *sb = (ml_statics_block *)malloc(statics_block_size);
    (*sb)->statics_count = statics_count;

    for (int i = 0; i < 8*8; i++)
    {
        (*sb)->roof_heights[i] = -1;
    }

    //printf("statics_count. %d\n", statics_count);

    for (int i = 0; i < statics_count; i++)
    {
        int tile_id = read_sint16_le(&p, end);
        int dx = read_uint8(&p, end);
        int dy = read_uint8(&p, end);
        int z = read_sint8(&p, end);
        read_uint16_le(&p, end); // unknown
        (*sb)->statics[i].tile_id = tile_id;
        (*sb)->statics[i].dx = dx;
        (*sb)->statics[i].dy = dy;
        (*sb)->statics[i].z = z;

        ml_item_data_entry *item_data = ml_get_item_data(tile_id);
        if (item_data->flags & 0x10000000)
        {
            // is roof!
            if ((*sb)->roof_heights[dx+dy*8] == -1 || z > (*sb)->roof_heights[dx+dy*8]) // higher than existing roof?
            {
                (*sb)->roof_heights[dx+dy*8] = z;
            }
        }

        //printf("%d %d %d %d\n", tile_id, dx, dy, z);
    }
}
Example #12
0
static void parse_anim(const char *p, const char *end, ml_anim **animation)
{
    //printf("parsing... offset: %d, length: %d\n", offset, length);

    //p += offset;

    uint16_t palette[0x100];
    int frame_count;
    int frame_start_offsets[64];

    int total_frames_size;

    for (int i = 0; i < 0x100; i++)
    {
        palette[i] = read_uint16_le(&p, end);
        // set alpha
        if (palette[i]) { palette[i] |= 0x8000; }
        //printf("palette %d %d\n", i, palette[i]);
    }

    const char *payload_start = p;

    frame_count = read_sint32_le(&p, end);
    assert(frame_count <= sizeof(frame_start_offsets)/sizeof(frame_start_offsets[0]));
    for (int i = 0; i < frame_count; i++)
    {
        frame_start_offsets[i] = read_sint32_le(&p, end);
        //printf("offset %d %d\n", i, frame_start_offsets[i]);
    }

    total_frames_size = 0;
    for (int i = 0; i < frame_count; i++)
    {
        if (frame_start_offsets[i] != 0)
        {
            p = payload_start + frame_start_offsets[i] + 4;

            int width = read_sint16_le(&p, end);
            int height = read_sint16_le(&p, end);

            total_frames_size += 2 * width * height;
        }
    }

    //printf("frames size: %d\n", total_frames_size);

    int anim_meta_data_size = sizeof(ml_anim) + frame_count * sizeof((*animation)->frames[0]);
    int anim_size = anim_meta_data_size + total_frames_size;
    //printf("this animation is %d bytes\n", anim_size);
    *animation = (ml_anim *)malloc(anim_size);
    ml_anim *anim = *animation;
    anim->frame_count = frame_count;

    char *frame_data_start = ((char *)anim) + anim_meta_data_size;

    int offset_accum = 0;
    for (int i = 0; i < frame_count; i++)
    {
        //printf("frame %d of %d\n", i, frame_count);
        p = payload_start + frame_start_offsets[i];

        int center_x = 0;
        int center_y = 0;

        int width = 0;
        int height = 0;

        if (frame_start_offsets[i] != 0)
        {
            center_x = read_sint16_le(&p, end);
            center_y = read_sint16_le(&p, end);
            
            width = read_sint16_le(&p, end);
            height = read_sint16_le(&p, end);
        }

        anim->frames[i].center_x = center_x;
        anim->frames[i].center_y = center_y;
        anim->frames[i].width = width;
        anim->frames[i].height = height;
        anim->frames[i].data = (uint16_t *)(frame_data_start + offset_accum);
        offset_accum += 2 * width * height;

        uint16_t *target_data = anim->frames[i].data;
        memset(target_data, 0, 2 * width * height);

        //printf("%d %d %d %d\n", center_x, center_y, width, height);

        if (frame_start_offsets[i] != 0)
        {
            while (true)
            {
                uint32_t header = read_uint32_le(&p, end);
                //printf("header %08x\n", header);
                if (header == 0x7FFF7FFFul)
                {
                    // finished...
                    break;
                }
                int offset_x = ((header >> 22) ^ 0x200) - 0x200;
                int offset_y = (((header >> 12) & 0x3ff) ^ 0x200) - 0x200;
                int run = header & 0xfff;

                int start_x = center_x + offset_x;
                int start_y = center_y + height + offset_y;

                uint16_t *w = (uint16_t *)&target_data[start_x + start_y * width];
                uint16_t *wend = w + width * height;

                //printf("%d %d\n", width, height);
                //printf("%d %d %d\n", start_x, start_y, run);

                for (int j = 0; j < run; j++)
                {
                    assert(w < wend);
                    *w = palette[read_uint8(&p, end)];
                    w += 1;
                }

                //printf("%d %d %d\n", start_x, start_y, run);
            }
        }
    }

    // when we are done we should have written every byte we allocated
    assert(anim_meta_data_size + offset_accum == anim_size);

    //printf("read %d\n", (int)((p - payload_start) + 0x200));

}