Compressed internal layouts [David Haywood]

This commit is contained in:
Miodrag Milanovic 2016-03-30 20:38:44 +02:00
parent c95d9c0ec3
commit 9353a1ccb3
14 changed files with 185 additions and 59 deletions

View File

@ -1436,9 +1436,9 @@ $(GENDIR)/includes/SDL2:
-$(call MKDIR,$@)
-$(call COPY,3rdparty/SDL2/include/,$(GENDIR)/includes/SDL2)
$(GENDIR)/%.lh: $(SRC)/%.lay scripts/build/file2str.py | $(GEN_FOLDERS)
@echo Converting $<...
$(SILENT)$(PYTHON) scripts/build/file2str.py $< $@ layout_$(basename $(notdir $<))
$(GENDIR)/%.lh: $(SRC)/%.lay scripts/build/complay.py | $(GEN_FOLDERS)
@echo Compressing $<...
$(SILENT)$(PYTHON) scripts/build/complay.py $< $@ layout_$(basename $(notdir $<))
$(SRC)/devices/cpu/m68000/m68kops.cpp: $(SRC)/devices/cpu/m68000/m68k_in.cpp $(SRC)/devices/cpu/m68000/m68kmake.cpp
ifeq ($(TARGETOS),asmjs)

71
scripts/build/complay.py Normal file
View File

@ -0,0 +1,71 @@
#!/usr/bin/python
##
## license:BSD-3-Clause
## copyright-holders:Aaron Giles, Andrew Gardner
from __future__ import with_statement
import sys
import os
import zlib
if len(sys.argv) < 4:
print('Usage:')
print(' complay <source.lay> <output.h> <varname>')
print('')
sys.exit(0)
srcfile = sys.argv[1]
dstfile = sys.argv[2]
varname = sys.argv[3]
type = 'UINT8'
try:
myfile = open(srcfile, 'rb')
except IOError:
sys.stderr.write("Unable to open source file '%s'\n" % srcfile)
sys.exit(-1)
byteCount = os.path.getsize(srcfile)
compsize = 0
compressiontype = 1
try:
dst = open(dstfile,'w')
dst.write('const %s %s_data[] =\n{\n\t' % ( type, varname))
offs = 0
with open(srcfile, "rb") as src:
while True:
chunk = src.read(byteCount)
if chunk:
compchunk = zlib.compress(chunk, 9)
compsize = len(compchunk)
for b in compchunk:
# For Python 2.x compatibility.
b = ord(b)
dst.write('%d' % b)
offs += 1
if offs != compsize:
dst.write(',')
else:
break
dst.write('\n\t')
dst.write('\n};\n')
except IOError:
sys.stderr.write("Unable to open output file '%s'\n" % dstfile)
sys.exit(-1)
try:
dst.write('extern const internal_layout %s;\n' % ( varname ))
dst.write('const internal_layout %s = { \n\t' % ( varname ))
dst.write('%d,%d,%d,%s_data\n' % ( byteCount, compsize, compressiontype, varname ))
dst.write('\n};\n')
dst.close()
except IOError:
sys.stderr.write("Unable to open output file '%s'\n" % dstfile)
sys.exit(-1)

View File

@ -53,7 +53,7 @@ end
function layoutbuildtask(_folder, _name)
return { MAME_DIR .. "src/".._folder.."/".. _name ..".lay" , GEN_DIR .. _folder .. "/".._name..".lh",
{ MAME_DIR .. "scripts/build/file2str.py" }, {"@echo Converting src/".._folder.."/".._name..".lay...", PYTHON .. " $(1) $(<) $(@) layout_".._name }};
{ MAME_DIR .. "scripts/build/complay.py" }, {"@echo Compressing src/".._folder.."/".._name..".lay...", PYTHON .. " $(1) $(<) $(@) layout_".._name }};
end
function precompiledheaders()

View File

