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(); }
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(¤tProject->tileC->tDat[(c*currentProject->tileC->tileSize)],¤tProject->tileC->truetDat[(c*256)],foundRow,true,alphaZero); }else currentProject->tileC->tileToTrueCol(¤tProject->tileC->tDat[(c*currentProject->tileC->tileSize)],¤tProject->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(); }
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(); } }