/*-*-C-*-
 * Relocation etc
 */

#include "resed.h"
#include "main.h"

#include "resformat.h"

#include "relocate.h"


/*
 * Relocate a block received from the shell.  After calling this
 * all the pointers will be to the real strings and messages.
 * Sprite relocations are not done because we use the Wimp sprite
 * pool.
 *
 * If all is well, returns the address of the start of the object body.
 *
 * If the structure is found to be corrupt in some way, a NULL pointer
 * is returned.
 */

char * relocate_object (ResourceFileObjectTemplateHeaderPtr object)
{
    unsigned int strings = (unsigned int) object + object->stringtableoffset;
    unsigned int messages = (unsigned int) object + object->messagetableoffset;
    RelocationTablePtr relocs = (RelocationTablePtr) ((unsigned int) object + object->relocationtableoffset);
    char * body = ((char *) &object->hdr) + object->hdr.bodyoffset;

/*    dprintf ("MENU: relocate_object() messages are at offset %d\n", messages); */

    if (object->relocationtableoffset > 0)
    {
        int i;
/*        dprintf ("%d relocations\n", relocs->numrelocations); */
        for (i = 0; i < relocs->numrelocations; i++)
        {
            unsigned int *word;
/*            dprintf ("Reloc number %d\n", i); */
            word = (unsigned int *) (body + relocs->relocations[i].wordtorelocate);
/*            dprintf ("wordtorelocate is %d and word is %d\n", relocs->relocations[i].wordtorelocate, word); */
/*            dprintf ("Reloc word at offset %d value %d\n", relocs->relocations[i].wordtorelocate, *word); */
            if (*word == 0xffffffff)
                *word = 0;
            else
            {
                switch (relocs->relocations[i].directive)
                {
                case RELOCATE_STRINGREFERENCE:
                    *word += strings;
/*                    dprintf (" string, new value is %d *%s*\n", *word, *word); */
                    break;
                case RELOCATE_MSGREFERENCE:
                    *word += messages;
/*                    dprintf (" msg, new value is %d *%s*\n", *word, *word); */
                    break;

                /* only the two relocations above can arise in menus */
                default:
                    return NULL;
                }
            }
        }
    }
/*    dprintf ("Leaving relocate\n"); */
    return body;
}