@ -74,7 +74,7 @@ struct game_driver
const rom_entry * rom; // pointer to list of ROMs for the game
const char * compatible_with;
UINT32 flags; // orientation and other flags; see defines below
const char * default_layout; // default internally defined layout
const internal_layout * default_layout; // default internally defined layout
};
@ -95,7 +95,22 @@ struct game_driver
// standard GAME() macro
#define GAME(YEAR,NAME,PARENT,MACHINE,INPUT,CLASS,INIT,MONITOR,COMPANY,FULLNAME,FLAGS) \
GAMEL(YEAR,NAME,PARENT,MACHINE,INPUT,CLASS,INIT,MONITOR,COMPANY,FULLNAME,FLAGS,((const char *)0))
extern const game_driver GAME_NAME(NAME) = \
{ \
__FILE__, \
#PARENT, \
#NAME, \
FULLNAME, \
#YEAR, \
COMPANY, \
MACHINE_CONFIG_NAME(MACHINE), \
INPUT_PORTS_NAME(INPUT), \
&driver_device::driver_init_wrapper<CLASS, &CLASS::init_##INIT>, \
ROM_NAME(NAME), \
nullptr, \
(MONITOR)|(FLAGS)|MACHINE_TYPE_ARCADE, \
nullptr \
};
// standard macro with additional layout
#define GAMEL(YEAR,NAME,PARENT,MACHINE,INPUT,CLASS,INIT,MONITOR,COMPANY,FULLNAME,FLAGS,LAYOUT) \
@ -111,9 +126,9 @@ extern const game_driver GAME_NAME(NAME) = \
INPUT_PORTS_NAME(INPUT), \
&driver_device::driver_init_wrapper<CLASS, &CLASS::init_##INIT>, \
ROM_NAME(NAME), \
NULL, \
nullptr, \
(MONITOR)|(FLAGS)|MACHINE_TYPE_ARCADE, \
&LAYOUT[0] \
&LAYOUT \
};
// standard console definition macro
@ -132,7 +147,7 @@ extern const game_driver GAME_NAME(NAME) = \
ROM_NAME(NAME), \
#COMPAT, \
ROT0|(FLAGS)|MACHINE_TYPE_CONSOLE, \
NULL \
nullptr \
};
// standard computer definition macro
@ -151,7 +166,7 @@ extern const game_driver GAME_NAME(NAME) = \
ROM_NAME(NAME), \
#COMPAT, \
ROT0|(FLAGS)|MACHINE_TYPE_COMPUTER, \
NULL \
nullptr \
};
// standard system definition macro
@ -170,7 +185,7 @@ extern const game_driver GAME_NAME(NAME) = \
ROM_NAME(NAME), \
#COMPAT, \
ROT0|(FLAGS)|MACHINE_TYPE_OTHER, \
NULL \
nullptr \
};

View File

@ -36,6 +36,15 @@ struct gfx_decode_entry;
class driver_device;
class screen_device;
struct internal_layout
{
size_t decompressed_size;
size_t compressed_size;
UINT8 compression_type;
const UINT8* data;
};
// ======================> machine_config
// machine configuration definition
@ -66,7 +75,7 @@ public:
bool m_force_no_drc; // whether or not to force DRC off
// other parameters
const char * m_default_layout; // default layout for this machine
const internal_layout * m_default_layout; // default layout for this machine
// helpers during configuration; not for general use
device_t *device_add(device_t *owner, const char *tag, device_type type, UINT32 clock);
@ -201,7 +210,7 @@ References an external machine config.
// core video parameters
#define MCFG_DEFAULT_LAYOUT(_layout) \
config.m_default_layout = &(_layout)[0];
config.m_default_layout = &(_layout);
// add/remove devices
#define MCFG_DEVICE_ADD(_tag, _type, _clock) \

View File

