예제 #1
0
void load_truecolor_tiles(Fl_Widget*,void*){
	if(!currentProject->containsData(pjHaveTiles)){
		currentProject->haveMessage(pjHaveTiles);
		return;
	}
	//start by loading the file
	filereader f=filereader("Load truecolor tiles");
	if(!f.amt)
		return;
	unsigned i=f.selDat();
	size_t file_size = f.lens[i];
	if (file_size&255){
		fl_alert("Error: this file is not a multiple of 256 so it is not a valid truecolor tiles. The file size is: %d",file_size);
		return;
	}
	currentProject->tileC->truetDat.resize(file_size);
	currentProject->tileC->tDat.resize(file_size*currentProject->tileC->tileSize/currentProject->tileC->tcSize);
	memcpy(currentProject->tileC->truetDat.data(),f.dat[i],file_size);
	currentProject->tileC->amt=file_size/256;
	updateTileSelectAmt();
	window->redraw();
}
예제 #2
0
void load_tiles(Fl_Widget*,void*o){
	//if o=0 load if o=1 append if o=2 load at
	if(!currentProject->containsData(pjHaveTiles)){
		currentProject->haveMessage(pjHaveTiles);
		return;
	}
	size_t file_size;
	unsigned mode=(uintptr_t)o;
	char * returned=(char*)fl_input("What row should these tiles use?\nEnter 0 to 3 to selected a row or -1 to -4 to auto determine based on tilemap\nWhen specifing a negative number to figure out what the default will be use this formula abs(row)-1","-1");
	if (unlikely(!returned))
		return;
	if (unlikely(!verify_str_number_only(returned)))
		return;
	int row=atoi(returned);
	if (unlikely((row > 3) || (row < -4))){
		fl_alert("You entered %d which is out of range it must be in range of -4 to 3",row);
		return;
	}
	uint8_t defaultRow=row >= 0 ? row:abs(row)-1;
	int compression=compressionAsk();
	bool alphaZero=fl_ask("Set color #0 to alpha 0 instead of 255")?true:false;
	void*output;
	filereader f=filereader("Load tiles");
	if(f.amt==0)
		return;
	unsigned idx=f.selDat();
	file_size = f.lens[idx];
	unsigned truecolor_multiplier;
	truecolor_multiplier=256/currentProject->tileC->tileSize;
	if(compression)
		output=decodeTypeRam((uint8_t*)f.dat[idx],f.lens[idx],file_size,compression);
	else{
		if (file_size%currentProject->tileC->tileSize){
			fl_alert("Error: This is not a valid tile file each tile is %d bytes and this file is not a multiple of %d so it is not a valid tile file",currentProject->tileC->tileSize,currentProject->tileC->tileSize);
			return;
		}
	}
	uint32_t offset_tiles;
	uint32_t offset_tiles_bytes;
	if(mode==2){
		const char * str=fl_input("Counting from zero which tile should this start at?");
		if(!str){
			return;
		}
		if(!verify_str_number_only((char*)str)){
			return;
		}
		int off=atoi(str);
		if(off>=0){
			offset_tiles=off;
			offset_tiles_bytes=offset_tiles*currentProject->tileC->tileSize;
		}else{
			fl_alert("You must enter a number greater than or equal to zero");
			return;
		}
	}else if(mode==1){
		offset_tiles=currentProject->tileC->amt;
		offset_tiles_bytes=offset_tiles*currentProject->tileC->tileSize;
	}else{
		offset_tiles=0;
		offset_tiles_bytes=0;
	}
	if(mode==2){
		if(offset_tiles+(file_size/currentProject->tileC->tileSize)>=currentProject->tileC->amt)
			currentProject->tileC->tDat.resize(offset_tiles_bytes+file_size);
	}else
		currentProject->tileC->tDat.resize(offset_tiles_bytes+file_size);
	if(compression){
		memcpy(currentProject->tileC->tDat.data()+offset_tiles_bytes,output,file_size);
		free(output);
	}else
		memcpy(currentProject->tileC->tDat.data()+offset_tiles_bytes,f.dat[idx],file_size);
	if(currentProject->getTileType()!=PLANAR_TILE)
		currentProject->tileC->toPlanar(currentProject->getTileType(),offset_tiles,offset_tiles+(file_size/currentProject->tileC->tileSize));
	if(mode==2){
		if(offset_tiles+(file_size/currentProject->tileC->tileSize)>=currentProject->tileC->amt)
			currentProject->tileC->truetDat.resize((file_size*truecolor_multiplier)+(offset_tiles_bytes*truecolor_multiplier));
	}else
		currentProject->tileC->truetDat.resize((file_size*truecolor_multiplier)+(offset_tiles_bytes*truecolor_multiplier));
	for(uint32_t c=offset_tiles;c<(file_size/currentProject->tileC->tileSize)+offset_tiles;c++) {
		if(row < 0){
			uint32_t x,y;
			uint8_t foundRow=defaultRow;
			for(y=0;y<currentProject->tms->maps[currentProject->curPlane].mapSizeHA;++y){
				for(x=0;x<currentProject->tms->maps[currentProject->curPlane].mapSizeW;++x){
					if(currentProject->tms->maps[currentProject->curPlane].get_tile(x,y) == c) {
						foundRow=currentProject->tms->maps[currentProject->curPlane].getPalRow(x,y);
						goto doTile;
					}
				}
			}
doTile:
			currentProject->tileC->tileToTrueCol(&currentProject->tileC->tDat[(c*currentProject->tileC->tileSize)],&currentProject->tileC->truetDat[(c*256)],foundRow,true,alphaZero);
		}else
			currentProject->tileC->tileToTrueCol(&currentProject->tileC->tDat[(c*currentProject->tileC->tileSize)],&currentProject->tileC->truetDat[(c*256)],defaultRow,true,alphaZero);
	}
	if(mode==2){
		if(offset_tiles+(file_size/currentProject->tileC->tileSize)>=currentProject->tileC->amt){
			currentProject->tileC->amt=(file_size/currentProject->tileC->tileSize);
			currentProject->tileC->amt+=offset_tiles;
		}
	}else{
		currentProject->tileC->amt=(file_size/currentProject->tileC->tileSize);
		currentProject->tileC->amt+=offset_tiles;
	}
	updateTileSelectAmt();
	window->tile_select->value(0);
	window->tile_select_2->value(0);
	window->redraw();
}
예제 #3
0
void sprites::importSpriteSheet(const char*fname){
	if(!fname){
		if(!load_file_generic("Load image"))
			return;
		fname=the_file.c_str();
	}
	if(fname){
		Fl_Shared_Image * loaded_image=Fl_Shared_Image::get(fname);
		if(!loaded_image){
			fl_alert("Error loading image");
			return;
		}
		unsigned depth=loaded_image->d();
		if (unlikely(depth != 3 && depth != 4 && depth!=1)){
			fl_alert("Please use color depth of 1,3 or 4\nYou Used %d",depth);
			loaded_image->release();
			return;
		}else
			printf("Image depth %d\n",depth);
		uint32_t w,h;
		w=loaded_image->w();
		h=loaded_image->h();
		bool grayscale;
		uint8_t*palMap;
		uint8_t*imgptr;
		unsigned remap[256];
		if(depth==1){
			grayscale=handle1byteImg(loaded_image,remap);
			if(!grayscale){
				palMap=(uint8_t*)loaded_image->data()[1];
				imgptr=(uint8_t*)loaded_image->data()[2];
			}
		}
		uint8_t mask[3];
		bool useAlpha;
		if(getMaskColorImg(loaded_image,grayscale,remap,palMap,mask,useAlpha)){
			std::vector<int> rects;//x0,x1,y0,y1
			Fl_Window *winP;
			Fl_Progress *progress;
			mkProgress(&winP,&progress);
			time_t lasttime=time(NULL);
			progress->maximum(h);
			Fl::check();
			for(int y=0;y<h;++y){
				for(int x=0;x<w;++x){
					if(!isMask(x,y,loaded_image,grayscale,useAlpha,mask)){
						rects.push_back(x);
						while(!isMask(x+1,y,loaded_image,grayscale,useAlpha,mask))
							++x;
						rects.push_back(x);
						rects.push_back(y);
						rects.push_back(y);
					}
				}
				if((time(NULL)-lasttime)>=1){
					lasttime=time(NULL);
					progress->value(h);
					Fl::check();
				}
			}
			progress->maximum(rects.size());
			progress->value(0);
			//Now combine the rectangles
			//Start by combining rectangles by that touch with y values
			bool canEnd;
			int pass=0;
			char txtbufstage[1024];
			char txtbuf[1024];
			do{
			canEnd=true;
			snprintf(txtbufstage,1024,"Stage 1 pass %d",pass++);
			winP->label(txtbufstage);
			Fl::check();
			for(int i=0;i<rects.size();i+=4){
				for(int j=0;j<rects.size();j+=4){
					if(i==j)
						continue;
					//See if rectangles are touching or overlap
					//if((inRange(rects[j+2],rects[i+2]-1,rects[i+3]+1)||inRange(rects[i+2],rects[j+2]-1,rects[j+3]+1))&&(!((rects[i+2]==rects[j+2])||(rects[i+3]==rects[j+3])))){//Is rectange j directly above or below i
					if((rects[j+3]-rects[i+2])==1){
						if((inRange(rects[j],rects[i]-1,rects[i+1]+1)||inRange(rects[i],rects[j]-1,rects[j+1]+1))){
							canEnd=false;
							//Merge the two squares obtaining maximum size
							//Now try and find the combination that results in the largest rectangle
							rects[i]=std::min(rects[i],rects[j]);
							rects[i+1]=std::max(rects[i+1],rects[j+1]);
							rects[i+2]=std::min(rects[i+2],rects[j+2]);
							rects[i+3]=std::max(rects[i+3],rects[j+3]);
							rects.erase(rects.begin()+j,rects.begin()+j+4);
							//Now try to find next in sequence
							bool foundit;
							do{
								foundit=false;
								for(int a=0;a<rects.size();a+=4){
									int look=rects[i+3]+1;
									if(rects[a+2]==look){
										if((inRange(rects[a],rects[i]-1,rects[i+1]+1)||inRange(rects[i],rects[a]-1,rects[a+1]+1))){
											foundit=true;
											rects[i]=std::min(rects[i],rects[a]);
											rects[i+1]=std::max(rects[i+1],rects[a+1]);
											rects[i+2]=std::min(rects[i+2],rects[a+2]);
											rects[i+3]=std::max(rects[i+3],rects[a+3]);
											rects.erase(rects.begin()+a,rects.begin()+a+4);
										}
									}
								}
							}while(foundit);
						}
					}
				}
				if((time(NULL)-lasttime)>=1){
					lasttime=time(NULL);
					progress->maximum(rects.size());
					progress->value(i);
					snprintf(txtbuf,1024,"Rectangles: %d",rects.size());
					progress->label(txtbuf);
					Fl::check();
				}
			}
			}while(!canEnd);
			pass=0;
			do{
				canEnd=true;
				snprintf(txtbufstage,1024,"Stage 2 pass %d",pass++);
				winP->label(txtbufstage);
				progress->maximum(rects.size());
				progress->value(0);
				Fl::check();
				for(int i=0;i<rects.size();i+=4){
					for(int j=0;j<rects.size();j+=4){
						if(i==j)
							continue;
						//Merge overlapping rectangles
						if((rects[i]<=rects[j+1])&&(rects[i+1]>=rects[j])&&(rects[i+2]<=rects[j+3])&&(rects[i+3]>=rects[j+2])){
							canEnd=false;
							rects[i]=std::min(rects[i],rects[j]);
							rects[i+1]=std::max(rects[i+1],rects[j+1]);
							rects[i+2]=std::min(rects[i+2],rects[j+2]);
							rects[i+3]=std::max(rects[i+3],rects[j+3]);
							rects.erase(rects.begin()+j,rects.begin()+j+4);
						}
						//Merge touching rectangles
						if(abs(rects[i+1]-rects[j])==1){
							if((inRange(rects[j+2],rects[i+2]-1,rects[i+3]+1)||inRange(rects[i+2],rects[j+2]-1,rects[j+3]+1))){
								canEnd=false;
								rects[i]=std::min(rects[i],rects[j]);
								rects[i+1]=std::max(rects[i+1],rects[j+1]);
								rects[i+2]=std::min(rects[i+2],rects[j+2]);
								rects[i+3]=std::max(rects[i+3],rects[j+3]);
								rects.erase(rects.begin()+j,rects.begin()+j+4);
							}
						}
					}
					if((time(NULL)-lasttime)>=1){
						lasttime=time(NULL);
						progress->maximum(rects.size());
						progress->value(i);
						snprintf(txtbuf,1024,"Rectangles: %d",rects.size());
						progress->label(txtbuf);
						Fl::check();
					}
				}
			}while(!canEnd);
			winP->remove(progress);// remove progress bar from window
			delete(progress);// deallocate it
			delete winP;
			std::vector<bool> deleted;
			deleted.resize(rects.size()/4);
			//Now show the window allowing user to adjust sprite settings
			if(window){
				win=new Fl_Double_Window(640,480,"Sprite selection");
				win->begin();
				win->resizable(win);
				Fl_Button * Ok=new Fl_Button(256,448,64,24,"Okay");
				Ok->callback(RetCB,(void*)1);
				Fl_Button * Cancel=new Fl_Button(320,448,64,24,"Cancel");
				Cancel->callback(RetCB,0);
				Fl_Scroll*scroll=new Fl_Scroll(8,8,624,440);
				box=new RectBox(8,8,w,h);
				box->scroll=scroll;
				box->rects=&rects;
				box->deleted=&deleted;
				box->image(loaded_image);
				scroll->end();
				win->end();
				win->set_modal();
				win->show();
				Fl::check();

				while(win->shown())
					Fl::wait();
				delete win;
			}else
				retOkay=true;
			if(retOkay){
				for(unsigned i=0;i<rects.size();i+=4){
					recttoSprite(rects[i],rects[i+1],rects[i+2],rects[i+3],-1,loaded_image,grayscale,remap,palMap,mask,true,useAlpha);
				}
				updateTileSelectAmt();
			}
			deleted.clear();
			rects.clear();
		}
		loaded_image->release();
	}
}