/*--------------------------------------------------------------------------
  Project:  Manual 2D Library - m2d
  File:     m2d_directTexture.cpp

  Copyright (C)2007-2009 Nintendo  All Rights Reserved.

  These coded instructions, statements, and computer programs contain
  proprietary information of Nintendo of America Inc. and/or Nintendo
  Company Ltd., and are protected by Federal copyright law. They may
  not be disclosed to third parties or copied or duplicated in any form,
  in whole or in part, without the prior written consent of Nintendo.

  $Revision: 1.9 $
 *-------------------------------------------------------------------------*/

#include <nitro.h>
#include <nitro/gx/g3.h>
#include <nnsys/misc.h>
#include <ntmv/m2d/debug.h>
#include <ntmv/m2d/objectConstructor.h>
#include <ntmv/m2d/directTexture.h>
#include <ntmv/m2d/common.h>
#include <ntmv/m2d/page.h>
#include <cstring>

namespace ntmv
{
namespace m2d
{

/*---------------------------------------------------------------------------*
  Name:         DirectTexture::DirectTexture

  Description:  Constructor

  Arguments:    None.

  Returns:      None.
 *---------------------------------------------------------------------------*/
DirectTexture::DirectTexture()
:   mpImage(0)
{
    std::memset(&mFlags, 0, sizeof(mFlags));
}

/*---------------------------------------------------------------------------*
  Name:         DirectTexture::Set

  Description:  Sets the image resource.

  Arguments:    objectConstructor:  A reference to an ObjectConstructor object.
                pImageHd:           A pointer to the image resource header.

  Returns:      None.
 *---------------------------------------------------------------------------*/
void
DirectTexture::Set(
    const ObjectConstructor&    objectConstructor,
    const ImageHeader*          pImageHd
)
{
    mSize.Set(static_cast<s16>(pImageHd->width), static_cast<s16>(pImageHd->height));

    switch (pImageHd->texelFormat)
    {
    case GX_TEXFMT_DIRECT:
        mpImage = reinterpret_cast<const u16*>(pImageHd + 1);
        break;

    case GX_TEXFMT_PLTT256:     // 256 colors
        // Convert into the Direct format and save
        {
            u16* pDst = objectConstructor.NewArray<u16>(static_cast<u32>(pImageHd->width * pImageHd->height));
            NNS_NULL_ASSERT(pDst);
            mFlags.bAllocImage = true;
            mpImage = pDst;
            const u16 *const palette = reinterpret_cast<const u16*>(pImageHd + 1);
            const u8* pSrc = reinterpret_cast<const u8*>(palette + pImageHd->paletteEntryNum);
            const u8 *const pSrcEnd = pSrc + pImageHd->width * pImageHd->height;
                
            while (pSrc < pSrcEnd)
            {
                const u8 idx = *pSrc++;
                u16 alpha = 0x8000;
                if (idx == 0 && pImageHd->bHasAlphaPal) // When referencing palette 0, and there's a transparent color.
                {
                    alpha = 0;
                }

                *pDst++ = static_cast<u16>(palette[idx] | alpha);
            }
        }
        break;

    default:    // Unsupported format
        NNS_ASSERT(false);
    }
}

/*---------------------------------------------------------------------------*
  Name:         DirectTexture::Finalize

  Description:  Performs shutdown.

  Arguments:    objectConstructor:  A reference to an ObjectConstructor object.

  Returns:      None.
 *---------------------------------------------------------------------------*/
void
DirectTexture::Finalize(const ObjectConstructor& objectConstructor)
{
    NTMV_LOG("DirectTexture::Finalize()\n");

    if (mFlags.bAllocImage)
    {
        objectConstructor.DeletePrimArray(const_cast<u16*>(mpImage));
        mFlags.bAllocImage = false;
    }
}

}   // namespace m2d
}   // namespace ntmv
