/*-----------------------------------------------------------------------------
    Name        : rinDeviceCRC
    Description : generate a CRC of the detected devices for detection of
                  changing hardware (light assurance that previous video
                  mode will still be working correctly)
    Inputs      :
    Outputs     :
    Return      : crc32
----------------------------------------------------------------------------*/
unsigned int rinDeviceCRC(void)
{
    rdevice* cdev;
    rdevice* devlist;
    rdevice* pdevlist;
    unsigned int crc;

    if (nDevices == 0 || rDeviceList == NULL)
    {
        return 0;
    }

    devlist = (rdevice*)rinMemAlloc(nDevices * sizeof(rdevice));
    pdevlist = devlist;

    cdev = rDeviceList;
    do
    {
        memcpy(pdevlist, cdev, sizeof(rdevice));
        pdevlist->modes = NULL;
        pdevlist->next = NULL;
        pdevlist++;
        cdev = cdev->next;
    } while (cdev != NULL);

    crc = crc32Compute((void*)devlist, nDevices * sizeof(rdevice));

    rinMemFree(devlist);

    return crc;
}
static void hwdOutputDevice(LPSTR desc0, LPSTR name0, LPD3DDEVICEDESC hal)
{
    DWORD crc0, crc1, crc2;
    D3DDEVICEDESC caps;

    caps = *hal;
//    crc0 = (DWORD)crc32Compute((BYTE*)&caps, sizeof(D3DDEVICEDESC));
    crc0 = (DWORD)crc32Compute((BYTE*)&dat, sizeof(hwDat));
    caps.dwSize = 0;
    caps.dwFlags = 0;
    caps.dcmColorModel = (D3DCOLORMODEL)0;
    caps.dwDevCaps = 0;
    caps.bClipping = 0;
    crc1 = (DWORD)crc32Compute((BYTE*)&caps, sizeof(D3DDEVICEDESC));
    
    crc2  = (DWORD)crc32Compute((BYTE*)&caps.dtcTransformCaps, sizeof(D3DTRANSFORMCAPS));
    crc2 += (DWORD)crc32Compute((BYTE*)&caps.dpcLineCaps, sizeof(D3DPRIMCAPS));
    crc2 += (DWORD)crc32Compute((BYTE*)&caps.dpcTriCaps, sizeof(D3DPRIMCAPS));
    
    printf("[%08X][%08X][%08X][%s][%s]\n",
           crc1, crc0, crc2,
           desc0, name0);
}
int main(int argc, char* argv[])
{
    if (argc == 3)
    {
        DWORD vendorId, deviceId;
        sscanf(argv[1], "%u", &vendorId);
        sscanf(argv[2], "%u", &deviceId);
        memset(&dat, 0, sizeof(hwDat));
        dat.vendor  = vendorId;
        dat.product = 4;
        dat.device  = deviceId;
        DWORD crc = (DWORD)crc32Compute((BYTE*)&dat, sizeof(hwDat));
        printf("[%08X]\n", crc);
    }
    else
    {
        hwdEnumerate();
    }
    return 0;
}
void lifExportPalettedPage(lifpage* page, char* filePrefix)
{
    lifheader* newLif;
    lifheader* lif;
    color* palette;
    ubyte* teamEffect0;
    ubyte* teamEffect1;
    ubyte* data;
    sdword size;

    //
    //create a new LiF header w/ teamEffect[01] copied
    //from any LiF on the page, same w/ palette.
    //copy the palette CRC

    newLif = new lifheader;
    lif = lifFirstLIFOnPage(page);
    palette = new color[256];
    teamEffect0 = new ubyte[256];
    teamEffect1 = new ubyte[256];
    memset(palette, 0, 256 * sizeof(color));
    memset(teamEffect0, 0, 256);
    memset(teamEffect1, 0, 256);

    data = new ubyte[page->width * page->height];
    memset(data, 0, page->width * page->height);
    
    memcpy(newLif, lif, sizeof(lifheader));

    newLif->flags = TRF_Paletted;
    lifGatherFlags(page, newLif->flags);

    newLif->width = page->width;
    newLif->height = page->height;
    newLif->paletteCRC = lif->paletteCRC;

    //palettes & team effects are the same for all images on the page
    memcpy(palette, lif->palette, 256 * sizeof(color));
    if (newLif->flags & TRF_TeamColor0)
    {
        lifheader* lif0 = lifFirstTeam0OnPage(page);
        memcpy(teamEffect0, lif0->teamEffect0, 256);
    }
    if (newLif->flags & TRF_TeamColor1)
    {
        lifheader* lif1 = lifFirstTeam1OnPage(page);
        memcpy(teamEffect1, lif1->teamEffect1, 256);
    }

    newLif->palette = palette;
    newLif->data = data;

    //
    //.. copy LiF data into the larger bitmap ..
    for (list_lif::iterator i = liflist.begin(); i != liflist.end(); ++i)
    {
        if ((*i).parent != page)
        {
            //not ours
            continue;
        }

        lifBlit(newLif, (*i).header, (*i).packedX, (*i).packedY);
    }

    page->header = newLif;

    //
    //generate CRCs for the large bitmap
    newLif->imageCRC = crc32Compute(data, page->width * page->height);

    if (!exportPages)
    {
        goto DONT_EXPORT;
    }

    //
    //save the page
    FILE* out;
    char fullName[1024];
    strcpy(fullName, filePrefix);
    strcat(fullName, page->name);
    strcat(fullName, ".lif");
    out = fopen(fullName, "wb");
    if (out == NULL)
    {
        if (!quietMode)
        {
            printf("couldn't create %s.lif\n", page->name);
        }
    }
    else
    {
        size = sizeof(lifheader);

        newLif->data = (ubyte*)size;
        size += page->width * page->height;

        newLif->palette = (color*)size;
        size += 256 * sizeof(color);

        if (newLif->flags & TRF_TeamColor0)
        {
            newLif->teamEffect0 = (ubyte*)size;
            size += 256;
        }
        else
        {
            newLif->teamEffect0 = NULL;
        }

        if (newLif->flags & TRF_TeamColor1)
        {
            newLif->teamEffect1 = (ubyte*)size;
        }
        else
        {
            newLif->teamEffect1 = NULL;
        }
        
        //header
        fwrite(newLif, sizeof(lifheader), 1, out);

        //data
        fwrite(data, page->width * page->height, 1, out);

        //palette
        fwrite(palette, 256 * sizeof(color), 1, out);

        //team effect 0
        if (newLif->flags & TRF_TeamColor0)
        {
            fwrite(teamEffect0, 256, 1, out);
        }

        //team effect 1
        if (newLif->flags & TRF_TeamColor1)
        {
            fwrite(teamEffect1, 256, 1, out);
        }
        
        fclose(out);
    }

DONT_EXPORT:

    if (pacDumpTargas)
    {
        newLif->data = data;
        newLif->palette = palette;
        strcpy(fullName, filePrefix);
        strcat(fullName, page->name);
        strcat(fullName, ".tga");
        tgaExportLIF(newLif, fullName);
    }

    //
    //free memory
    delete [] palette;
    delete [] teamEffect0;
    delete [] teamEffect1;
    delete [] data;
    delete newLif;
}
void lifExportAlphaPage(lifpage* page, char* filePrefix)
{
    lifheader* newLif;
    lifheader* lif;
    ubyte* teamEffect0;
    ubyte* teamEffect1;
    ubyte* data;
    sdword size;

    newLif = new lifheader;
    lif = lifFirstLIFOnPage(page);
    memcpy(newLif, lif, sizeof(lifheader));

    teamEffect0 = new ubyte[page->width * page->height];
    teamEffect1 = new ubyte[page->width * page->height];
    memset(teamEffect0, 0, page->width * page->height);
    memset(teamEffect1, 0, page->width * page->height);

    data = new ubyte[sizeof(color) * page->width * page->height];
    memset(data, 0, sizeof(color) * page->width * page->height);

    newLif->flags = TRF_Alpha;
    lifGatherFlags(page, newLif->flags);

    newLif->width = page->width;
    newLif->height = page->height;

    newLif->data = data;
    newLif->palette = NULL;
    newLif->teamEffect0 = teamEffect0;
    newLif->teamEffect1 = teamEffect1;

    //
    //.. copy LiF data into the larger bitmap ..
    for (list_lif::iterator i = liflist.begin(); i != liflist.end(); ++i)
    {
        if ((*i).parent != page)
        {
            continue;
        }

        //blit data
        lifLongBlit(newLif, (*i).header, (*i).packedX, (*i).packedY);
        //blit team effect 0
        if (HAS_TEAM_EFFECT0((*i).header))
        {
            lifBlit0(newLif, (*i).header, (*i).packedX, (*i).packedY);
        }
        //blit team effect 1
        if (HAS_TEAM_EFFECT1((*i).header))
        {
            lifBlit1(newLif, (*i).header, (*i).packedX, (*i).packedY);
        }
    }

    page->header = newLif;

    //
    //generate CRCs for the large bitmap
    newLif->imageCRC = crc32Compute(data, sizeof(color) * page->width * page->height);

    if (!exportPages)
    {
        goto DONT_EXPORT;
    }

    //
    //save the page
    FILE* out;
    char fullName[1024];
    strcpy(fullName, filePrefix);
    strcat(fullName, page->name);
    strcat(fullName, ".lif");
    out = fopen(fullName, "wb");
    if (out == NULL)
    {
        if (!quietMode)
        {
            printf("couldn't create %s.lif\n", page->name);
        }
    }
    else
    {
        size = sizeof(lifheader);
        newLif->data = (ubyte*)size;
        size += sizeof(color) * page->width * page->height;

        newLif->palette = NULL;

        if (newLif->flags & TRF_TeamColor0)
        {
            newLif->teamEffect0 = (ubyte*)size;
            size += page->width * page->height;
        }
        else
        {
            newLif->teamEffect0 = NULL;
        }
        
        if (newLif->flags & TRF_TeamColor1)
        {
            newLif->teamEffect1 = (ubyte*)size;
        }
        else
        {
            newLif->teamEffect1 = NULL;
        }
        
        //header
        fwrite(newLif, sizeof(lifheader), 1, out);

        //data
        fwrite(data, sizeof(color) * page->width * page->height, 1, out);

        //team effect 0
        if (newLif->flags & TRF_TeamColor0)
        {
            fwrite(teamEffect0, page->width * page->height, 1, out);
        }

        //team effect 1
        if (newLif->flags & TRF_TeamColor1)
        {
            fwrite(teamEffect1, page->width * page->height, 1, out);
        }

        fclose(out);
    }

DONT_EXPORT:
    
    if (pacDumpTargas)
    {
        newLif->data = data;
        strcpy(fullName, filePrefix);
        strcat(fullName, page->name);
        strcat(fullName, ".tga");
        tgaExportLIF(newLif, fullName);
    }

    //
    //free memory
    delete [] teamEffect0;
    delete [] teamEffect1;
    delete [] data;
    delete newLif;
}