Convert image to FLI when enabling the mode. show errors in layer 4

This commit is contained in:
Thomas Bernard 2018-12-10 20:26:36 +01:00
parent fd6e420008
commit 2d392fb7b1
No known key found for this signature in database
GPG Key ID: 0FF11B67A5C0863C
4 changed files with 106 additions and 12 deletions

View File

@ -437,6 +437,11 @@ void Button_Constraint_mode(void)
Verbose_message("Error!", "Emulation of Amstrad CPC's Mode5 can only be used on an image whose width is a multiple of 48.");
return;
}
if (Selected_Constraint_Mode == IMAGE_MODE_C64FLI && ((Main.image_width < 160) || (Main.image_height < 200)))
{
Verbose_message("Error!", "Emulation of Commodore 64 FLI Mode needs a 160x200 sized image.");
return;
}
// now check the constraints on existing pixels
switch (Selected_Constraint_Mode)
@ -467,14 +472,54 @@ void Button_Constraint_mode(void)
// switch to layer mode if needed
if (Main.backups->Pages->Image_mode != IMAGE_MODE_LAYERED)
Switch_layer_mode(IMAGE_MODE_LAYERED);
Main.backups->Pages->Transparent_color = 16;
// auto-create extra layers
while (Main.backups->Pages->Nb_layers < 3)
if (Add_layer(Main.backups, Main.backups->Pages->Nb_layers))
if (Add_layer(Main.backups, 0))
{
Verbose_message("Error!", "Failed to create the 3 layers needed by C64 Flexible Line Interpretation mode.");
return;
}
Main.backups->Pages->Transparent_color = 16;
{
word x, y;
byte bitmap[8000],screen_ram[1024*8],color_ram[1024];
byte background[200];
memset(bitmap, 0, sizeof(bitmap));
memset(screen_ram, 0, sizeof(screen_ram));
memset(color_ram, 0, sizeof(color_ram));
memset(background, 0, sizeof(background));
// give "hints" to the converter
for (y = 0; y < 200; y++)
background[y] = Read_pixel_from_layer(0, 0, y);
for (y = 0; y < 25; y++)
{
for (x = 0; x < 40; x++)
color_ram[x + y*40] = Read_pixel_from_layer(1, x*4, y*8);
}
if (C64_pixels_to_FLI(bitmap, screen_ram, color_ram, background, Main.backups->Pages->Image[2].Pixels, Main.image_width, 1) > 0)
{
// put errors in layer 4 if not already done
if (Main.backups->Pages->Nb_layers < 4)
{
Add_layer(Main.backups, Main.backups->Pages->Nb_layers);
C64_pixels_to_FLI(bitmap, screen_ram, color_ram, background, Main.backups->Pages->Image[2].Pixels, Main.image_width, 1);
}
}
// copy background to layer 1
// and color RAM to layer 2
for (y = 0; y < 200; y++)
{
for (x = 0; x < 160; x++)
{
Pixel_in_layer(0, x, y, background[y]);
Pixel_in_layer(1, x, y, color_ram[(x >> 2) + (y >> 3)*40]);
}
}
}
break;
case IMAGE_MODE_HGR:
case IMAGE_MODE_DHGR:

View File

@ -3348,7 +3348,10 @@ int Save_C64_fli_monolayer(T_IO_Context *context, byte saveWhat, word loadAddr)
memset(color_ram, 0, sizeof(color_ram));
memset(background, 0, sizeof(background));
if (C64_pixels_to_FLI(bitmap, screen_ram, color_ram, background, context->Target_address, context->Pitch) > 0)
memset(color_ram, 0xff, 40*25); // no hint
memset(background, 0xff, 200);
if (C64_pixels_to_FLI(bitmap, screen_ram, color_ram, background, context->Target_address, context->Pitch, 0) > 0)
return 1;
file = Open_file_write(context);

View File

