Exemple #1
0
/*! \note	Still very unsafe, but I need to redo everything later anyway.
*/
void grs_run(GritShared *grs, GritRec *gr_base)
{
	// Make sure we have shared data.
	if( grs->dib==NULL && grs->palRec.data==NULL)
	{
		lprintf(LOG_WARNING, "No shared data to run with!\n");
		return;
	}

	// Make copy of gr_base for flags, etc
	GritRec *gr= grit_alloc();
	grs_free(gr->shared);

	grit_copy_options(gr, gr_base);
	grit_copy_strings(gr, gr_base);

	// Attach shared data
	gr->shared= grs;
	strrepl(&gr->symName, grs->symName);
	strrepl(&gr->dstPath, grs->dstPath);

	if(grs->dib == NULL)
	{
		// Palette only. Create new dib.
		gr->srcDib= dib_alloc(16, 16, 8, NULL);
		memset(dib_get_pal(gr->srcDib), 0, PAL_MAX*RGB_SIZE);
		memcpy(dib_get_pal(gr->srcDib), grs->palRec.data, rec_size(&grs->palRec));
	}
	else
		gr->srcDib= dib_clone(grs->dib);

	// NOTE: aliasing screws up deletion later; detach manually.
	gr->_dib= gr->srcDib;	

	// Run for shared gr
	do 
	{
		if(!grit_validate(gr))
			break;

		bool grit_prep_gfx(GritRec *gr);
		bool grit_prep_shared_pal(GritRec *gr);

		if(gr->gfxProcMode != GRIT_EXCLUDE)
			grit_prep_gfx(gr);
		
		if(gr->palProcMode != GRIT_EXCLUDE)
			grit_prep_shared_pal(gr);

		if(gr->bExport)
			grit_export(gr);

	} while(0);

	gr->_dib= NULL;

	// Detach shared data and delete gr
	gr->shared= NULL;
	grit_free(gr);
}
Exemple #2
0
BOOL CxpGbaDlg::UpdateGritRec(BOOL b2gr)
{
	DWORD dw;
	char str[MAXPATHLEN];

	// TODO: al/gfx trans ; img modes ; tileset

	if(b2gr)	// data -> gr
	{
		UpdateData(TRUE);

		SetDstPath(mDstPath);

		// clear previous gr data
		grit_clear(mgr);
		grs_clear(mgr->shared);

		mgr->bExport= true;

		// Yes, yes, very wasteful
		mgr->srcDib= dib_clone(mpDib);

		mgr->bHeader= mbHeader==TRUE;
		mgr->bAppend= mbAppend==TRUE;
		mgr->fileType= mFileType;

		// TODO check whether this is all OK!!
		if(mbSymChk)
			mgr->symName= strdup(mSymName);
		else
			mgr->symName= strdup(mDstTitle);

		// make sure it's a valid C varname
		str_fix_ident(mgr->symName, mgr->symName, 
			strlen(mgr->symName));

		sprintf(str, "%s/%s.%s", mDstDir, mDstTitle, c_fileTypes[mFileType]);
		mgr->dstPath= strdup(str);

		// --- palette ---
		if(mbPal)
		{
			mgr->palProcMode= GRIT_EXPORT;

			mgr->palStart= mPalStart;
			mgr->palEnd= mPalStart+mPalCount;
			if(mgr->palEnd > 256)
				mgr->palEnd= 256;

			if(mPalTrans != 0)
			{
				mgr->palHasAlpha= true;
				mgr->palAlphaId= mPalTrans;
			}
		}

		// --- image ---
		// NOTE: we should probably always process the image, 
		//   just not necessarily export
		if(1)
		{
			if(mbGfx)
				mgr->gfxProcMode= GRIT_EXPORT;

			switch(mGfxMode)
			{
			case GFX_MODE_TILE:
				mgr->gfxMode= GRIT_GFX_TILE;
				break;
			case GFX_MODE_BMP:
				mgr->gfxMode= GRIT_GFX_BMP;
				break;
			case GFX_MODE_BMP_A:
				mgr->gfxMode= GRIT_GFX_BMP_A;
				break;
			case GFX_MODE_BMP_T:
				mgr->gfxMode= GRIT_GFX_BMP;

				// Empty color && non-zero pal-trans -> use pal-trans
				// Empty color otherwise: use FF00FF
				// non-empty: use non-empty
				dw= strlen(mGfxTransStr);

				if( dw != 0 || !mgr->palHasAlpha )
				{
					if(dw==0)
						mGfxTransStr= "FF00FF";
					mgr->gfxAlphaColor= str2rgb(mGfxTransStr);
					mgr->gfxHasAlpha= true;
				}
				break;				
			}

			mgr->gfxOffset= 0;
			mgr->gfxBpp= 1<<mGfxBpp;
			mgr->gfxCompression= mGfxCprs;

		}
		// --- map ---
		if(mbMap)
		{
			mgr->mapProcMode= GRIT_EXPORT;	
			mgr->mapCompression= mMapCprs;

			if(mbMapRdx)
			{
				mgr->mapRedux |= GRIT_RDX_TILE;
				if(mbMapRdxFlip)
					mgr->mapRedux |= GRIT_RDX_FLIP;
				if(mbMapRdxPal)
					mgr->mapRedux |= GRIT_RDX_PBANK;
			}

			if(mbMetaPal)
				mgr->mapRedux |= GRIT_META_PAL;

			mgr->mapLayout= moMapFormat;
			if(mgr->mapLayout == GRIT_MAP_AFFINE)
				mgr->msFormat= c_mapselGbaAffine;
			else
				mgr->msFormat= c_mapselGbaText;

			mgr->msFormat.base= mMapOffset;

			// Add external tileset stuff
			if(mbTileset)
			{
				if(mTilesetPath.IsEmpty())
					mTilesetPath= mDstDir + mDstTitle + "tiles.bmp";
				mgr->shared->tilePath= strdup(mTilesetPath);
				mgr->gfxIsShared= true;
			}
		}

		if(mbObjCustom)
		{
			mgr->metaWidth= mObjHorz;
			mgr->metaHeight= mObjVert;
		}
		else
		{
			dw= moObjShape*4 + moObjSize;
			mgr->metaWidth= cObjSizes[dw][0];
			mgr->metaHeight= cObjSizes[dw][1];
		}
		// area
		dw= moAreaSize+IDC_AREA_CSM;
		if(dw == IDC_AREA_CSM)
		{
			mgr->areaLeft  = mAreaLeft;
			mgr->areaTop   = mAreaTop;
			mgr->areaRight = mAreaLeft+mAreaWidth;
			mgr->areaBottom= mAreaTop+mAreaHeight;
		}
		else
		{
			mgr->areaLeft  = 0;
			mgr->areaTop   = 0;
			mgr->areaRight = dib_get_width(mpDib);
			mgr->areaBottom= dib_get_height(mpDib);
		}

		mgr->gfxDataType= moVarChunk;
		mgr->mapDataType= moVarChunk;
		mgr->palDataType= moVarChunk;

		// RIFF overrides
		if(IsRiffed())
		{
			mgr->bRiff= true;
			if(mgr->gfxCompression==GRIT_CPRS_OFF)
				mgr->gfxCompression= GRIT_CPRS_HEADER;

			if(mgr->mapCompression==GRIT_CPRS_OFF)
				mgr->mapCompression= GRIT_CPRS_HEADER;

			if(mgr->palCompression==GRIT_CPRS_OFF)
				mgr->palCompression= GRIT_CPRS_HEADER;
		}
	}
	else		// gr -> data
	{
		// --- file ---
		mbHeader = mgr->bHeader;
		mbAppend = mgr->bAppend;
		
		// --- palette ---
		mPalStart= mgr->palStart;
		mPalCount= mgr->palEnd-mgr->palStart;
		mPalTrans= mgr->palAlphaId;

		// --- image ---
		if(mgr->gfxHasAlpha)
		{
			RGBQUAD *rgb= &mgr->gfxAlphaColor;
			mGfxMode= GFX_MODE_BMP_T;
			mGfxTransStr.Format("%02X%02X%02X", rgb->rgbRed, 
				rgb->rgbGreen, rgb->rgbBlue);
		}
		else if(mgr->gfxMode == GRIT_GFX_BMP_A)
			mGfxMode= GFX_MODE_BMP_T;			
		else if(mgr->gfxMode == GRIT_GFX_BMP)
			mGfxMode= GFX_MODE_BMP;			
		else
			mGfxMode= GFX_MODE_TILE;			

		//mgr->gfx_ofs;
		//mgr->gfxBpp;

		// map
		if(mbMap)
		{
			moMapFormat= mgr->mapLayout;

			if(mgr->mapRedux & GRIT_RDX_TILE)
			{	
				mbMapRdx= TRUE;
				mbMapRdxFlip= mbMapRdxPal= FALSE;
				if(mgr->mapRedux & GRIT_RDX_FLIP)
					mbMapRdxFlip= TRUE;
				if(mgr->mapRedux & GRIT_RDX_PBANK)
					mbMapRdxPal= TRUE;
			}
			mMapOffset= mgr->msFormat.base;
		}
		// meta
		if(mbObjCustom)
		{
			mObjHorz= mgr->metaWidth;
			mObjVert= mgr->metaHeight;
		}
		// area
		mAreaLeft= mgr->areaLeft;
		mAreaTop= mgr->areaTop;
		mAreaWidth= mgr->areaRight-mgr->areaLeft;
		mAreaHeight= mgr->areaBottom-mgr->areaTop;

		UpdateData(FALSE);
	}

	return TRUE;
}
Exemple #3
0
/*!	Does map creation and layout, tileset reduction and map
	compression. Updates \a gr._dib with the new tileset, and fills
	in \a gr._mapRec and \a gr._metaRec.
	\note The work bitmap must be 8 bpp here, and already rearranged
	to a tile strip, which are the results of \c grit_prep_work_dib()
	and \c grit_prep_tiles(), respectively.
*/
bool grit_prep_map(GritRec *gr)
{
    if(dib_get_bpp(gr->_dib) < 8)
    {
        lprintf(LOG_ERROR, "  Can't map for bpp<8.\n");
        return false;
    }

    CLDIB *workDib= gr->_dib;

    // --- if SBB-mode, tile to 256x256. ---
    if(gr->mapLayout == GRIT_MAP_REG)
    {
        lprintf(LOG_STATUS, "  tiling to Screenblock size (256x256p).\n");

        int blockW= 256, blockH= 256;
        if(gr->bColMajor)
        {
            blockW= dib_get_width(workDib);
            blockH= dib_get_height(workDib);
            dib_redim(workDib, 256, blockH, 0);
        }

        if(!dib_redim(workDib, blockW, blockH, 0))
        {
            lprintf(LOG_ERROR, "  SBB tiling failed.\n");
            return false;
        }
    }

    ETmapFlags flags;
    Tilemap *metaMap= NULL, *map= NULL;
    RECORD metaRec= { 0, 0, NULL }, mapRec= { 0, 0, NULL };
    MapselFormat mf;

    CLDIB *extDib= NULL;
    int tileN= 0;
    uint extW= 0, extH= 0, tileW= gr->tileWidth, tileH= gr->tileHeight;
    uint mtileW= gr->mtileWidth(), mtileH= gr->mtileHeight();

    if(gr->gfxIsShared)
    {
        extDib= gr->shared->dib;
        extW= extDib ? dib_get_width(extDib) : 0;
        extH= extDib ? dib_get_height(extDib) : 0;
    }

    // --- If metatiled, convert to metatiles. ---
    if(gr->isMetaTiled())
    {
        lprintf(LOG_STATUS, "  Performing metatile reduction: tiles%s%s\n",
                (gr->mapRedux & GRIT_META_PAL ? ", palette" : "") );

        flags  = TMAP_DEFAULT;
        if(gr->mapRedux & GRIT_META_PAL)
            flags |= TMAP_PBANK;
        if(gr->bColMajor)
            flags |= TMAP_COLMAJOR;

        metaMap= tmap_alloc();
        if(extW == mtileW)
        {
            lprintf(LOG_STATUS, "  Using external metatileset.\n");
            tmap_init_from_dib(metaMap, workDib, mtileW, mtileH, flags, extDib);
        }
        else
            tmap_init_from_dib(metaMap, workDib, mtileW, mtileH, flags, NULL);

        mf= c_mapselGbaText;
        tileN= tmap_get_tilecount(metaMap);
        if(tileN >= (1<<mf.idLen))
            lprintf(LOG_WARNING, "  Number of metatiles (%d) exceeds field limit (%d).\n",
                    tileN, 1<<mf.idLen);

        tmap_pack(metaMap, &metaRec, &mf);
        if( BYTE_ORDER == BIG_ENDIAN && mf.bitDepth > 8 )
            data_byte_rev(metaRec.data, metaRec.data, rec_size(&metaRec), mf.bitDepth/8);

        // Make temp copy for base-tiling and try to avoid aliasing pointers.
        // Gawd, I hate manual mem-mgt >_<.
        dib_free(workDib);
        if(gr->bColMajor)
            workDib= dib_redim_copy(metaMap->tiles, tileN*mtileW, mtileH, 0);
        else
            workDib= dib_clone(metaMap->tiles);
    }

    // ---Convert to base tiles. ---
    flags = 0;
    if(gr->mapRedux & GRIT_RDX_TILE)
        flags |= TMAP_TILE;
    if(gr->mapRedux & GRIT_RDX_FLIP)
        flags |= TMAP_FLIP;
    if(gr->mapRedux & GRIT_RDX_PBANK)
        flags |= TMAP_PBANK;
    if(gr->bColMajor)
        flags |= TMAP_COLMAJOR;

    lprintf(LOG_STATUS, "  Performing tile reduction: %s%s%s\n",
            (flags & TMAP_TILE  ? "unique tiles; " : ""),
            (flags & TMAP_FLIP  ? "flip; " : ""),
            (flags & TMAP_PBANK ? "palswap; " : ""));

    map= tmap_alloc();
    if(extW == tileW)
    {
        lprintf(LOG_STATUS, "  Using external tileset.\n");
        tmap_init_from_dib(map, workDib, tileW, tileH, flags, extDib);
    }
    else
        tmap_init_from_dib(map, workDib, tileW, tileH, flags, NULL);

    // --- Pack/Reformat and compress ---
    //# TODO: allow custom mapsel format.
    mf= gr->msFormat;

    tileN= tmap_get_tilecount(metaMap);
    if(tileN >= (1<<mf.idLen))
        lprintf(LOG_WARNING, "  Number of tiles (%d) exceeds field limit (%d).\n",
                tileN, 1<<mf.idLen);

    tmap_pack(map, &mapRec, &mf);

    if( BYTE_ORDER == BIG_ENDIAN && mf.bitDepth > 8 )
        data_byte_rev(mapRec.data, mapRec.data, rec_size(&mapRec), mf.bitDepth/8);

    grit_compress(&mapRec, &mapRec, gr->mapCompression);

    // --- Cleanup ---

    // Make extra copy for external tile dib.
    if(gr->gfxIsShared)
    {
        dib_free(gr->shared->dib);

        // Use metatileset for external, unless the old external was a
        // base tileset.
        if(gr->isMetaTiled() && extW != tileW)
            gr->shared->dib= dib_clone(metaMap->tiles);
        else
            gr->shared->dib= dib_clone(map->tiles);
    }

    // Attach tileset for later processing.
    gr->_dib= tmap_detach_tiles(map);

    rec_alias(&gr->_mapRec, &mapRec);
    rec_alias(&gr->_metaRec, &metaRec);

    tmap_free(map);
    tmap_free(metaMap);

    lprintf(LOG_STATUS, "Map preparation complete.\n");
    return true;
}