* Add codenet lua script (linux only for now) to send pictures to a runnning C64

* Fix C64 multicolor format :
   - Improve background color detection
   - Do not save as FLI unless the file extension matches

fixes #521, #522 and #524


git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@2043 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Adrien Destugues 2012-12-29 18:58:07 +00:00
parent 613ad628dd
commit 92e438bde5
2 changed files with 162 additions and 71 deletions

View File

@ -0,0 +1,17 @@
-- Codenet send for grafx2 2.4 and up, by Michael Ilsaas.
-- Sends the latest saved picture. Set the IP address of the C64 in the line below.
ip = "192.168.0.64"; -- <-- IP address of the C64.
fn, fp = getfilename();
picfile = assert(io.open(fp .. '/' .. fn ,"r"));
picsize = picfile:seek("end")
picfile:close();
if picsize == 9000 or picsize == 9002 then -- check for hires
os.execute("echo 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 | base64 -d > /tmp/picview.prg");
else
os.execute("echo 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 | base64 -d > /tmp/picview.prg");
end
if picsize == 9000 or picsize == 10001 then -- check for loadaddress, add two bytes if not found
os.execute('echo a >> /tmp/picview.prg');
end
os.execute('cat '.. fp .. '/' .. fn .. ' >> /tmp/picview.prg'); -- append pic to c64 binary
os.execute("codenet -x /tmp/picview.prg -n "..ip); -- send file to c64

View File

