diff --git a/src/const.h b/src/const.h index a2109e02..487f0f75 100644 --- a/src/const.h +++ b/src/const.h @@ -147,7 +147,8 @@ enum FILE_FORMATS FORMAT_GPL, ///< Gimp palette FORMAT_SCR, ///< Amstrad CPC FORMAT_CM5, ///< Amstrad CPC Mode 5 - FORMAT_PPH, ///< Amastad CPC Perfect Pix + FORMAT_PPH, ///< Amstrad CPC Perfect Pix + FORMAT_GOS, ///< Amstrad Plus Graphos FORMAT_XPM, ///< X PixMap FORMAT_ICO, ///< Windows icons FORMAT_INFO, ///< Amiga OS icons diff --git a/src/fileformats.h b/src/fileformats.h index a31486aa..56926bfe 100644 --- a/src/fileformats.h +++ b/src/fileformats.h @@ -130,6 +130,10 @@ void Test_PPH(T_IO_Context *, FILE *); void Load_PPH(T_IO_Context *); void Save_PPH(T_IO_Context *); +// -- Graphos (Amstrad CPC) +void Test_GOS(T_IO_Context *, FILE *); +void Load_GOS(T_IO_Context *); + // -- XPM (X PixMap) // Loading is done through SDL_Image void Save_XPM(T_IO_Context*); diff --git a/src/loadsave.c b/src/loadsave.c index 5a0f366e..2228ddf7 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -118,10 +118,10 @@ const T_Format File_formats[] = { "pi1;pc1;pi2;pc2;pi3;pc3;neo;" "c64;p64;a64;pi;rp;aas;art;dd;iph;ipt;hpc;ocp;koa;koala;fli;bml;cdu;prg;pmg;rpm;" "gpx;" - "cpc;scr;win;" + "cpc;scr;win;pph,cm5;go1;" "hgr;dhgr;" "grb;grob;" - "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;ic2;cur;cm5;pph;info;flc;bin;map"}, + "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;ic2;cur;info;flc;bin;map"}, {FORMAT_ALL_PALETTES, "(pal)", NULL, NULL, NULL, 1, 0, 0, "", "kcf;pal;gpl"}, {FORMAT_ALL_FILES, "(*.*)", NULL, NULL, NULL, 0, 0, 0, "", "*"}, {FORMAT_GIF, " gif", Test_GIF, Load_GIF, Save_GIF, 0, 1, 1, "gif", "gif"}, @@ -149,6 +149,7 @@ const T_Format File_formats[] = { {FORMAT_SCR, " cpc", Test_SCR, Load_SCR, Save_SCR, 0, 0, 0, "scr", "cpc;scr;win"}, {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, NULL , 0, 0, 0, "go1", "go1"}, {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"}, diff --git a/src/miscfileformats.c b/src/miscfileformats.c index 372a5ceb..952975cd 100644 --- a/src/miscfileformats.c +++ b/src/miscfileformats.c @@ -4683,6 +4683,154 @@ void Save_SCR(T_IO_Context * context) free (output); } +/** + * Test for GO1/GO2/KIT - Amstrad Plus Graphos + * + * This format is made of 3 files + * .KIT hold the palette in "Kit4096" format. There are 16 colors each stored + * as 12 bit RGB in RB0G order. + * .GO1 and GO2 hold each half of the picture (top and bottom) + * The file always cover the whole display of the Plus (196*272 or so) + */ +void Test_GOS(T_IO_Context * context, FILE * file) +{ + FILE *file_oddeve; + unsigned long file_size; + file_size = File_length_file(file); + if (file_size != 16512) { + File_error = 1; + return; + } + + file_oddeve = Open_file_read_with_alternate_ext(context, "GO2"); + if (file_oddeve == NULL) { + File_error = 2; + return; + } + file_size = File_length_file(file_oddeve); + fclose(file_oddeve); + if (file_size != 16512) { + File_error = 3; + return; + } + + file_oddeve = Open_file_read_with_alternate_ext(context, "KIT"); + if (file_oddeve == NULL) { + File_error = 4; + return; + } + file_size = File_length_file(file_oddeve); + fclose(file_oddeve); + if (file_size != 160) { + File_error = 5; + return; + } + + File_error = 0; +} + + +void Load_GOS(T_IO_Context* context) +{ + FILE *file; + long file_size; + int i; + int x, y; + byte * pixel_data; + + if (!(file = Open_file_read(context))) + { + File_error = 1; + return; + } + + file_size=File_length_file(file); + + if (CPC_check_AMSDOS(file, NULL, NULL)) { + fseek(file, 128, SEEK_SET); // right after AMSDOS header + } + + context->Ratio = PIXEL_WIDE; + Pre_load(context, 192, 272, file_size, FORMAT_GOS, context->Ratio, 0); + context->Width = 192; + context->Height = 272; + + // load pixels + pixel_data = GFX2_malloc(16384); + memset(pixel_data, 0, 16384); + Read_bytes(file, pixel_data, file_size); + + i = 0; + for (y = 0; y < 168; y++) { + x = 0; + while (x < 192) { + byte pixels = pixel_data[i]; + Set_pixel(context, x++, y, (pixels & 0x80) >> 7 | (pixels & 0x08) >> 2 | (pixels & 0x20) >> 3 | (pixels & 0x02) << 2); + Set_pixel(context, x++, y, (pixels & 0x40) >> 6 | (pixels & 0x04) >> 1 | (pixels & 0x10) >> 2 | (pixels & 0x01) << 3); + i++; + } + + i += 0x800; + if (i > 0x3FFF) { + i -= 0x4000; + } else { + i -= 192 / 2; + } + } + + fclose(file); + + // load pixels from GO2 + file = Open_file_read_with_alternate_ext(context, "GO2"); + if (CPC_check_AMSDOS(file, NULL, NULL)) { + fseek(file, 128, SEEK_SET); // right after AMSDOS header + } + Read_bytes(file, pixel_data, file_size); + i = 0; + for (y = 168; y < 272; y++) { + x = 0; + while (x < 192) { + byte pixels = pixel_data[i]; + Set_pixel(context, x++, y, (pixels & 0x80) >> 7 | (pixels & 0x08) >> 2 | (pixels & 0x20) >> 3 | (pixels & 0x02) << 2); + Set_pixel(context, x++, y, (pixels & 0x40) >> 6 | (pixels & 0x04) >> 1 | (pixels & 0x10) >> 2 | (pixels & 0x01) << 3); + i++; + } + + i += 0x800; + if (i > 0x3FFF) { + i -= 0x4000; + } else { + i -= 192 / 2; + } + } + + fclose(file); + + file = Open_file_read_with_alternate_ext(context, "KIT"); + if (CPC_check_AMSDOS(file, NULL, NULL)) { + fseek(file, 128, SEEK_SET); // right after AMSDOS header + } + + if (Config.Clear_palette) + memset(context->Palette,0,sizeof(T_Palette)); + + for (i = 0; i < 16; i++) { + uint16_t word; + if (!Read_word_be(file, &word)) { + fclose(file); + File_error = 2; + return; + } + + context->Palette[i].R = ((word >> 8) & 0xF) * 0x11; + context->Palette[i].G = ((word >> 0) & 0xF) * 0x11; + context->Palette[i].B = ((word >> 12) & 0xF) * 0x11; + } + + fclose(file); + File_error = 0; +} + /** * Test for CM5 - Amstrad CPC "Mode 5" picture *