Exemple #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;
}
Exemple #2
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;
}
Exemple #3
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;
}
Exemple #4
0
static
int load_module_import (struct prx *p, struct prx_import *imp)
{
  uint32 i, offset;
  if (imp->nfuncs) {
    imp->funcs = (struct prx_function *) xmalloc (imp->nfuncs * sizeof (struct prx_function));
    offset = prx_translate (p, imp->nidsvaddr);
    for (i = 0; i < imp->nfuncs; i++) {
      struct prx_function *f = &imp->funcs[i];
      f->nid = read_uint32_le (&p->data[offset + 4 * i]);
      f->vaddr = imp->funcsvaddr + 8 * i;
      f->libname = imp->name;
      f->name = NULL;
      f->numargs = -1;
      f->pfunc = NULL;
    }
  }

  if (imp->nvars) {
    imp->vars = (struct prx_variable *) xmalloc (imp->nvars * sizeof (struct prx_variable));
    offset = prx_translate (p, imp->varsvaddr);
    for (i = 0; i < imp->nvars; i++) {
      struct prx_variable *v = &imp->vars[i];
      v->nid = read_uint32_le (&p->data[offset + 8 * i + 4]);
      v->vaddr = read_uint32_le (&p->data[offset +  8 * i]);
      v->libname = imp->name;
      v->name = NULL;
    }
 }
  return 1;
}
Exemple #5
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);
    }
}
Exemple #6
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;
    }
}
Exemple #7
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);
    }
}
Exemple #8
0
static
int load_module_export (struct prx *p, struct prx_export *exp)
{
  uint32 i, offset, disp;
  offset = prx_translate (p, exp->expvaddr);
  disp = 4 * (exp->nfuncs + exp->nvars);
  if (exp->nfuncs) {
    exp->funcs = (struct prx_function *) xmalloc (exp->nfuncs * sizeof (struct prx_function));
    for (i = 0; i < exp->nfuncs; i++) {
      struct prx_function *f = &exp->funcs[i];
      f->vaddr = read_uint32_le (&p->data[offset + disp]);
      f->nid = read_uint32_le (&p->data[offset]);
      f->name = NULL;
      f->libname = exp->name;
      f->numargs = -1;
      f->pfunc = NULL;
      offset += 4;
      if (exp->namevaddr == 0) {
        f->name = resolve_syslib_nid (f->nid);
      }
    }
  }

  if (exp->nvars) {
    exp->vars = (struct prx_variable *) xmalloc (exp->nvars * sizeof (struct prx_variable));
    for (i = 0; i < exp->nvars; i++) {
      struct prx_variable *v = &exp->vars[i];
      v->vaddr = read_uint32_le (&p->data[offset + disp]);
      v->nid = read_uint32_le (&p->data[offset]);
      v->name = NULL;
      v->libname = exp->name;
      offset += 4;
      if (exp->namevaddr == 0) {
        v->name = resolve_syslib_nid (v->nid);
      }
    }
  }
  return 1;
}
Exemple #9
0
static void parse_unicode_font_metadata(const char *p, const char *end, ml_font_metadata *font_metadata)
{
    const char *start = p;

    uint32_t char_data_start[0x10000];

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

    int max_width  = 0;
    int max_height = 0;

    int non_nulls = 0;

    int total_pixels = 0;

    for (int i = 0; i < 0x10000; i++)
    {
        p = start + char_data_start[i];
        if (p == end) // special case for broken unifont3.mul...
        {
            p -= 4;
        }

        int kerning  = read_sint8(&p, end);
        int baseline = read_sint8(&p, end);
        int width    = read_sint8(&p, end);
        int height   = read_sint8(&p, end);

        if (width  > max_width ) max_width  = width ;
        if (height > max_height) max_height = height;

        font_metadata->chars[i].kerning  = kerning;
        font_metadata->chars[i].baseline = baseline;
        font_metadata->chars[i].width    = width;
        font_metadata->chars[i].height   = height;

        total_pixels += width * height;

        if (char_data_start[i] != 0)
        {
            non_nulls += 1;
        }
    }

    //printf("%d %d %d %d\n", non_nulls, total_pixels, max_width, max_height);

}
Exemple #10
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;
        }
    }
}
Exemple #11
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);
    }
}
Exemple #12
0
static void parse_render_unicode_font_string(const char *p, const char *end, int font_id, std::wstring s, ml_art **res)
{
    const char *start = p;

    uint32_t char_data_start[0x10000];

    for (int i = 0; i < 0x10000; i++)
    {
        char_data_start[i] = read_uint32_le(&p, end);
    }

    int str_len = s.length();

    const int space_width = 3;

    int art_width;
    int art_height;

    ml_get_font_string_dimensions(font_id, s, &art_width, &art_height);

    int art_size = sizeof(ml_art) + 2 * art_width * art_height;

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

    (*res)->width = art_width;
    (*res)->height = art_height;

    uint16_t *target_data = (*res)->data;
    memset(target_data, 0, 2 * art_width * art_height);

    int offset_x = 0;
    for (int i = 0; i < str_len; i++)
    {
        wchar_t c = s[i];
        assert(c >= 0 && c < 0x10000);
        p = start + char_data_start[c];
        if (p == end) // special case for broken unifont3.mul...
        {
            p -= 4;
        }

        int kerning  = read_uint8(&p, end);
        int baseline = read_uint8(&p, end);
        int width    = read_uint8(&p, end);
        int height   = read_uint8(&p, end);

        // special handle space
        if (c == ' ')
        {
            width = space_width;
        }
        else
        {
            for (int j = 0; j < art_height; j++)
            {
                uint16_t *w = target_data + offset_x + j * art_width;

                if (j >= baseline && j < baseline + height)
                {
                    uint8_t raw_data;
                    for (int x = 0; x < width; x++)
                    {
                        if ((x % 8) == 0)
                        {
                            raw_data = read_uint8(&p, end);
                        }

                        if (raw_data & 0x80)
                        {
                            *w++ = 0xffff;
                        }
                        else
                        {
                            *w++ = 0x0000;
                        }


                        raw_data <<= 1;
                    }
                }
            }
        }

        //printf("'%c' width: %d\n", c, width);

        offset_x += width+1;
    }

    //printf("total width, height: %d, %d\n", art_width, art_height);
}
Exemple #13
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));

}