@ -2690,7 +2690,13 @@ int Save_C64_multi(T_IO_Context *context, char *filename, byte saveWhat, byte lo
*/ */
int cx,cy,x,y,c[4]={0,0,0,0},color,lut[16],bits,pixel,pos=0; int cx,cy,x,y,c[4]={0,0,0,0},color,lut[16],bits,pixel,pos=0;
int cand,n,used;
word cols, candidates = 0, invalids = 0;
// FIXME allocating this on the stack is not a good idea. On some platforms
// the stack has a rather small size...
byte bitmap[8000],screen_ram[1000],color_ram[1000]; byte bitmap[8000],screen_ram[1000],color_ram[1000];
word numcolors,count; word numcolors,count;
dword cusage[256]; dword cusage[256];
byte i,background=0; byte i,background=0;
@ -2699,81 +2705,144 @@ int Save_C64_multi(T_IO_Context *context, char *filename, byte saveWhat, byte lo
numcolors=Count_used_colors(cusage); numcolors=Count_used_colors(cusage);
count=0; count=0;
for(x=0;x<16;x++)
{
//printf("color %d, pixels %d\n",x,cusage[x]);
if(cusage[x]>count)
{
count=cusage[x];
background=x;
}
}
for(cy=0; cy<25; cy++) // Detect the ackground color the image should be using. It's the one that's
{ // used on all tiles having 4 colors.
//printf("\ny:%2d ",cy); for(y=0;y<200;y=y+8)
for(cx=0; cx<40; cx++) {
{ for (x = 0; x<160; x=x+4)
numcolors=Count_used_colors_area(cusage,cx*4,cy*8,4,8); {
if(numcolors>4) cols = 0;
{
Warning_message("More than 4 colors in 4x8"); // Compute the usage count of each color in the tile
// TODO hilite offending block for (cy=0;cy<8;cy++)
return 1; for (cx=0;cx<4;cx++)
} {
color=1; pixel=Get_pixel(context, x+cx,y+cy);
c[0]=background; cols |= (1 << pixel);
for(i=0; i<16; i++) }
{
lut[i]=0; cand = 0;
if(cusage[i]) used = 0;
{ // Count the number of used colors in the tile
if(i!=background) for (n = 0; n<16; n++)
{ {
lut[i]=color; if (cols & (1 << pixel))
c[color]=i; used++;
color++; }
}
else if (used>3)
{ {
lut[i]=0; // This is a tile that uses the background color (and 3 others)
}
} // Try to guess which color is most likely the background one
} for (n = 0; n<16; n++)
// add to screen_ram and color_ram {
screen_ram[cx+cy*40]=c[1]<<4|c[2]; if ((cols & (1 << n)) && !((candidates | invalids) & (1 << n))) {
color_ram[cx+cy*40]=c[3]; // This color was not used in any other tile yet,
//printf("%x%x%x ",c[1],c[2],c[3]); // but it could be the background one.
for(y=0;y<8;y++) candidates |= 1 << n;
{ }
bits=0;
for(x=0;x<4;x++) if ((cols & 1 << n) == 0 ) {
{ // This color isn't used at all in this tile:
pixel=Get_pixel(context, cx*4+x,cy*8+y); // Can't be the global
if(pixel>15) invalids |= 1 << n;
{ }
Warning_message("Color above 15 used");
// TODO hilite as in hires, you should stay to if (candidates & (1 << n)) {
// the fixed 16 color palette // We have a candidate, mark it as such
return 1; cand++;
} }
bits=bits<<2; }
bits|=lut[pixel];
// After checking the constraints for this tile, do we have
} // candidate background colors left ?
//Write_byte(file,bits&255); if (cand==0)
bitmap[pos++]=bits; {
} Warning_message("No possible global background color found");
} return 1;
} }
}
}
}
// Now just pick the first valid candidate
for (n = 0; n<16; n++)
{
if (candidates & (1 << n)) {
background = n;
break;
}
}
// Now that we know which color is the background, we can encode the cells
for(cy=0; cy<25; cy++)
{
//printf("\ny:%2d ",cy);
for(cx=0; cx<40; cx++)
{
numcolors=Count_used_colors_area(cusage,cx*4,cy*8,4,8);
if(numcolors>4)
{
Warning_message("More than 4 colors in 4x8");
// TODO hilite offending block
return 1;
}
color=1;
c[0]=background;
for(i=0; i<16; i++)
{
lut[i]=0;
if(cusage[i])
{
if(i!=background)
{
lut[i]=color;
c[color]=i;
color++;
}
else
{
lut[i]=0;
}
}
}
// add to screen_ram and color_ram
screen_ram[cx+cy*40]=c[1]<<4|c[2];
color_ram[cx+cy*40]=c[3];
//printf("%x%x%x ",c[1],c[2],c[3]);
for(y=0;y<8;y++)
{
bits=0;
for(x=0;x<4;x++)
{
pixel=Get_pixel(context, cx*4+x,cy*8+y);
if(pixel>15)
{
Warning_message("Color above 15 used");
// TODO hilite as in hires, you should stay to
// the fixed 16 color palette
return 1;
}
bits=bits<<2;
bits|=lut[pixel];
}
//Write_byte(file,bits&255);
bitmap[pos++]=bits;
}
}
}
file = fopen(filename,"wb"); file = fopen(filename,"wb");
if(!file) if(!file)
{ {
Warning_message("File open failed"); Warning_message("File open failed");
File_error = 1; File_error = 2;
return 1; return 2;
} }
setvbuf(file, NULL, _IOFBF, 64*1024); setvbuf(file, NULL, _IOFBF, 64*1024);
@ -2883,10 +2952,15 @@ void Save_C64(T_IO_Context * context)
} }
//printf("saveWhat=%d, loadAddr=%d\n",saveWhat,loadAddr); //printf("saveWhat=%d, loadAddr=%d\n",saveWhat,loadAddr);
if (context->Width==320) if (strcasecmp(filename + strlen(filename) - 4, ".fli") == 0)
File_error = Save_C64_hires(context,filename,saveWhat,loadAddr); {
else // FIXME moving FLI to a separate format in the fileselector would be smarter
File_error = Save_C64_fli(filename,saveWhat,loadAddr); File_error = Save_C64_fli(filename,saveWhat,loadAddr);
} else if (context->Width==320)
File_error = Save_C64_hires(context,filename,saveWhat,loadAddr);
else {
File_error = Save_C64_multi(context, filename,saveWhat,loadAddr);
}
} }