@ -38,6 +38,7 @@
#include "pages.h"
#include "windows.h"
#include "layers.h"
#include "graph.h"
// I don't have round() in MSVC++ 2010 (_MSC_VER=1600)
#if defined(_MSC_VER)
@ -399,7 +400,8 @@ int C64_FLI(T_IO_Context * context, byte *bitmap, byte *screen_ram, byte *color_
}
int C64_pixels_to_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background, const byte * pixels, long pitch)
int C64_pixels_to_FLI(byte *bitmap, byte *screen_ram, byte *color_ram,
byte *background, const byte * pixels, long pitch, int errmode)
{
int bx, by; // 4x8 block coordinates
int cx, cy; // coordinates inside block
@ -445,13 +447,22 @@ int C64_pixels_to_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *bac
if (n_possible_backgrounds == 0)
{
//ERROR
Warning_with_format("No possible background color for line %d.\n4x1 pixel blocks using 4 different colors must share at least one color.", by*8+cy);
return 1;
if (errmode == 0)
{
Warning_with_format("No possible background color for line %d.\n4x1 pixel blocks using 4 different colors must share at least one color.", by*8+cy);
return 1;
}
error_count++;
GFX2_Log(GFX2_INFO, "C64_pixels_to_FLI() no possible background for line %u. Default to #0.\n", by*8+cy);
// default to background color #0
if (background[by*8+cy] >= 16)
background[by*8+cy] = 0;
}
else
{
// pick the first one
background[by*8+cy] = count_trailing_zeros(background_possible[cy]);
// if the caller gave us a "hint", check it is "possible"
if (background[by*8+cy] >= 16 || (background_possible[cy] & (1 << background[by*8+cy])) == 0)
background[by*8+cy] = count_trailing_zeros(background_possible[cy]); // pick the first possible
#ifdef _DEBUG
if (background[by*8+cy] != 0)
GFX2_Log(GFX2_DEBUG, " y=%d background_possible=$%04x (count=%d) background color=#%d\n",
@ -488,10 +499,38 @@ int C64_pixels_to_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *bac
// choose the color RAM values (default to #0)
if (color_ram_possible[bx] == 0)
{
Warning_with_format("No possible color RAM value for 4x8 block (%d,%d) coordinates (%d,%d)\nThe 8 4x1 blocks must share a color.", bx, by, bx*4, by*8);
return 1;
if (errmode == 0)
{
Warning_with_format("No possible color RAM value for 4x8 block (%d,%d) coordinates (%d,%d)\nThe 8 4x1 blocks must share a color.", bx, by, bx*4, by*8);
return 1;
}
else
{
// Mark errors in Layer 4
for(cy = 0; cy < 8; cy++)
{
word colors_used = 0;
for(cx = 0; cx < 4; cx++)
{
pixel = pixels[bx*4+cx + pitch*(by*8+cy)];
if (pixel < 16 && pixel != background[by*8+cy])
colors_used |= 1 << pixel;
}
if (count_set_bits(colors_used) >= 3)
{
error_count++;
GFX2_Log(GFX2_INFO, "C64_pixels_to_FLI() too much colors in block at (%u to %u, %u)\n", bx*4, bx*4+3, by*7+cy);
for(cx = 0; cx < 4; cx++)
{
pixel = pixels[bx*4+cx + pitch*(by*8+cy)];
if (pixel < 16 && pixel != background[by*8+cy] && Main.backups->Pages->Nb_layers >= 4)
Pixel_in_layer(3, bx*4+cx, by*8+cy, 17);
}
}
}
}
}
else
else if (color_ram[by*40+bx] >= 16 || ((1 << color_ram[by*40+bx]) & color_ram_possible[bx]) == 0)
{
word possible = color_ram_possible[bx];
// avoid using same color as background

View File

@ -43,15 +43,22 @@ int C64_FLI(T_IO_Context * context, byte *bitmap, byte *screen_ram, byte *color_
/**
* Convert a (1 layer) picture to C64 FLI format
*
* Some "hints" can be put in background and color_ram.
* (a color value >= 16 means no hint).
*
* Errors can be either outputed to the user with Warning messages,
* or put in layer 4. The layer 4 has to be created before.
*
* @param bitmap a 8000 byte buffer to store bitmap data
* @param screen_ram a 8192 byte buffer to store the 8 screen RAMs
* @param color_ram a 1000 byte buffer to store the color RAM
* @param background a 200 byte buffer to store the background colors
* @param pixels source pixel buffer (at least 160x200)
* @param pitch bytes per line of the pixel buffer
* @param errmode error reporting mode 0 = report, 1 = mark in layer 4
* @return 0 the number of constraint errors
*/
int C64_pixels_to_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background, const byte * pixels, long pitch);
int C64_pixels_to_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background, const byte * pixels, long pitch, int errmode);
#if 0
/**