@ -46,6 +46,7 @@
#include "drivenum.h"
#include "xmlfile.h"
#include "ui/ui.h"
#include <zlib.h>
@ -906,7 +907,7 @@ render_container::user_settings::user_settings()
// render_target - constructor
//-------------------------------------------------
render_target::render_target(render_manager &manager, const char *layoutfile, UINT32 flags)
render_target::render_target(render_manager &manager, const internal_layout *layoutfile, UINT32 flags)
: m_next(nullptr),
m_manager(manager),
m_curview(nullptr),
@ -1548,7 +1549,7 @@ void render_target::update_layer_config()
// given render target
//-------------------------------------------------
void render_target::load_layout_files(const char *layoutfile, bool singlefile)
void render_target::load_layout_files(const internal_layout *layoutfile, bool singlefile)
{
bool have_default = false;
// if there's an explicit file, load that first
@ -1587,34 +1588,34 @@ void render_target::load_layout_files(const char *layoutfile, bool singlefile)
if (screens == 1)
{
if (system.flags & ORIENTATION_SWAP_XY)
load_layout_file(nullptr, layout_vertical);
load_layout_file(nullptr, &layout_vertical);
else
load_layout_file(nullptr, layout_horizont);
load_layout_file(nullptr, &layout_horizont);
assert_always(m_filelist.count() > 0, "Couldn't parse default layout??");
}
if (!have_default)
{
if (screens == 0)
{
load_layout_file(nullptr, layout_noscreens);
load_layout_file(nullptr, &layout_noscreens);
assert_always(m_filelist.count() > 0, "Couldn't parse default layout??");
}
else
if (screens == 2)
{
load_layout_file(nullptr, layout_dualhsxs);
load_layout_file(nullptr, &layout_dualhsxs);
assert_always(m_filelist.count() > 0, "Couldn't parse default layout??");
}
else
if (screens == 3)
{
load_layout_file(nullptr, layout_triphsxs);
load_layout_file(nullptr, &layout_triphsxs);
assert_always(m_filelist.count() > 0, "Couldn't parse default layout??");
}
else
if (screens == 4)
{
load_layout_file(nullptr, layout_quadhsxs);
load_layout_file(nullptr, &layout_quadhsxs);
assert_always(m_filelist.count() > 0, "Couldn't parse default layout??");
}
}
@ -1626,6 +1627,55 @@ void render_target::load_layout_files(const char *layoutfile, bool singlefile)
// and append it to our list
//-------------------------------------------------
bool render_target::load_layout_file(const char *dirname, const internal_layout *layout_data)
{
// +1 to ensure data is terminated for XML parser
auto tempout = make_unique_clear<UINT8[]>(layout_data->decompressed_size+1);
z_stream stream;
int zerr;
/* initialize the stream */
memset(&stream, 0, sizeof(stream));
stream.next_out = tempout.get();
stream.avail_out = layout_data->decompressed_size;
zerr = inflateInit(&stream);
if (zerr != Z_OK)
{
fatalerror("could not inflateInit");
return false;
}
/* decompress this chunk */
stream.next_in = (unsigned char*)layout_data->data;
stream.avail_in = layout_data->compressed_size;
zerr = inflate(&stream, Z_NO_FLUSH);
/* stop at the end of the stream */
if (zerr == Z_STREAM_END)
{
// OK
}
else if (zerr != Z_OK)
{
fatalerror("decompression error\n");
return false;
}
/* clean up */
zerr = inflateEnd(&stream);
if (zerr != Z_OK)
{
fatalerror("inflateEnd error\n");
return false;
}
return load_layout_file(dirname, (const char*)tempout.get());
}
bool render_target::load_layout_file(const char *dirname, const char *filename)
{
// if the first character of the "file" is an open brace, assume it is an XML string
@ -2529,7 +2579,7 @@ float render_manager::max_update_rate() const
// target_alloc - allocate a new target
//-------------------------------------------------
render_target *render_manager::target_alloc(const char *layoutfile, UINT32 flags)
render_target *render_manager::target_alloc(const internal_layout *layoutfile, UINT32 flags)
{
return &m_targetlist.append(*global_alloc(render_target(*this, layoutfile, flags)));
}

View File

@ -888,7 +888,7 @@ class render_target
friend class render_manager;
// construction/destruction
render_target(render_manager &manager, const char *layoutfile = nullptr, UINT32 flags = 0);
render_target(render_manager &manager, const internal_layout *layoutfile = nullptr, UINT32 flags = 0);
~render_target();
public:
@ -966,8 +966,9 @@ public:
private:
// internal helpers
void update_layer_config();
void load_layout_files(const char *layoutfile, bool singlefile);
void load_layout_files(const internal_layout *layoutfile, bool singlefile);
bool load_layout_file(const char *dirname, const char *filename);
bool load_layout_file(const char *dirname, const internal_layout *layout_data);
void add_container_primitives(render_primitive_list &list, const object_transform &xform, render_container &container, int blendmode);
void add_element_primitives(render_primitive_list &list, const object_transform &xform, layout_element &element, int state, int blendmode);
bool map_point_internal(INT32 target_x, INT32 target_y, render_container *container, float &mapped_x, float &mapped_y, ioport_port *&mapped_input_port, ioport_value &mapped_input_mask);
@ -1044,7 +1045,7 @@ public:
float max_update_rate() const;
// targets
render_target *target_alloc(const char *layoutfile = nullptr, UINT32 flags = 0);
render_target *target_alloc(const internal_layout *layoutfile = nullptr, UINT32 flags = 0);
void target_free(render_target *target);
render_target *first_target() const { return m_targetlist.first(); }
render_target *target_by_index(int index) const;

View File

@ -16,26 +16,26 @@
//**************************************************************************
// no screens layouts
extern const char layout_noscreens[]; // for screenless systems
extern const internal_layout layout_noscreens; // for screenless systems
// single screen layouts
extern const char layout_horizont[]; // horizontal 4:3 screens
extern const char layout_vertical[]; // vertical 4:3 screens
extern const internal_layout layout_horizont; // horizontal 4:3 screens
extern const internal_layout layout_vertical; // vertical 4:3 screens
// dual screen layouts
extern const char layout_dualhsxs[]; // dual 4:3 screens side-by-side
extern const char layout_dualhovu[]; // dual 4:3 screens above and below
extern const char layout_dualhuov[]; // dual 4:3 screens below and above
extern const internal_layout layout_dualhsxs; // dual 4:3 screens side-by-side
extern const internal_layout layout_dualhovu; // dual 4:3 screens above and below
extern const internal_layout layout_dualhuov; // dual 4:3 screens below and above
// triple screen layouts
extern const char layout_triphsxs[]; // triple 4:3 screens side-by-side
extern const internal_layout layout_triphsxs; // triple 4:3 screens side-by-side
// quad screen layouts
extern const char layout_quadhsxs[]; // quad 4:3 screens side-by-side
extern const internal_layout layout_quadhsxs; // quad 4:3 screens side-by-side
// LCD screen layouts
extern const char layout_lcd[]; // generic 1:1 lcd screen layout
extern const char layout_lcd_rot[]; // same, for use with ROT90 or ROT270
extern const internal_layout layout_lcd; // generic 1:1 lcd screen layout
extern const internal_layout layout_lcd_rot; // same, for use with ROT90 or ROT270
#endif // __RENDLAY_H__

View File

@ -130,7 +130,7 @@ video_manager::video_manager(running_machine &machine)
// the native target is hard-coded to our internal layout and has all options disabled
if (m_snap_native)
{
m_snap_target = machine.render().target_alloc(layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN);
m_snap_target = machine.render().target_alloc(&layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN);
m_snap_target->set_backdrops_enabled(false);
m_snap_target->set_overlays_enabled(false);
m_snap_target->set_bezels_enabled(false);

View File

@ -1251,16 +1251,6 @@ ADDRESS_MAP_END
/*************************** layout ********************************/
static const char layout_hp48gx[] = "hp48gx";
static const char layout_hp48g [] = "hp48g";
static const char layout_hp48gp[] = "hp48gp";
static const char layout_hp48sx[] = "hp48sx";
static const char layout_hp48s [] = "hp48s";
static const char layout_hp49g [] = "hp49g";
/*************************** driver ********************************/
@ -1297,7 +1287,6 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( hp48gx, hp48_common )
MCFG_MACHINE_START_OVERRIDE (hp48_state, hp48gx )
MCFG_DEFAULT_LAYOUT ( layout_hp48gx )
/* expansion ports */
MCFG_HP48_PORT_ADD ( "port1", 0, HP48_CE2, 128*1024 )
@ -1310,7 +1299,6 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( hp48g, hp48_common )
MCFG_MACHINE_START_OVERRIDE (hp48_state, hp48g )
MCFG_DEFAULT_LAYOUT ( layout_hp48g )
/* serial I/O */
//MCFG_XMODEM_ADD( "rs232_x", hp48_xmodem_rs232_conf )
@ -1320,7 +1308,6 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( hp48gp, hp48_common )
MCFG_MACHINE_START_OVERRIDE (hp48_state, hp48gp )
MCFG_DEFAULT_LAYOUT ( layout_hp48gp )
/* serial I/O */
//MCFG_XMODEM_ADD( "rs232_x", hp48_xmodem_rs232_conf )
@ -1332,7 +1319,6 @@ static MACHINE_CONFIG_DERIVED( hp48sx, hp48_common )
MCFG_CPU_MODIFY ( "maincpu" )
MCFG_CPU_CLOCK ( 2000000 )
MCFG_MACHINE_START_OVERRIDE (hp48_state, hp48sx )
MCFG_DEFAULT_LAYOUT ( layout_hp48sx )
/* expansion ports */
MCFG_HP48_PORT_ADD ( "port1", 0, HP48_CE1, 128*1024)
@ -1346,7 +1332,6 @@ static MACHINE_CONFIG_DERIVED( hp48s, hp48_common )
MCFG_CPU_MODIFY ( "maincpu" )
MCFG_CPU_CLOCK ( 2000000 )
MCFG_MACHINE_START_OVERRIDE (hp48_state, hp48s )
MCFG_DEFAULT_LAYOUT ( layout_hp48s )
/* serial I/O */
//MCFG_KERMIT_ADD( "rs232_k", hp48_kermit_rs232_conf )
@ -1355,7 +1340,6 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( hp49g, hp48_common )
MCFG_CPU_MODIFY ( "maincpu" )
MCFG_MACHINE_START_OVERRIDE (hp48_state, hp49g )
MCFG_DEFAULT_LAYOUT ( layout_hp49g )
/* serial I/O */
//MCFG_XMODEM_ADD( "rs232_x", hp48_xmodem_rs232_conf )

View File

@ -322,7 +322,7 @@ rumbling on a subwoofer in the cabinet.)
#include "includes/taitoipt.h"
#include "includes/ninjaw.h"
extern const char layout_darius[];
extern const internal_layout layout_darius;
void ninjaw_state::parse_control( ) /* assumes Z80 sandwiched between 68Ks */
{

View File

@ -100,7 +100,7 @@ protected:
};
extern const char layout_dlair[];
extern const internal_layout layout_dlair;

View File

@ -85,9 +85,6 @@
/**************************** common *******************************/
/* layout */
static const char layout_thomson[] = "thomson";
#define KEY(pos,name,key) \
PORT_BIT ( 1<<(pos), IP_ACTIVE_LOW, IPT_KEYBOARD ) \
PORT_NAME ( name ) \
@ -630,7 +627,6 @@ static MACHINE_CONFIG_START( to7, thomson_state )
MCFG_PALETTE_ADD ( "palette", 4097 ) /* 12-bit color + transparency */
MCFG_PALETTE_INIT_OWNER(thomson_state, thom)
MCFG_VIDEO_START_OVERRIDE( thomson_state, thom )
MCFG_DEFAULT_LAYOUT( layout_thomson )
/* sound */
MCFG_SPEAKER_STANDARD_MONO("mono")

View File

@ -242,7 +242,7 @@ public:
MACHINE_CONFIG_EXTERN( mw8080bw_root );
MACHINE_CONFIG_EXTERN( invaders );
extern const char layout_invaders[];
extern const internal_layout layout_invaders;
/*----------- defined in audio/mw8080bw.c -----------*/