From 4d57ba39bbf54514e392eb8982ec68aa9192f2e5 Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Fri, 27 Dec 2019 02:29:02 +0100 Subject: [PATCH] Loading of MSX Mode 2 pictures 256x192 --- src/Makefile | 4 +- src/const.h | 1 + src/fileformats.h | 4 + src/loadsave.c | 2 + src/msxformats.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 src/msxformats.c diff --git a/src/Makefile b/src/Makefile index 936e0ef8..897c1aea 100644 --- a/src/Makefile +++ b/src/Makefile @@ -810,7 +810,7 @@ OBJS = main.o init.o graph.o $(APIOBJ) misc.o special.o \ transform.o pversion.o factory.o $(PLATFORMOBJ) \ loadsave.o loadsavefuncs.o \ pngformat.o motoformats.o stformats.o c64formats.o cpcformats.o \ - ifformat.o \ + ifformat.o msxformats.o \ fileformats.o miscfileformats.o libraw2crtc.o \ brush_ops.o buttons_effects.o layers.o \ oldies.o tiles.o colorred.o unicode.o gfx2surface.o \ @@ -823,7 +823,7 @@ TESTSOBJS = $(patsubst %.c,%.o,$(wildcard tests/*.c)) \ miscfileformats.o fileformats.o oldies.o libraw2crtc.o \ loadsavefuncs.o packbits.o tifformat.o c64load.o 6502.o \ pngformat.o motoformats.o stformats.o c64formats.o cpcformats.o \ - ifformat.o \ + ifformat.o msxformats.o \ op_c.o colorred.o \ unicode.o \ io.o realpath.o version.o pversion.o \ diff --git a/src/const.h b/src/const.h index 16b0674c..6a1ab366 100644 --- a/src/const.h +++ b/src/const.h @@ -159,6 +159,7 @@ enum FILE_FORMATS FORMAT_HGR, ///< Apple II HGR and DHGR FORMAT_TIFF, ///< Tagged Image File Format FORMAT_GRB, ///< HP-48 Grob + FORMAT_MSX, ///< MSX formats FORMAT_MISC, ///< Must be last of enum: others formats recognized by SDL_image (or recoil) FORMAT_CLIPBOARD ///< To load/save from/to Clipboard }; diff --git a/src/fileformats.h b/src/fileformats.h index b1507074..6f9f0e2a 100644 --- a/src/fileformats.h +++ b/src/fileformats.h @@ -192,5 +192,9 @@ void Save_TIFF_to_memory(T_IO_Context *, void * *, unsigned long *); void Test_GRB(T_IO_Context *, FILE *); void Load_GRB(T_IO_Context *); +// -- MSX ------------------------------------------------------------------- +void Test_MSX(T_IO_Context *, FILE *); +void Load_MSX(T_IO_Context *); + /// @} #endif diff --git a/src/loadsave.c b/src/loadsave.c index 5b7d5bf3..6cfd772f 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -121,6 +121,7 @@ const T_Format File_formats[] = { "cpc;scr;win;pph;cm5;go1;" "hgr;dhgr;" "grb;grob;" + "sc2;" "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, "", "*"}, @@ -157,6 +158,7 @@ const T_Format File_formats[] = { {FORMAT_INFO," info",Test_INFO,Load_INFO,NULL, 0, 0, 0, "info", "info"}, {FORMAT_FLI, " flc", Test_FLI, Load_FLI, NULL, 0, 0, 0, "flc", "flc;fli;dat"}, {FORMAT_MOTO," moto",Test_MOTO,Load_MOTO,Save_MOTO,0, 1, 0, "bin", "bin;map"}, + {FORMAT_MSX, " msx", Test_MSX, Load_MSX, NULL, 0, 0, 0, "sc2", "sc2"}, {FORMAT_HGR, " hgr", Test_HGR, Load_HGR, Save_HGR, 0, 0, 1, "hgr", "hgr;dhgr;bin"}, #ifndef __no_tifflib__ {FORMAT_TIFF," tiff",Test_TIFF,Load_TIFF,Save_TIFF,0, 1, 1, "tif", "tif;tiff"}, diff --git a/src/msxformats.c b/src/msxformats.c new file mode 100644 index 00000000..67cf6905 --- /dev/null +++ b/src/msxformats.c @@ -0,0 +1,190 @@ +/* vim:expandtab:ts=2 sw=2: +*/ +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2018-2019 Thomas Bernard + Copyright 2011 Pawel Góralski + Copyright 2009 Petter Lindquist + Copyright 2008 Yves Rizoud + Copyright 2008 Franck Charlet + Copyright 2007-2011 Adrien Destugues + Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) + + Grafx2 is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 + of the License. + + Grafx2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grafx2; if not, see +*/ + +///@file msxformats.c +/// Formats for the MSX machines + +#include +#include +#include "fileformats.h" +#include "loadsavefuncs.h" +#include "io.h" +#include "misc.h" +#include "gfx2log.h" +#include "gfx2mem.h" + +/** + * @defgroup msx MSX picture formats + * @ingroup loadsaveformats + * + * MODE2 : 256x192 + * Support for the MSX pictures + * - SC2 "BSAVE" files + * + * @{ + */ + +/** + * Check if the file is in the MSX BSAVE format. Reads 7 bytes. + * + * @param file + * @param begin load address + * @param end end address + * @param exec execution address for BLOAD ,R + * @return 0 if the file is not in BSAVE format + */ +static int Check_MSX_BSAVE_format(FILE * file, word * begin, word * end, word * exec) +{ + byte type; + word b, e, r; + if (!Read_byte(file, &type) || !Read_word_le(file, &b) || !Read_word_le(file, &e) || !Read_word_le(file, &r)) + return 0; + if (type != 0xfe) + return 0; + if (b > e) + return 0; + if (begin != NULL) + *begin = b; + if (end != NULL) + *end = e; + if (exec != NULL) + *exec = r; + return 1; +} + +void Test_MSX(T_IO_Context * context, FILE * file) +{ + word begin, end, exec; + (void)context; + if (Check_MSX_BSAVE_format(file, &begin, &end, &exec)) + { + GFX2_Log(GFX2_DEBUG, "MSX : &H%04X-&H%04X,&H%04X\n", begin, end, exec); + if (begin < 0x4000 && end <= 0x4000) + File_error = 0; + } +} + +/** + * Load a MSX Screen 2 picture + * + * TMS9918 Mode II VRAM layout : + * - 0000-17FF : Pattern table + * - 1800-1AFF : Name table + * - 1B00-1B7F : Sprite attributes + * - 1B80-1FFF : UNUSED (1B80-1BAF = Palette) + * - 2000-37FF : Color table + * - 3800-3FFF : Sprite patterns + */ +void Load_MSX(T_IO_Context * context) +{ + unsigned long file_size; + FILE * file; + word begin, end, exec; + byte vram[16*1024]; + int row, col, sprite; + word addr; + + File_error = 1; + file = Open_file_read(context); + if (!Check_MSX_BSAVE_format(file, &begin, &end, &exec)) + { + fclose(file); + return; + } + if (begin >= 0x4000 || end > 0x4000) + { + fclose(file); + return; + } + memset(vram, 0, sizeof(vram)); + if (!Read_bytes(file, vram + begin, end - begin)) + { + fclose(file); + return; + } + file_size = File_length_file(file); + fclose(file); + + File_error = 0; + // TODO: load MSX palette + context->Transparent_color = 0; // Set color 0 as transparent + Pre_load(context, 256, 192, file_size, FORMAT_MSX, PIXEL_SIMPLE, 4); + for (row = 0; row < 24; row++) + { + for (col = 0; col < 32; col++) + { + int x, y; + byte pattern = vram[0x1800 + row*32 + col]; + addr = ((row & 0x18) << 8) + (pattern << 3); + for (y = 0; y < 8; y++, addr++) + { + byte bits = vram[addr]; + byte colors = vram[0x2000 + addr]; + for (x = 0; x < 8; x++) + { + Set_pixel(context, (col << 3) + x, (row << 3) + y, bits & 0x80 ? colors >> 4 : colors & 0x0f); + bits <<= 1; + } + } + } + } + if (end <= 0x3800) + return; // no sprites + // load sprites + Set_loading_layer(context, 1); + for (sprite = 0; sprite < 32; sprite++) + { + int x_pos, y_pos, x, y; + byte pattern; + byte color; + + y_pos = vram[0x1B00 + sprite * 4]; + x_pos = vram[0x1B00 + sprite * 4 + 1]; + pattern = vram[0x1B00 + sprite * 4 + 2]; + color = vram[0x1B00 + sprite * 4 + 3]; + GFX2_Log(GFX2_DEBUG, "Sprite #%02d (%d,%d) %02X %02X\n", sprite, x_pos, y_pos, pattern, color); + if (y_pos == 208) + break; + y_pos = (y_pos + 1) & 0xff; + if (color & 0x80) + x_pos -= 32; + color &= 0x0f; + addr = 0x3800 + (pattern << 3); + // 16x16 pixels sprites + for (y = 0; y < 16; y++, addr++) + { + word bits = (vram[addr] << 8) | vram[addr+16]; + for (x = 0; x < 16; x++) + { + if (bits & 0x8000) + Set_pixel(context, x_pos + x, y_pos + y, color); + bits <<= 1; + } + } + } +} + +/* @} */