Exemple #1
0
/* Default implementation of tile_rectangle */
int
gx_default_tile_rectangle(gx_device *dev, register gx_bitmap *tile,
  int x, int y, int w, int h, gx_color_index color0, gx_color_index color1)
{	/* Fill the rectangle in chunks */
	int width = tile->width;
	int height = tile->height;
	int raster = tile->raster;
	int ex = x + w, ey = y + h;
	int fex = ex - width, fey = ey - height;
	int irx = ((width & (width - 1)) == 0 ?	/* power of 2 */
		x & (width - 1) :
		x % width);
	int ry = y % height;
	int icw = width - irx;
	int ch = height - ry;
	byte *row = tile->data + ry * raster;
	int (*proc_mono)(P10(gx_device *, byte *, int, int,
		int, int, int, int, gx_color_index, gx_color_index));
	int (*proc_color)(P8(gx_device *, byte *, int, int,
		int, int, int, int));
	int color_halftone =
		(color0 == gx_no_color_index && color1 == gx_no_color_index);
	int cx, cy;
	if ( color_halftone )
		proc_color = dev->procs->copy_color;
	else
		proc_mono = dev->procs->copy_mono;
#ifdef DEBUG
if ( gs_debug['t'] )
   {	int ptx, pty;
	byte *ptp = tile->data;
	printf("[t]tile w=%d h=%d raster=%d; x=%d y=%d w=%d h=%d\n",
		tile->width, tile->height, tile->raster, x, y, w, h);
	for ( pty = 0; pty < tile->height; pty++ )
	   {	printf("   ");
		for ( ptx = 0; ptx < tile->raster; ptx++ )
			printf("%3x", *ptp++);
	   }
	printf("\n");
   }
#endif
	if ( icw > w ) icw = w;
	if ( ch > h ) ch = h;
#define real_copy_tile(sourcex, tx, tw)\
  (color_halftone ?\
    (*proc_color)(dev, row, sourcex, raster, tx, cy, tw, ch) :\
    (*proc_mono)(dev, row, sourcex, raster, tx, cy, tw, ch, color0, color1))
#ifdef DEBUG
#define copy_tile(sx, tx, tw)\
  if ( gs_debug['t'] )\
	printf("   copy sx=%d x=%d y=%d w=%d h=%d\n",\
		sx, tx, cy, tw, ch);\
  real_copy_tile(sx, tx, tw)
#else
#define copy_tile(sx, tx, tw)\
  real_copy_tile(sx, tx, tw)
#endif
	for ( cy = y; cy < ey; )
	   {	copy_tile(irx, x, icw);
		cx = x + icw;
		while ( cx <= fex )
		   {	copy_tile(0, cx, width);
			cx += width;
		   }
		if ( cx < ex )
		   {	copy_tile(0, cx, ex - cx);
		   }
		cy += ch;
		ch = (cy > fey ? ey - cy : height);
		row = tile->data;
	   }
#undef copy_tile
#undef real_copy_tile
	return 0;
}
// Find the block boundary for each discard level in the input image.
// We parse the input blocks and copy them in a temporary output stream.
// For the moment, we do nothing more that parsing the raw list of blocks and outputing result.
void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base)
{
	// We need the number of levels in that image before starting.
	getMetadata(base);
	
	for (int discard_level = 0; discard_level < mLevels; discard_level++)
	{
		//std::cout << "Parsing discard level = " << discard_level << std::endl;
		// Create the input codestream object.
		setupCodeStream(base, TRUE, MODE_FAST);
		mCodeStreamp->apply_input_restrictions(0, 4, discard_level, 0, NULL);
		mCodeStreamp->set_max_bytes(KDU_LONG_MAX,true);
		siz_params *siz_in = mCodeStreamp->access_siz();
	
		// Create the output codestream object.
		siz_params siz;
		siz.copy_from(siz_in,-1,-1,-1,0,discard_level,false,false,false);
		siz.set(Scomponents,0,0,mCodeStreamp->get_num_components());
	
		U32 max_output_size = base.getWidth()*base.getHeight()*base.getComponents();
		max_output_size = (max_output_size < 1000 ? 1000 : max_output_size);
		U8 *output_buffer = new U8[max_output_size];
		U32 output_size = 0; // Address updated by LLKDUMemTarget to give the final compressed buffer size
		LLKDUMemTarget output(output_buffer, output_size, max_output_size);
		kdu_codestream codestream_out; 
		codestream_out.create(&siz,&output);
		//codestream_out.share_buffering(*mCodeStreamp);
		siz_params *siz_out = codestream_out.access_siz();
		siz_out->copy_from(siz_in,-1,-1,-1,0,discard_level,false,false,false);
		codestream_out.access_siz()->finalize_all(-1);
	
		// Set up rate control variables
		kdu_long max_bytes = KDU_LONG_MAX;
		kdu_params *cod = siz_out->access_cluster(COD_params);
		int total_layers;  cod->get(Clayers,0,0,total_layers);
		kdu_long *layer_bytes = new kdu_long[total_layers];
		int nel, non_empty_layers = 0;
	
		// Now ready to perform the transfer of compressed data between streams
		int flush_counter = INT_MAX;
		kdu_dims tile_indices_in;  
		mCodeStreamp->get_valid_tiles(tile_indices_in);
		kdu_dims tile_indices_out; 
		codestream_out.get_valid_tiles(tile_indices_out);
		assert((tile_indices_in.size.x == tile_indices_out.size.x) &&
			   (tile_indices_in.size.y == tile_indices_out.size.y));
		int num_blocks=0;
	
		kdu_coords idx;
		//std::cout << "Parsing tiles : x = " << tile_indices_out.size.x << " to y = " << tile_indices_out.size.y << std::endl;
		for (idx.y=0; idx.y < tile_indices_out.size.y; idx.y++)
		{
			for (idx.x=0; idx.x < tile_indices_out.size.x; idx.x++)
			{
				kdu_tile tile_in = mCodeStreamp->open_tile(idx+tile_indices_in.pos);
				int tnum_in = tile_in.get_tnum();
				int tnum_out = idx.x + idx.y*tile_indices_out.size.x;
				siz_out->copy_from(siz_in,tnum_in,tnum_out,0,0,discard_level,false,false,false);
				siz_out->finalize_all(tnum_out);
				// Note: do not open the output tile without first copying any tile-specific code-stream parameters
				kdu_tile tile_out = codestream_out.open_tile(idx+tile_indices_out.pos);
				assert(tnum_out == tile_out.get_tnum());
				copy_tile(tile_in,tile_out,tnum_in,tnum_out,siz_in,siz_out,0,num_blocks);
				tile_in.close();
				tile_out.close();
				flush_counter--;
				if ((flush_counter <= 0) && codestream_out.ready_for_flush())
				{
					flush_counter = INT_MAX;
					nel = codestream_out.trans_out(max_bytes,layer_bytes,total_layers);
					non_empty_layers = (nel > non_empty_layers)?nel:non_empty_layers;
				}
			}
		}
	
		// Generate the output code-stream
		if (codestream_out.ready_for_flush())
		{
			nel = codestream_out.trans_out(max_bytes,layer_bytes,total_layers);
			non_empty_layers = (nel > non_empty_layers)?nel:non_empty_layers;
		}
		if (non_empty_layers > total_layers)
			non_empty_layers = total_layers; // Can happen if a tile has more layers
	
		// Print out stats
		std::cout << "Code stream parsing for discard level = " << discard_level << std::endl;
		std::cout << "    Total compressed memory in  = " << mCodeStreamp->get_compressed_data_memory() << " bytes" << std::endl;
		std::cout << "    Total compressed memory out = " << codestream_out.get_compressed_data_memory() << " bytes" << std::endl;
		//std::cout << "    Output contains " << total_layers << " quality layers" << std::endl;		
		std::cout << "    Transferred " << num_blocks << " code-blocks from in to out" << std::endl;
		//std::cout << "    Read " << mCodeStreamp->get_num_tparts() << " tile-part(s) from a total of " << (int) tile_indices_in.area() << " tile(s)" << std::endl;
		std::cout << "    Total bytes read = " << mCodeStreamp->get_total_bytes() << std::endl;
		//std::cout << "    Wrote " << codestream_out.get_num_tparts() << " tile-part(s) in a total of " << (int) tile_indices_out.area() << " tile(s)" << std::endl;
		std::cout << "    Total bytes written = " << codestream_out.get_total_bytes() << std::endl;
		std::cout << "-------------" << std::endl;
	
		// Clean-up
		cleanupCodeStream();
		codestream_out.destroy();
		delete[] output_buffer;	
	}
	return;
}
/* Note that this also does the right thing for colored tiles. */
static int
win_ddb_tile_rectangle(gx_device * dev, const gx_tile_bitmap * tile,
      int x, int y, int w, int h, gx_color_index czero, gx_color_index cone,
		       int px, int py)
{
    fit_fill(dev, x, y, w, h);
    if (czero != gx_no_color_index && cone != gx_no_color_index) {
	fill_rect(x, y, w, h, czero);
	czero = gx_no_color_index;
    }
    if (tile->raster == bmWidthBytes && tile->size.y <= bmHeight &&
	(px | py) == 0 && cone != gx_no_color_index
	) {			/* We can do this much more efficiently */
	/* by using the internal algorithms of copy_mono */
	/* and gx_default_tile_rectangle. */
	int width = tile->size.x;
	int height = tile->size.y;
	int rwidth = tile->rep_width;
	int irx = ((rwidth & (rwidth - 1)) == 0 ?	/* power of 2 */
		   x & (rwidth - 1) :
		   x % rwidth);
	int ry = y % tile->rep_height;
	int icw = width - irx;
	int ch = height - ry;
	int ex = x + w, ey = y + h;
	int fex = ex - width, fey = ey - height;
	int cx, cy;

	select_brush((int)cone);

	if (tile->id != wdev->bm_id || tile->id == gx_no_bitmap_id) {
	    wdev->bm_id = tile->id;
	    SetBitmapBits(wdev->hbmmono,
			  (DWORD) (bmWidthBytes * tile->size.y),
			  (BYTE *) tile->data);
	}
#define copy_tile(srcx, srcy, tx, ty, tw, th)\
  BitBlt(wdev->hdcbit, tx, ty, tw, th, wdev->hdcmono, srcx, srcy, rop_write_at_1s)

	if (ch > h)
	    ch = h;
	for (cy = y;;) {
	    if (w <= icw)
		copy_tile(irx, ry, x, cy, w, ch);
	    else {
		copy_tile(irx, ry, x, cy, icw, ch);
		cx = x + icw;
		while (cx <= fex) {
		    copy_tile(0, ry, cx, cy, width, ch);
		    cx += width;
		}
		if (cx < ex) {
		    copy_tile(0, ry, cx, cy, ex - cx, ch);
		}
	    }
	    if ((cy += ch) >= ey)
		break;
	    ch = (cy > fey ? ey - cy : height);
	    ry = 0;
	}

	win_update((gx_device_win *) dev);
	return 0;
    }
    return gx_default_tile_rectangle(dev, tile, x, y, w, h, czero, cone, px, py);
}
Exemple #4
0
static void loadsty(char* filename, char* exprt, char* setname_tex, char* setname_spr, char* setname_font, char* etiles, char* esprites) {
	sty = fopen(filename,"rb");
	fseek(sty,0,2);
	int filesize = ftell(sty);
	fseek(sty,0,0);

	printf("Reading %s...\n",filename);

	FREAD(&chunkheader, 1, 4, sty, filename, printf);
	FREAD(&chunkdata, 2, 1, sty, filename, printf);
	if (chunkheader != 0x54534247) { //GBST
		printf("Not a GTA2 style file!\n");
		return;
	}

	if ((chunkdata & 0xFFFF) != 700) {
		printf("Bad GTA2 style file version (must be 700)\n");
		return;
	}

	sprite_count = 0;

	bool TilesPresent = false;
	bool SpritesPresent = false;

	//read map chunks	
	while (ftell(sty) < filesize) {
		FREAD(&chunkheader, 1, 4, sty, filename, printf);
		FREAD(&chunkdata, 1, 4, sty, filename, printf);
		printf("\n");

		/*
		PALX palette index
		PPAL physical palettes
		PALB palette base
		TILE tiles
		SPRG sprite graphics
		SPRX sprite index
		SPRB sprites bases
		DELS delta store
		DELX delta index
		FONB font base
		CARI car info
		OBJI map object info
		PSXT PSX tiles
		RECY car recycling info*/

		switch (chunkheader) {
			case 0x584C4150: //PALX
				printf("PALX: Found PALX chunk [size: %d]\n",chunkdata);
				printf("PALX: Reading %d pallete entries\n",chunkdata/2);
				FREAD(&pallete_index,1,32768,sty, filename, printf);
				break;
			case 0x4C415050: //PPAL
				printf("PPAL: Found PPAL chunk [size: %d]\n",chunkdata);
				printf("PPAL: Reading %d pallete pages (%d palletes)\n",chunkdata/(64*1024),chunkdata/(1024));
				FREAD(&pallete,4,chunkdata/4,sty, filename, printf);
				break;
			case 0x424C4150: //PALB
				printf("PALB: Found PALB chunk [size: %d]\n",chunkdata);
				printf("PALB: Reading pallete bases...\n");

				FREAD(&palletebase.tile,2,1,sty, filename, printf);
				FREAD(&palletebase.sprite,2,1,sty, filename, printf);
				FREAD(&palletebase.car_remap,2,1,sty, filename, printf);
				FREAD(&palletebase.ped_remap,2,1,sty, filename, printf);
				FREAD(&palletebase.code_obj_remap,2,1,sty, filename, printf);
				FREAD(&palletebase.map_obj_remap,2,1,sty, filename, printf);
				FREAD(&palletebase.user_remap,2,1,sty, filename, printf);
				FREAD(&palletebase.font_remap,2,1,sty, filename, printf);

				printf("PALB: tile base: %d\n",palletebase.tile);
				printf("PALB: sprite base: %d\n",palletebase.sprite);
				printf("PALB: car_remap base: %d\n",palletebase.car_remap);
				printf("PALB: ped_remap base: %d\n",palletebase.ped_remap);
				printf("PALB: code_obj_remap base: %d\n",palletebase.code_obj_remap);
				printf("PALB: map_obj_remap base: %d\n",palletebase.map_obj_remap);
				printf("PALB: user_remap base: %d\n",palletebase.user_remap);
				printf("PALB: font_remap base: %d\n",palletebase.font_remap);
				break;
			case 0x454C4954: //TILE
				printf("TILE: Found TILE chunk [size: %d]\n",chunkdata);
				printf("TILE: Reading %d tiles...\n",chunkdata/(64*64));
				FREAD(&tile_data,1,chunkdata,sty, filename, printf);
				TilesPresent = true;
				break;
			case 0x47525053: //SPRG
				printf("SPRG: Found SPRG chunk [size: %d]\n",chunkdata);
				printf("SPRG: Reading sprite graphics\n");
				FREAD(&spritedata[0],1,chunkdata,sty, filename, printf);
				SpritesPresent = true;
				break;
			case 0x58525053: //SPRX
				printf("SPRX: Found SPRX chunk [size: %d]\n",chunkdata);
				printf("SPRX: Reading %d sprites...\n",chunkdata/8);
				FREAD(&sprite_entries[0],1,chunkdata,sty, filename, printf);
				sprite_count = chunkdata/8;
				break;
			case 0x42525053: //SPRB
				unsigned short temp;

				printf("SPRB: Found SPRB chunk [size: %d]\n",chunkdata);
				printf("SPRB: Reading sprite bases...\n");

				spritebase.car = 0;
				FREAD(&temp,2,1,sty, filename, printf); spritebase.ped = spritebase.car + temp;
				FREAD(&temp,2,1,sty, filename, printf); spritebase.code_obj = spritebase.ped + temp;
				FREAD(&temp,2,1,sty, filename, printf); spritebase.map_obj = spritebase.code_obj + temp;
				FREAD(&temp,2,1,sty, filename, printf); spritebase.user = spritebase.map_obj + temp;
				FREAD(&temp,2,1,sty, filename, printf); spritebase.font = spritebase.user + temp;
				FREAD(&temp,2,1,sty, filename, printf); 

				/*spritebase.ped = spritebase.car;
				spritebase.car = 0;
				spritebase.code_obj += spritebase.ped;
				spritebase.map_obj += spritebase.code_obj;
				spritebase.user += spritebase.map_obj;
				spritebase.font += spritebase.user;*/

				printf("SPRB: car base: %d\n",spritebase.car);
				printf("SPRB: ped base: %d\n",spritebase.ped);
				printf("SPRB: code_obj base: %d\n",spritebase.code_obj);
				printf("SPRB: map_obj base: %d\n",spritebase.map_obj);
				printf("SPRB: user base: %d\n",spritebase.user);
				printf("SPRB: font base: %d\n",spritebase.font);
				break;
			case 0x534C4544: //DELS
				printf("DELS: Found DELS chunk [size: %d]\n",chunkdata);
				fseek(sty,chunkdata,1);
				break;
			case 0x584C4544: //DELX
				printf("DELX: Found DELX chunk [size: %d]\n",chunkdata);
				fseek(sty,chunkdata,1);
				break;
			case 0x424E4F46: //FONB
				printf("FONB: Found FONB chunk [size: %d]\n",chunkdata);
				//fseek(sty,chunkdata,1);
				FREAD(&fontbase.font_count,2,1,sty, filename, printf);
				printf("FONB: Found %d fonts...\n",fontbase.font_count);
				fontbase.sprbase[0] = spritebase.font;
				for (int i=0;i<fontbase.font_count;i++) {
					FREAD(&fontbase.base[i],2,1,sty, filename, printf);
					if (i > 0) fontbase.sprbase[i] = fontbase.sprbase[i-1] + fontbase.base[i];
					printf("FONB: Font %d [%d characters, sprbase %d]\n",i,fontbase.base[i],fontbase.sprbase[i]);
				}
				break;
			case 0x49524143: //CARI
				printf("CARI: Found CARI chunk [size: %d]\n",chunkdata);
				fseek(sty,chunkdata,1);
				break;
			case 0x494A424F: //OBJI
				printf("OBJI: Found OBJI chunk [size: %d]\n",chunkdata);
				fseek(sty,chunkdata,1);
				break;
			case 0x54585350: //PSXT
				printf("PSXT: Found PSXT chunk, skipping (dont need PSX tiles) [size: %d]\n",chunkdata);
				fseek(sty,chunkdata,1);
				break;
			case 0x59434552: //RECY
				printf("RECY: Found RECY chunk [size: %d]\n",chunkdata);
				fseek(sty,chunkdata,1);
				break;
			case 0x43455053: //SPEC
				printf("SPEC: Undocumented SPEC chunk, skipping [size: %d]\n",chunkdata);
				fseek(sty,chunkdata,1);
				break;
			default:
				printf("UNKN: Unknown/unsupported chunk, skipping [size: %d]\n",chunkdata);
				fseek(sty,chunkdata,SEEK_CUR);
				break;
		}
	}

	if (strcmp(exprt,"true") == 0) {
		if (strcmp(etiles,"true") != 0) {
			printf("\nExporting tiles...\n");
			for (int i=0;i<992;i++) {
				char tilename[256];
		
				sprintf(&tilename[0],"tile_%d.bmp",i);
				save_tile(&tilename[0],i);
		
				printf("..writing tile bitmaps %d\r",i);
			}
		}
		if (strcmp(esprites,"true") == 0) {
			printf("\n\nExporting sprites...\n");
			for (int i=0;i<sprite_count;i++) {
				char tilename[256];
		
				sprintf(&tilename[0],"sprite_%d.bmp",i);
				save_sprite(&tilename[0],i);
		
				printf("..writing sprite %d\r",i);
			}
		}
	}

	printf("\nSaving graphics (opengta.tex)\n");

	bmp = fopen("opengta.tex","wb+");
	char header[5] = "ZTEX"; int chunksize = 4; int texversion = 130;
	fwrite(&header[0],1,4,bmp); //"ZTEX"
	fwrite(&chunksize,4,1,bmp);
	fwrite(&texversion,4,1,bmp);
	printf("\tchunk %s (%d bytes)\n",header,chunksize);

	if (strcmp(etiles,"true") != 0) {
		TilesPresent = false;
	}
	if (strcmp(esprites,"true") != 0) {
		SpritesPresent = false;
	}

	//Write tile data
	int cpos;

	if (TilesPresent) {
		sprintf(header,"%s","TILE"); chunksize = 0;
		fwrite(&header[0],1,4,bmp); //"TILE"
		cpos = ftell(bmp); 
		chunksize += fwrite(&chunksize,4,1,bmp);
	
		texversion = strlen(setname_tex); 
		chunksize += fwrite(&texversion,1,1,bmp); //TILEID: 0
		chunksize += fwrite(&setname_tex[0],1,texversion,bmp);
	
		printf("\t\tGenerating texture atlas for tiles\n");
		Texture_Atlas tileAtlas;
		tileAtlas.createEmpty(2048,2048);
		tileAtlas.atlasStart(1024);
		for (int i=0;i<992;i++) {
			copy_tile(i);
			printf("\t\tTile: %d out of %d\r",i,992);
			tileAtlas.atlasAdd(0x1,0x0,4,64,64,(unsigned char*)&sprite_buffer[0]);
			//write_tile_tex(i);
		}
		printf("\nEffective atlas size: %d bytes (%d KB)\n",tileAtlas.effectiveSize(),tileAtlas.effectiveSize() / 1024);
		tileAtlas.atlasStop();
		tileAtlas.dumpBMP("tiles.bmp");
		//Write atlas
		chunksize += fwrite(tileAtlas.textureData,1,tileAtlas.effectiveSize(),bmp);
		//for (int y = 0; y < tileAtlas.atlasHeight; y++)
			//for (int x = 0; x < tileAtlas.atlasWidth; x++)
				//fwrite(&tileAtlas.textureData[x+y*tileAtlas.atlasWidth],4,1,bmp);
		tileAtlas.releaseTexture();
	
		printf("\tchunk %s (%d bytes)\n",header,chunksize);
		fseek(bmp,cpos,0); fwrite(&chunksize,4,1,bmp);
		fseek(bmp,chunksize,1);
	}





	//Write sprite data
	if (SpritesPresent) {
		sprintf(header,"%s","SPR0"); chunksize = 0;
		fwrite(&header[0],1,4,bmp); //"SPR0" (sprite data)
		cpos = ftell(bmp); 
		fwrite(&chunksize,4,1,bmp);
	
		texversion = strlen(setname_spr); 
		chunksize += fwrite(&texversion,1,1,bmp); //TILEID: 0
		chunksize += fwrite(&setname_spr[0],1,texversion,bmp);
	
		//Prepare tiles
		for (int i = 0; i < sprite_count; i++) sprite_entries[i].pad = i;
		sort_tiles();
	
		printf("\t\tGenerating texture atlas for sprites (takes a while)\n");
		Texture_Atlas spriteAtlas;
		spriteAtlas.createEmpty(2048,2048);
		spriteAtlas.atlasStart(8192);
		//sprite_count = 64;
		int atlasid[8192];
		for (int i=0;i<sprite_count;i++) {
			copy_sprite(i);
			printf("\t\tSprite: %d out of %d\r",i,sprite_count);
			atlasid[sprite_entries[i].pad] = spriteAtlas.atlasAdd(0x1,0x0,4,sprite_entries[i].w,sprite_entries[i].h,(unsigned char*)&sprite_buffer[0]);
		}
		printf("\nEffective atlas size: %d bytes (%d KB)\n",spriteAtlas.effectiveSize(),spriteAtlas.effectiveSize() / 1024);
		printf("\t\tWriting sprites\n");
	
		//Unsort sprites (from previous sort request)
		bool all_sort;
		do {
			all_sort = true;
			for (int i = 0; i < sprite_count; i++)
				if (sprite_entries[i].pad != i) {
					int j = sprite_entries[i].pad;
					sprite_entry tmp = sprite_entries[i];
					sprite_entries[i] = sprite_entries[j];
					sprite_entries[j] = tmp;
					all_sort = false;
				}
		} while (all_sort == false);

		//Write sprite information
		chunksize += 4*fwrite(&sprite_count,4,1,bmp);
		for (int i=0;i<sprite_count;i++) {
			char spritename[256];
			sprintf(&spritename[0],"%s_%d",setname_spr,i);
			unsigned char namelen = strlen(&spritename[0]);

			chunksize += fwrite(&namelen,1,1,bmp);
			chunksize += fwrite(&spritename[0],1,namelen,bmp);
			//chunksize += fwrite(&sprite_entries[i].w,1,1,bmp);
			//chunksize += fwrite(&sprite_entries[i].h,1,1,bmp);
			//chunksize += fwrite(&sprite_entries[i].,1,1,bmp);

			chunksize += 4*fwrite(&spriteAtlas.atlasTextures[atlasid[i]].Left,4,1,bmp);
			chunksize += 4*fwrite(&spriteAtlas.atlasTextures[atlasid[i]].Right,4,1,bmp);
			chunksize += 4*fwrite(&spriteAtlas.atlasTextures[atlasid[i]].Top,4,1,bmp);
			chunksize += 4*fwrite(&spriteAtlas.atlasTextures[atlasid[i]].Bottom,4,1,bmp);
		}
		
		spriteAtlas.atlasStop();
		spriteAtlas.dumpBMP("sprites.bmp");
		//Write atlas
		chunksize += fwrite(spriteAtlas.textureData,1,spriteAtlas.effectiveSize(),bmp);
		//for (int y = 0; y < spriteAtlas.atlasHeight; y++)
			//for (int x = 0; x < spriteAtlas.atlasWidth; x++)
				//fwrite(&spriteAtlas.textureData[x+y*spriteAtlas.atlasWidth],4,1,bmp);

		spriteAtlas.releaseTexture();
		printf("    chunk %s (%d bytes)\n",header,chunksize);
		fseek(bmp,cpos,0); fwrite(&chunksize,4,1,bmp);
		fseek(bmp,chunksize,1);





		sprintf(header,"%s","FNT0"); chunksize = 0;
		fwrite(&header[0],1,4,bmp); //"FNT0" (sprite data)
		cpos = ftell(bmp); fwrite(&chunksize,4,1,bmp);
		chunksize += 2*fwrite(&fontbase.font_count,2,1,bmp); //Font count

		//texversion = strlen(setname_spr); 
		//chunksize += fwrite(&texversion,1,1,bmp); //TILEID: 0
		//chunksize += fwrite(&setname_spr[0],1,texversion,bmp);

		printf("\t\tWriting fonts\n");
		for (int i=0;i<fontbase.font_count;i++) {
			char fontname[256];
			sprintf(&fontname[0],"%s_%d",setname_font,i);
			unsigned char namelen = strlen(&fontname[0]);

			unsigned short numchars = fontbase.base[i] + '!';

			chunksize += fwrite(&namelen,1,1,bmp);
			chunksize += fwrite(&fontname[0],1,namelen,bmp);
			chunksize += 2*fwrite(&numchars,2,1,bmp);
			for (int k = 0; k < numchars; k++) {
				char charname[256];
				if ((k >= '!') && (k <= numchars)) {
					sprintf(charname,"%s_%d",setname_spr,k-'!'+fontbase.sprbase[i]);
					namelen = strlen(charname);
				} else {
					namelen = 0;
				}

				chunksize += fwrite(&namelen,1,1,bmp);
				chunksize += fwrite(&charname[0],1,namelen,bmp);
			}
		}

		printf("    chunk %s (%d bytes)\n",header,chunksize);
		fseek(bmp,cpos,0); fwrite(&chunksize,4,1,bmp);
		fseek(bmp,chunksize,1);
	}
	fclose(bmp);

/*
ZTEX Texture file header
SPR0 GTA2-exported sprites (2048x2048 atlas)
SPR1 GTA2-exported sprites (1024x1024 atlas)
SPR2 GTA2-exported sprites (256x256 atlas)
SPR3 OpenGTA2 sprites (variable atlas size)
TILE GTA2-exported tiles (2048x2048 atlas by 64x64 tiles)
TIL1 GTA2-exported tiles (1024x1024 atlas)
TIL2 GTA2-exported tiles (256x256 atlas)
TIL3 OpenGTA2 tiles (variable tile size, variable atlas size)
FNT0 GTA2-exported fonts
FNT1 OpenGTA2 fonts (sprite based)
FNT2 OpenGTA2 fonts (with font graphics)

PACK Packed information (unpacked into different chunk)
*/

	printf("\nDone!\n");

	fclose(sty);
}
Exemple #5
0
/* Default implementation of tile_rectangle */
int
gx_default_tile_rectangle(gx_device *dev, register const gx_bitmap *tile,
  int x, int y, int w, int h, gx_color_index color0, gx_color_index color1,
  int px, int py)
{	/* Fill the rectangle in chunks */
	int width = tile->size.x;
	int height = tile->size.y;
	int raster = tile->raster;
	int rwidth = tile->rep_width;
	int irx = ((rwidth & (rwidth - 1)) == 0 ?	/* power of 2 */
		(x + px) & (rwidth - 1) :
		(x + px) % rwidth);
	int ry = (y + py) % tile->rep_height;
	int icw = width - irx;
	int ch = height - ry;
	byte *row = tile->data + ry * raster;
#define d_proc_mono (dev->procs->copy_mono)
	dev_proc_copy_mono((*proc_mono));
#define d_proc_color (dev->procs->copy_color)
	dev_proc_copy_color((*proc_color));
#define d_color_halftone\
		(color0 == gx_no_color_index && color1 == gx_no_color_index)
	int color_halftone;
#define get_color_info()\
  if ( (color_halftone = d_color_halftone) ) proc_color = d_proc_color;\
  else proc_mono = d_proc_mono
	int code;
#ifdef DEBUG
if ( gs_debug['t'] )
   {	int ptx, pty;
	const byte *ptp = tile->data;
	dprintf3("[t]tile %dx%d raster=%d;",
		tile->size.x, tile->size.y, tile->raster);
	dprintf6(" x,y=%d,%d w,h=%d,%d p=%d,%d\n",
		x, y, w, h, px, py);
	for ( pty = 0; pty < tile->size.y; pty++ )
	   {	dprintf("   ");
		for ( ptx = 0; ptx < tile->raster; ptx++ )
			dprintf1("%3x", *ptp++);
	   }
	dputc('\n');
   }
#endif
#define real_copy_tile(srcx, tx, ty, tw, th)\
  code =\
    (color_halftone ?\
     (*proc_color)(dev, row, srcx, raster, gx_no_bitmap_id, tx, ty, tw, th) :\
     (*proc_mono)(dev, row, srcx, raster, gx_no_bitmap_id, tx, ty, tw, th, color0, color1));\
  gp_check_interrupts();\
  if ( code < 0 ) return_error(code)
#ifdef DEBUG
#define copy_tile(sx, tx, ty, tw, th)\
  if ( gs_debug['t'] )\
	dprintf5("   copy sx=%d x=%d y=%d w=%d h=%d\n",\
		 sx, tx, ty, tw, th);\
  real_copy_tile(sx, tx, ty, tw, th)
#else
#define copy_tile(sx, tx, ty, tw, th)\
  real_copy_tile(sx, tx, ty, tw, th)
#endif
	if ( icw >= w )
	   {	/* Narrow operation */
		int ey, fey, cy;
		if ( ch >= h )
		   {	/* Just one (partial) tile to transfer. */
#define color_halftone d_color_halftone
#define proc_color d_proc_color
#define proc_mono d_proc_mono
			copy_tile(irx, x, y, w, h);
#undef proc_mono
#undef proc_color
#undef color_halftone
			return 0;
		   }
		get_color_info();
		ey = y + h;
		fey = ey - height;
		copy_tile(irx, x, y, w, ch);
		cy = y + ch;
		row = tile->data;
		do
		   {	ch = (cy > fey ? ey - cy : height);
			copy_tile(irx, x, cy, w, ch);
		   }
		while ( (cy += ch) < ey );
		return 0;
	   }
	get_color_info();
	if ( ch >= h )
	   {	/* Shallow operation */
		int ex = x + w;
		int fex = ex - width;
		int cx = x + icw;
		copy_tile(irx, x, y, icw, h);
		while ( cx <= fex )
		   {	copy_tile(0, cx, y, width, h);
			cx += width;
		   }
		if ( cx < ex )
		   {	copy_tile(0, cx, y, ex - cx, h);
		   }
	   }
	else
	   {	/* Full operation */
		int ex = x + w, ey = y + h;
		int fex = ex - width, fey = ey - height;
		int cx, cy;
		for ( cy = y; ; )
		   {	copy_tile(irx, x, cy, icw, ch);
			cx = x + icw;
			while ( cx <= fex )
			   {	copy_tile(0, cx, cy, width, ch);
				cx += width;
			   }
			if ( cx < ex )
			   {	copy_tile(0, cx, cy, ex - cx, ch);
			   }
			if ( (cy += ch) >= ey ) break;
			ch = (cy > fey ? ey - cy : height);
			row = tile->data;
		   }
	   }
#undef copy_tile
#undef real_copy_tile
	return 0;
}