Support for saving SymbOS .SGX graphics files
This commit is contained in:
		
							parent
							
								
									713fd9ff71
								
							
						
					
					
						commit
						9ed89cc860
					
				
							
								
								
									
										125
									
								
								src/cpcformats.c
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								src/cpcformats.c
									
									
									
									
									
								
							@ -30,9 +30,14 @@
 | 
			
		||||
#include "loadsavefuncs.h"
 | 
			
		||||
#include "libraw2crtc.h"
 | 
			
		||||
#include "oldies.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "gfx2mem.h"
 | 
			
		||||
#include "gfx2log.h"
 | 
			
		||||
 | 
			
		||||
#ifndef MIN
 | 
			
		||||
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef MAX
 | 
			
		||||
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
 | 
			
		||||
#endif
 | 
			
		||||
@ -275,6 +280,126 @@ void Load_SGX(T_IO_Context * context)
 | 
			
		||||
  fclose(data.file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Write SGX file format as specified here :
 | 
			
		||||
 * http://www.cpcwiki.eu/index.php/Format:SGX_(SymbOS_graphic_files)
 | 
			
		||||
 *
 | 
			
		||||
 * We are using only simple chunks for 4 colors pictures.
 | 
			
		||||
 * Chunk dimentions are limited to the ones of simple chunks (252x255),
 | 
			
		||||
 * we could go up to 508x65535 with extended chunks.
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 for error
 | 
			
		||||
 */
 | 
			
		||||
static int Save_SGX_Sub(T_IO_Context * context, FILE * file, word n_colors)
 | 
			
		||||
{
 | 
			
		||||
  word posy = 0;
 | 
			
		||||
 | 
			
		||||
  while (posy < context->Height)
 | 
			
		||||
  {
 | 
			
		||||
    word posx = 0;
 | 
			
		||||
    word height = MIN(context->Height - posy, 255);
 | 
			
		||||
    if (posy != 0)
 | 
			
		||||
    {
 | 
			
		||||
      // Write Line Feed
 | 
			
		||||
      if (!Write_byte(file, 255)
 | 
			
		||||
          || !Write_byte(file, 255) || !Write_byte(file, 255))
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    while (posx < context->Width)
 | 
			
		||||
    {
 | 
			
		||||
      word width = MIN(context->Width - posx, 252);
 | 
			
		||||
      GFX2_Log(GFX2_DEBUG, "Save_SGX : (%hu,%hu) %hux%hu %huc\n",
 | 
			
		||||
               posx, posy, width, height, n_colors);
 | 
			
		||||
      if (n_colors == 4)
 | 
			
		||||
      {
 | 
			
		||||
        word y;
 | 
			
		||||
        byte byte_width = (width + 3) >> 2;
 | 
			
		||||
        if (!Write_byte(file, byte_width)
 | 
			
		||||
            || !Write_byte(file, (byte)width) || !Write_byte(file, (byte)height))
 | 
			
		||||
          return 0;
 | 
			
		||||
        for (y = 0; y < height; y++)
 | 
			
		||||
        {
 | 
			
		||||
          byte i;
 | 
			
		||||
          word x;
 | 
			
		||||
          for (i = 0, x = 0; i < byte_width; i++)
 | 
			
		||||
          {
 | 
			
		||||
            byte b = 0;
 | 
			
		||||
            do
 | 
			
		||||
            {
 | 
			
		||||
              byte c = Get_pixel(context, posx + x++, posy + y);
 | 
			
		||||
              b <<= 1;
 | 
			
		||||
              b |= (c & 1) << 4;
 | 
			
		||||
              b |= (c & 2) >> 1;
 | 
			
		||||
            } while (x & 3);
 | 
			
		||||
            if (!Write_byte(file, b))
 | 
			
		||||
              return 0;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        word y;
 | 
			
		||||
        word byte_width = (width + 1) >> 1;
 | 
			
		||||
        if (!Write_byte(file, 64) || !Write_byte(file, 5)
 | 
			
		||||
            || !Write_word_le(file, byte_width) || !Write_word_le(file, width) || !Write_word_le(file, height))
 | 
			
		||||
          return 0;
 | 
			
		||||
        for (y = 0; y < height; y++)
 | 
			
		||||
        {
 | 
			
		||||
          word i, x;
 | 
			
		||||
          for (i = 0, x = 0; i < byte_width; i++)
 | 
			
		||||
          {
 | 
			
		||||
            byte b = Get_pixel(context, posx + x++, posy + y) << 4;
 | 
			
		||||
            b |= Get_pixel(context, posx + x++, posy + y) & 0x0f;
 | 
			
		||||
            if (!Write_byte(file, b))
 | 
			
		||||
              return 0;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      posx += width;
 | 
			
		||||
    }
 | 
			
		||||
    posy += height;
 | 
			
		||||
  }
 | 
			
		||||
  // Write EOF marker
 | 
			
		||||
  for (posy = 0; posy < 3; posy++)
 | 
			
		||||
    Write_byte(file, 0);
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Save_SGX(T_IO_Context * context)
 | 
			
		||||
{
 | 
			
		||||
  FILE * file;
 | 
			
		||||
  dword color_usage[256];
 | 
			
		||||
  word n_colors;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  File_error =  1;
 | 
			
		||||
  n_colors = Count_used_colors(color_usage);
 | 
			
		||||
  for (i = 16; i < 256; i++)
 | 
			
		||||
  {
 | 
			
		||||
    if (color_usage[i] != 0)
 | 
			
		||||
    {
 | 
			
		||||
      Warning_message("SGX format is limited to 16 colors");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // 4 colors mode if sufficient, otherwise 16 colors
 | 
			
		||||
  n_colors = 4;
 | 
			
		||||
  for (i = 4; i < 16; i++)
 | 
			
		||||
  {
 | 
			
		||||
    if (color_usage[i] != 0)
 | 
			
		||||
    {
 | 
			
		||||
      n_colors = 16;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  file = Open_file_write(context);
 | 
			
		||||
  if (file == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
  if (Save_SGX_Sub(context, file, n_colors))
 | 
			
		||||
    File_error = 0;
 | 
			
		||||
  fclose(file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test for SCR file (Amstrad CPC)
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
@ -151,6 +151,7 @@ void Save_GOS(T_IO_Context *);
 | 
			
		||||
// -- SGX (SymbOS)
 | 
			
		||||
void Test_SGX(T_IO_Context *, FILE *);
 | 
			
		||||
void Load_SGX(T_IO_Context *);
 | 
			
		||||
void Save_SGX(T_IO_Context *);
 | 
			
		||||
 | 
			
		||||
// -- XPM (X PixMap)
 | 
			
		||||
// Loading is done through SDL_Image
 | 
			
		||||
 | 
			
		||||
@ -148,7 +148,7 @@ const T_Format File_formats[] = {
 | 
			
		||||
  {FORMAT_CM5, " cm5", Test_CM5, Load_CM5, Save_CM5, 0, 0, 1, "cm5", "cm5"},
 | 
			
		||||
  {FORMAT_PPH, " pph", Test_PPH, Load_PPH, Save_PPH, 0, 0, 1, "pph", "pph"},
 | 
			
		||||
  {FORMAT_GOS, " go1", Test_GOS, Load_GOS, Save_GOS, 0, 0, 0, "go1", "go1"},
 | 
			
		||||
  {FORMAT_SGX, " sgx", Test_SGX, Load_SGX, NULL,     0, 0, 1, "sgx", "sgx"},
 | 
			
		||||
  {FORMAT_SGX, " sgx", Test_SGX, Load_SGX, Save_SGX, 0, 0, 1, "sgx", "sgx"},
 | 
			
		||||
  {FORMAT_XPM, " xpm", NULL,     NULL,     Save_XPM, 0, 0, 0, "xpm", "xpm"},
 | 
			
		||||
  {FORMAT_ICO, " ico", Test_ICO, Load_ICO, Save_ICO, 0, 0, 0, "ico", "ico;ic2;cur"},
 | 
			
		||||
  {FORMAT_INFO," info",Test_INFO,Load_INFO,NULL,     0, 0, 0, "info", "info"},
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user