* Support *n conversion in stream_format/string_format

* Make stream_format return characters printed
* Add iostreams with std::vector storage
* Move to type-safe templates for logerror and popmessage
* Remove now-unnecessary I64FMT from calls to logerror/popmessage
* Put some lib/util stuff in util:: namespace
* Some fixes to Japanese translation
This commit is contained in:
Vas Crabb 2016-03-01 06:45:41 +11:00
parent b2fc583ed7
commit a830ea7627
56 changed files with 919 additions and 476 deletions

View File

@ -149,7 +149,7 @@ msgstr ""
#: src/emu/ui/custmenu.cpp:183 src/emu/ui/custmenu.cpp:468
#: src/emu/ui/optsmenu.cpp:247
msgid "^!Year"
msgstr ""
msgstr "^!年度"
#: src/emu/ui/custmenu.cpp:192 src/emu/ui/custmenu.cpp:504
msgid "Remove last filter"
@ -165,23 +165,20 @@ msgid "Select custom filters:"
msgstr "カスタムフィルタ選択:"
#: src/emu/ui/custmenu.cpp:459
#, fuzzy
msgid "^!Publisher"
msgstr "発売元%1$s〜"
msgstr "^!発売元"
#: src/emu/ui/custmenu.cpp:477
#, fuzzy
msgid "^!Software List"
msgstr "ソフトウェアのヒストリ"
msgstr "^!ソフトウェアリスト"
#: src/emu/ui/custmenu.cpp:486
#, fuzzy
msgid "^!Device type"
msgstr "デバイスタイプ%1$s〜"
msgstr "^!デバイスタイプ"
#: src/emu/ui/custmenu.cpp:495
msgid "^!Region"
msgstr ""
msgstr "^!リージョン"
#: src/emu/ui/custui.cpp:20
msgid "Show All"
@ -220,9 +217,8 @@ msgid "Custom UI Settings"
msgstr "カスタムUI設定"
#: src/emu/ui/custui.cpp:268
#, fuzzy
msgid "default"
msgstr "デフォルト"
msgstr "デフォルト"
#: src/emu/ui/custui.cpp:371
msgid "UI Font"
@ -355,23 +351,22 @@ msgstr "マウスオーバー"
#: src/emu/ui/custui.cpp:860 src/emu/ui/custui.cpp:863
msgid "Alpha"
msgstr ""
msgstr "アルファ"
#: src/emu/ui/custui.cpp:868 src/emu/ui/custui.cpp:871
#: src/emu/ui/custui.cpp:1030
msgid "Red"
msgstr ""
msgstr ""
#: src/emu/ui/custui.cpp:876 src/emu/ui/custui.cpp:879
#: src/emu/ui/custui.cpp:1033
#, fuzzy
msgid "Green"
msgstr "画面"
msgstr ""
#: src/emu/ui/custui.cpp:884 src/emu/ui/custui.cpp:887
#: src/emu/ui/custui.cpp:1034
msgid "Blue"
msgstr ""
msgstr ""
#: src/emu/ui/custui.cpp:890
msgid "Choose from palette"
@ -387,32 +382,31 @@ msgstr "色のプレビュー ="
#: src/emu/ui/custui.cpp:1026
msgid "White"
msgstr ""
msgstr ""
#: src/emu/ui/custui.cpp:1027
msgid "Silver"
msgstr ""
msgstr "銀色"
#: src/emu/ui/custui.cpp:1028
msgid "Gray"
msgstr ""
msgstr "灰色"
#: src/emu/ui/custui.cpp:1029
msgid "Black"
msgstr ""
msgstr ""
#: src/emu/ui/custui.cpp:1031
#, fuzzy
msgid "Orange"
msgstr "変更)"
msgstr "オレンジ"
#: src/emu/ui/custui.cpp:1032
msgid "Yellow"
msgstr ""
msgstr ""
#: src/emu/ui/custui.cpp:1035
msgid "Violet"
msgstr ""
msgstr ""
#: src/emu/ui/datmenu.cpp:59
msgid "Software History"
@ -606,9 +600,8 @@ msgid " Folder"
msgstr " 削除する"
#: src/emu/ui/dsplmenu.cpp:38
#, fuzzy
msgid "Video Mode"
msgstr "表示設定"
msgstr ""
#: src/emu/ui/dsplmenu.cpp:40
msgid "Hardware Stretch"
@ -620,16 +613,15 @@ msgstr ""
#: src/emu/ui/dsplmenu.cpp:42
msgid "HLSL"
msgstr ""
msgstr "HLSL"
#: src/emu/ui/dsplmenu.cpp:44
msgid "GLSL"
msgstr ""
msgstr "GLSL"
#: src/emu/ui/dsplmenu.cpp:45
#, fuzzy
msgid "Bilinear Filtering"
msgstr "フィルタを非表示にする"
msgstr "バイリニアフィルタリング"
#: src/emu/ui/dsplmenu.cpp:46
msgid "Bitmap Prescaling"
@ -689,9 +681,8 @@ msgid "New Image Name:"
msgstr ""
#: src/emu/ui/filesel.cpp:277
#, fuzzy
msgid "Image Format:"
msgstr "イメージ情報"
msgstr ""
#: src/emu/ui/filesel.cpp:283
msgid "Create"
@ -710,23 +701,20 @@ msgid "[create]"
msgstr ""
#: src/emu/ui/filesel.cpp:510 src/emu/ui/swlist.cpp:76
#, fuzzy
msgid "[software list]"
msgstr "ソフトウェアのヒストリ"
msgstr "【ソフトウェアリスト】"
#: src/emu/ui/filesel.cpp:802
#, fuzzy
msgid "Select image format"
msgstr "イメージ情報"
msgstr ""
#: src/emu/ui/filesel.cpp:862
#, fuzzy
msgid "Select access mode"
msgstr "選択済の項目"
msgstr ""
#: src/emu/ui/filesel.cpp:863
msgid "Read-only"
msgstr ""
msgstr "読み取り専用"
#: src/emu/ui/filesel.cpp:865
msgid "Read-write"
@ -772,12 +760,11 @@ msgstr ""
#: src/emu/ui/inputmap.cpp:52
msgid "User Interface"
msgstr ""
msgstr "ユーザーインターフェイス"
#: src/emu/ui/inputmap.cpp:59
#, fuzzy
msgid "Other Controls"
msgstr "スライダ設定"
msgstr ""
#: src/emu/ui/inputmap.cpp:625 src/emu/ui/miscmenu.cpp:90
#: src/emu/ui/slotopt.cpp:172
@ -877,24 +864,20 @@ msgid "Select New Machine"
msgstr "新しいマシンを選択"
#: src/emu/ui/menu.cpp:45
#, fuzzy
msgid "Control Panels"
msgstr "操作パネル画像"
#: src/emu/ui/menu.cpp:50
#, fuzzy
msgid "Artwork Preview"
msgstr "アートワークのプレビュー"
#: src/emu/ui/menu.cpp:54
#, fuzzy
msgid "Game Over"
msgstr "ゲームオーバー"
#: src/emu/ui/menu.cpp:63
#, fuzzy
msgid "Add or remove favorites"
msgstr "お気に入りに追加"
msgstr ""
#: src/emu/ui/menu.cpp:64
msgid "Export displayed list to file"
@ -914,7 +897,7 @@ msgstr "終了"
#: src/emu/ui/menu.cpp:263 src/emu/ui/menu.cpp:265
msgid "Return to Previous Menu"
msgstr ""
msgstr "前のメニューに戻る"
#: src/emu/ui/menu.cpp:680
msgid "Auto"
@ -1063,16 +1046,15 @@ msgstr "フィルタ"
#: src/emu/ui/optsmenu.cpp:226
msgid " ^!File"
msgstr ""
msgstr "^!ファイル"
#: src/emu/ui/optsmenu.cpp:231
msgid " ^!Category"
msgstr ""
#: src/emu/ui/optsmenu.cpp:254
#, fuzzy
msgid "^!Setup custom filter"
msgstr "カスタムフィルタ選択:"
msgstr ""
#: src/emu/ui/optsmenu.cpp:262
msgid "Customize UI"
@ -1447,7 +1429,7 @@ msgstr ""
#: src/emu/ui/selsoft.cpp:684
#, c-format
msgid "Driver: \"%1$s\" software list "
msgstr "ドライバ:「%1$s」ソフトウェアリスト"
msgstr "ドライバ:「%1$s」 ソフトウェアリスト"
#: src/emu/ui/selsoft.cpp:687
#, c-format
@ -1483,7 +1465,7 @@ msgstr "%1$s検索%2$s_"
#: src/emu/ui/simpleselgame.cpp:322
#, c-format
msgid "%1$-.100s"
msgstr ""
msgstr "%1$-.100s"
#: src/emu/ui/selsoft.cpp:1977 src/emu/ui/selsoft.cpp:1997
msgid "Software part selection:"
@ -1550,9 +1532,8 @@ msgid "Use External Samples"
msgstr "外部サンプル使用"
#: src/emu/ui/swlist.cpp:70
#, fuzzy
msgid "[file manager]"
msgstr "ファイルマネージャ"
msgstr "ファイルマネージャ"
#: src/emu/ui/swlist.cpp:235
msgid "Switch Item Ordering"
@ -1576,33 +1557,32 @@ msgid "[compatible lists]"
msgstr ""
#: src/emu/ui/tapectrl.cpp:84
#, fuzzy
msgid "stopped"
msgstr "切り落とし"
msgstr "停止"
#: src/emu/ui/tapectrl.cpp:86
msgid "playing"
msgstr ""
msgstr "再生中"
#: src/emu/ui/tapectrl.cpp:86
msgid "(playing)"
msgstr ""
msgstr "(再生中)"
#: src/emu/ui/tapectrl.cpp:87
msgid "recording"
msgstr ""
msgstr "録音中"
#: src/emu/ui/tapectrl.cpp:87
msgid "(recording)"
msgstr ""
msgstr "(録音中)"
#: src/emu/ui/tapectrl.cpp:94
msgid "Pause/Stop"
msgstr ""
msgstr "一時停止/停止"
#: src/emu/ui/tapectrl.cpp:97
msgid "Play"
msgstr ""
msgstr "再生"
#: src/emu/ui/tapectrl.cpp:100
msgid "Record"
@ -1610,11 +1590,11 @@ msgstr ""
#: src/emu/ui/tapectrl.cpp:103
msgid "Rewind"
msgstr ""
msgstr "巻き戻す"
#: src/emu/ui/tapectrl.cpp:106
msgid "Fast Forward"
msgstr ""
msgstr "早送り"
#: src/emu/ui/ui.cpp:415
msgid "This driver requires images to be loaded in the following device(s): "
@ -1769,6 +1749,11 @@ msgid ""
"\n"
"CPU:\n"
msgstr ""
"%1$s\n"
"%2$s %3$s\n"
"ドライバ:%4$s\n"
"\n"
"CPU:\n"
#: src/emu/ui/ui.cpp:1228 src/emu/ui/ui.cpp:1267
msgid "MHz"
@ -1900,17 +1885,17 @@ msgstr ""
#: src/emu/ui/ui.cpp:2025
#, c-format
msgid "%1$s Brightness"
msgstr ""
msgstr "%1$sの輝度"
#: src/emu/ui/ui.cpp:2028
#, c-format
msgid "%1$s Contrast"
msgstr ""
msgstr "%1$sのコントラスト"
#: src/emu/ui/ui.cpp:2031
#, c-format
msgid "%1$s Gamma"
msgstr ""
msgstr "%1$sのガンマ"
#: src/emu/ui/ui.cpp:2036
#, c-format
@ -2012,13 +1997,13 @@ msgstr ""
#: src/emu/ui/ui.cpp:2424 src/emu/ui/ui.cpp:2446
#, c-format
msgid "%1$.3f"
msgstr ""
msgstr "%1$.3f"
#: src/emu/ui/ui.cpp:2462 src/emu/ui/ui.cpp:2478 src/emu/ui/ui.cpp:2494
#: src/emu/ui/ui.cpp:2510
#, c-format
msgid "%1$1.2f"
msgstr ""
msgstr "%1$1.2f"
#: src/emu/ui/ui.cpp:2526
#, fuzzy, c-format

View File

@ -87,6 +87,7 @@ files {
MAME_DIR .. "src/emu/devfind.h",
MAME_DIR .. "src/emu/device.cpp",
MAME_DIR .. "src/emu/device.h",
MAME_DIR .. "src/emu/device.ipp",
MAME_DIR .. "src/emu/didisasm.cpp",
MAME_DIR .. "src/emu/didisasm.h",
MAME_DIR .. "src/emu/diexec.cpp",
@ -157,6 +158,7 @@ files {
MAME_DIR .. "src/emu/mame.h",
MAME_DIR .. "src/emu/machine.cpp",
MAME_DIR .. "src/emu/machine.h",
MAME_DIR .. "src/emu/machine.ipp",
MAME_DIR .. "src/emu/mconfig.cpp",
MAME_DIR .. "src/emu/mconfig.h",
MAME_DIR .. "src/emu/memarray.cpp",

View File

@ -85,6 +85,7 @@ project "utils"
MAME_DIR .. "src/lib/util/pool.h",
MAME_DIR .. "src/lib/util/sha1.cpp",
MAME_DIR .. "src/lib/util/sha1.h",
MAME_DIR .. "src/lib/util/strformat.h",
MAME_DIR .. "src/lib/util/tagmap.h",
MAME_DIR .. "src/lib/util/unicode.cpp",
MAME_DIR .. "src/lib/util/unicode.h",
@ -94,6 +95,7 @@ project "utils"
MAME_DIR .. "src/lib/util/un7z.h",
MAME_DIR .. "src/lib/util/vbiparse.cpp",
MAME_DIR .. "src/lib/util/vbiparse.h",
MAME_DIR .. "src/lib/util/vecstream.h",
MAME_DIR .. "src/lib/util/xmlfile.cpp",
MAME_DIR .. "src/lib/util/xmlfile.h",
MAME_DIR .. "src/lib/util/zippath.cpp",

View File

@ -444,12 +444,10 @@ const char *threecom3c505_device::cpu_context()
logerror - log an error message (w/o device tags)
-------------------------------------------------*/
void threecom3c505_device::logerror(const char *format, ...) const
template <typename Format, typename... Params>
void threecom3c505_device::logerror(Format &&fmt, Params &&... args) const
{
va_list arg;
va_start(arg, format);
machine().vlogerror(format, arg);
va_end(arg);
machine().logerror(std::forward<Format>(fmt), std::forward<Params>(args)...);
}
//**************************************************************************

View File

@ -143,7 +143,7 @@ protected:
virtual int setfilter(device_t *, int);
const char *cpu_context();
void logerror(const char *format, ...) const;
template <typename Format, typename... Params> void logerror(Format &&fmt, Params &&... args) const;
// device-level overrides
virtual void device_start() override;

View File

@ -75,7 +75,7 @@ protected:
void omti_disk_config(UINT16 disk_type);
private:
void logerror(const char *format, ...) const;
template <typename Format, typename... Params> void logerror(Format &&fmt, Params &&... args) const;
public:
UINT16 m_type;
@ -693,12 +693,10 @@ void omti8621_device::set_esdi_defect_list(UINT8 lun, UINT8 head)
logerror - log an error message (w/o device tags)
-------------------------------------------------*/
void omti8621_device::logerror(const char *format, ...) const
template <typename Format, typename... Params>
void omti8621_device::logerror(Format &&fmt, Params &&... args) const
{
va_list arg;
va_start(arg, format);
machine().vlogerror(format, arg);
va_end(arg);
machine().logerror(std::forward<Format>(fmt), std::forward<Params>(args)...);
}
/***************************************************************************
@ -1358,12 +1356,10 @@ void omti_disk_image_device::omti_disk_config(UINT16 disk_type)
logerror - log an error message (w/o device tags)
-------------------------------------------------*/
void omti_disk_image_device::logerror(const char *format, ...) const
template <typename Format, typename... Params>
void omti_disk_image_device::logerror(Format &&fmt, Params &&... args) const
{
va_list arg;
va_start(arg, format);
machine().vlogerror(format, arg);
va_end(arg);
machine().logerror(std::forward<Format>(fmt), std::forward<Params>(args)...);
}
/*-------------------------------------------------

View File

@ -115,7 +115,7 @@ private:
void format_track(const UINT8 * cdb);
void set_esdi_defect_list(UINT8 lun, UINT8 head);
void logerror(const char *format, ...) const;
template <typename Format, typename... Params> void logerror(Format &&fmt, Params &&... args) const;
void log_command(const UINT8 cdb[], const UINT16 cdb_length);
void log_data();

View File

@ -431,12 +431,10 @@ const char *sc499_device::cpu_context()
logerror - log an error message (w/o device tags)
-------------------------------------------------*/
void sc499_device::logerror(const char *format, ...) const
template <typename Format, typename... Params>
void sc499_device::logerror(Format &&fmt, Params &&... args) const
{
va_list arg;
va_start(arg, format);
machine().vlogerror(format, arg);
va_end(arg);
machine().logerror(std::forward<Format>(fmt), std::forward<Params>(args)...);
}
/*-------------------------------------------------

View File

@ -80,7 +80,7 @@ private:
virtual void eop_w(int state) override;
const char *cpu_context();
void logerror(const char *format, ...) const;
template <typename Format, typename... Params> void logerror(Format &&fmt, Params &&... args) const;
void tape_status_clear(UINT16 value);
void tape_status_set(UINT16 value);

View File

@ -20,55 +20,38 @@ const device_type ALTO2 = &device_creator<alto2_cpu_device>;
// LOGGING AND DEBUGGING
//**************************************************************************
#if ALTO2_DEBUG
int g_log_types = LOG_DISK | LOG_ETH;
int g_log_level = 8;
bool g_log_newline = true;
void logprintf(device_t *device, int type, int level, const char* format, ...)
{
static const char* type_name[] = {
"[CPU]",
"[EMU]",
"[T01]",
"[T02]",
"[T03]",
"[KSEC]",
"[T05]",
"[T06]",
"[ETH]",
"[MRT]",
"[DWT]",
"[CURT]",
"[DHT]",
"[DVT]",
"[PART]",
"[KWD]",
"[T17]",
"[MEM]",
"[RAM]",
"[DRIVE]",
"[DISK]",
"[DISPL]",
"[MOUSE]",
"[HW]",
"[KBD]"
};
if (!(g_log_types & type))
return;
if (level > g_log_level)
return;
if (g_log_newline) {
// last line had a \n - print type name
for (int i = 0; i < sizeof(type_name)/sizeof(type_name[0]); i++)
if (type & (1 << i))
device->logerror("%-7s ", type_name[i]);
}
va_list ap;
va_start(ap, format);
device->vlogerror(format, ap);
va_end(ap);
g_log_newline = format[strlen(format) - 1] == '\n';
}
int alto2_log_t::log_types = LOG_DISK | LOG_ETH;
int alto2_log_t::log_level = 8;
bool alto2_log_t::log_newline = true;
const char *const alto2_log_t::type_name[] = {
"[CPU]",
"[EMU]",
"[T01]",
"[T02]",
"[T03]",
"[KSEC]",
"[T05]",
"[T06]",
"[ETH]",
"[MRT]",
"[DWT]",
"[CURT]",
"[DHT]",
"[DVT]",
"[PART]",
"[KWD]",
"[T17]",
"[MEM]",
"[RAM]",
"[DRIVE]",
"[DISK]",
"[DISPL]",
"[MOUSE]",
"[HW]",
"[KBD]"
};
const size_t alto2_log_t::type_name_count = sizeof(alto2_log_t::type_name) / sizeof(alto2_log_t::type_name[0]);
alto2_log_t logprintf;
#endif
//**************************************************************************

View File

@ -125,10 +125,33 @@ enum {
LOG_KBD = (1 << 24),
LOG_ALL = ((1 << 25) - 1)
};
extern int m_log_types;
extern int m_log_level;
extern bool m_log_newline;
void logprintf(device_t *device, int type, int level, const char* format, ...);
class alto2_log_t
{
public:
template <typename... Params>
void operator()(device_t *device, int type, int level, const char* format, Params &&...args)
{
if (!(log_types & type))
return;
if (level > log_level)
return;
if (log_newline) {
// last line had a \n - print type name
for (int i = 0; i < type_name_count; i++)
if (type & (1 << i))
device->logerror("%-7s ", type_name[i]);
}
device->logerror(format, std::forward<Params>(args)...);
log_newline = format[strlen(format) - 1] == '\n';
}
private:
static int log_types;
static int log_level;
static bool log_newline;
static const char *const type_name[];
static const size_t type_name_count;
};
extern alto2_log_t logprintf;
# define LOG(x) logprintf x
#else
# define LOG(x)

View File

@ -376,31 +376,6 @@ uml::instruction &drcuml_block::append()
}
//-------------------------------------------------
// comment - attach a comment to the current
// output location in the specified block
//-------------------------------------------------
void drcuml_block::append_comment(const char *format, ...)
{
// do the printf
std::string temp;
va_list va;
va_start(va, format);
strvprintf(temp,format, va);
va_end(va);
// allocate space in the cache to hold the comment
char *comment = (char *)m_drcuml.cache().alloc_temporary(temp.length() + 1);
if (comment == nullptr)
return;
strcpy(comment, temp.c_str());
// add an instruction with a pointer
append().comment(comment);
}
//-------------------------------------------------
// optimize - apply various optimizations to a
// block of code

View File

@ -108,7 +108,7 @@ public:
// instruction appending
uml::instruction &append();
void append_comment(const char *format, ...) ATTR_PRINTF(2,3);
template <typename Format, typename... Params> void append_comment(Format &&fmt, Params &&... args);
// this class is thrown if abort() is called
class abort_compilation : public emu_exception
@ -236,4 +236,31 @@ private:
//**************************************************************************
// MEMBER TEMPLATES
//**************************************************************************
//-------------------------------------------------
// comment - attach a comment to the current
// output location in the specified block
//-------------------------------------------------
template <typename Format, typename... Params>
inline void drcuml_block::append_comment(Format &&fmt, Params &&... args)
{
// do the printf
std::string temp(util::string_format(std::forward<Format>(fmt), std::forward<Params>(args)...));
// allocate space in the cache to hold the comment
char *comment = (char *)m_drcuml.cache().alloc_temporary(temp.length() + 1);
if (comment != nullptr)
{
strcpy(comment, temp.c_str());
// add an instruction with a pointer
append().comment(comment);
}
}
#endif /* __DRCUML_H__ */

View File

@ -612,7 +612,7 @@ WRITE32_MEMBER( sh2_device::sh7604_w )
{
INT64 a = m_m[0x45] | ((UINT64)(m_m[0x44]) << 32);
INT64 b = (INT32)m_m[0x40];
LOG(("SH2 '%s' div+mod %" I64FMT "d/%" I64FMT "d\n", tag(), a, b));
LOG(("SH2 '%s' div+mod %d/%d\n", tag(), a, b));
if (b)
{
INT64 q = a / b;

View File

@ -870,11 +870,11 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
std::ostringstream buffer;
for (const char *opsrc = opinfo.mnemonic; *opsrc != 0; opsrc++)
if (*opsrc == '!')
stream_format(buffer, "%-8s", bang_size[m_size]);
util::stream_format(buffer, "%-8s", bang_size[m_size]);
else if (*opsrc == '#')
stream_format(buffer, "%-8s", pound_size[m_size]);
util::stream_format(buffer, "%-8s", pound_size[m_size]);
else
stream_format(buffer, "%-8c", *opsrc);
util::stream_format(buffer, "%-8c", *opsrc);
// iterate through parameters
for (int pnum = 0; pnum < m_numparams; pnum++)
@ -911,20 +911,20 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
if (size == 2) value = (UINT16)value;
if (size == 4) value = (UINT32)value;
if ((UINT32)value == value)
stream_format(buffer, "$%X", (UINT32)value);
util::stream_format(buffer, "$%X", (UINT32)value);
else
stream_format(buffer, "$%X%08X", (UINT32)(value >> 32), (UINT32)value);
util::stream_format(buffer, "$%X%08X", (UINT32)(value >> 32), (UINT32)value);
}
break;
// immediates have several special cases
case parameter::PTYPE_SIZE:
stream_format(buffer, "%s", sizes[param.size()]);
util::stream_format(buffer, "%s", sizes[param.size()]);
break;
// size + address space immediate
case parameter::PTYPE_SIZE_SPACE:
stream_format(buffer, "%s_%s", spaces[param.space()], sizes[param.size()]);
util::stream_format(buffer, "%s_%s", spaces[param.space()], sizes[param.size()]);
break;
// size + scale immediate
@ -933,30 +933,30 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
int scale = param.scale();
int size = param.size();
if (scale == size)
stream_format(buffer, "%s", sizes[size]);
util::stream_format(buffer, "%s", sizes[size]);
else
stream_format(buffer, "%s_x%d", sizes[size], 1 << scale);
util::stream_format(buffer, "%s_x%d", sizes[size], 1 << scale);
}
break;
// fmod immediate
case parameter::PTYPE_ROUNDING:
stream_format(buffer, "%s", fmods[param.rounding()]);
util::stream_format(buffer, "%s", fmods[param.rounding()]);
break;
// integer registers
case parameter::PTYPE_INT_REGISTER:
stream_format(buffer, "i%d", param.ireg() - REG_I0);
util::stream_format(buffer, "i%d", param.ireg() - REG_I0);
break;
// floating point registers
case parameter::PTYPE_FLOAT_REGISTER:
stream_format(buffer, "f%d", param.freg() - REG_F0);
util::stream_format(buffer, "f%d", param.freg() - REG_F0);
break;
// map variables
case parameter::PTYPE_MAPVAR:
stream_format(buffer, "m%d", param.mapvar() - MAPVAR_M0);
util::stream_format(buffer, "m%d", param.mapvar() - MAPVAR_M0);
break;
// memory
@ -969,40 +969,40 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
if (drcuml != nullptr && (symbol = drcuml->symbol_find(param.memory(), &symoffset)) != nullptr)
{
if (symoffset == 0)
stream_format(buffer, "[%s]", symbol);
util::stream_format(buffer, "[%s]", symbol);
else
stream_format(buffer, "[%s+$%X]", symbol, symoffset);
util::stream_format(buffer, "[%s+$%X]", symbol, symoffset);
}
// cache memory
else if (drcuml != nullptr && drcuml->cache().contains_pointer(param.memory()))
stream_format(buffer, "[+$%X]", (UINT32)(FPTR)((drccodeptr)param.memory() - drcuml->cache().near()));
util::stream_format(buffer, "[+$%X]", (UINT32)(FPTR)((drccodeptr)param.memory() - drcuml->cache().near()));
// general memory
else
stream_format(buffer, "[[$%p]]", param.memory());
util::stream_format(buffer, "[[$%p]]", param.memory());
break;
}
// string pointer
case parameter::PTYPE_STRING:
stream_format(buffer, "%s", (const char *)(FPTR)param.string());
util::stream_format(buffer, "%s", (const char *)(FPTR)param.string());
break;
// handle pointer
case parameter::PTYPE_CODE_HANDLE:
stream_format(buffer, "%s", param.handle().string());
util::stream_format(buffer, "%s", param.handle().string());
break;
default:
stream_format(buffer, "???");
util::stream_format(buffer, "???");
break;
}
}
// if there's a condition, append it
if (m_condition != COND_ALWAYS)
stream_format(buffer, ",%s", conditions[m_condition & 0x0f]);
util::stream_format(buffer, ",%s", conditions[m_condition & 0x0f]);
// if there are flags, append them
if (m_flags != 0)

View File

@ -111,14 +111,11 @@ diablo_hd_device::~diablo_hd_device()
}
#if DIABLO_DEBUG
void diablo_hd_device::logprintf(int level, const char* format, ...)
template <typename Format, typename... Params>
void diablo_hd_device::logprintf(int level, Format &&fmt, Params &&... args)
{
if (level > m_log_level)
return;
va_list ap;
va_start(ap, format);
vlogerror(format, ap);
va_end(ap);
if (level <= m_log_level)
logerror(std::forward<Format>(fmt), std::forward<Params>(args)...);
}
#endif
@ -126,7 +123,7 @@ void diablo_hd_device::set_sector_callback(void *cookie, void (*callback)(void *
{
if (m_sector_callback_cookie == cookie && m_sector_callback == callback)
return;
LOG_DRIVE((0,"[DHD%u] cookie=%p callback=%p\n", m_unit, cookie, callback));
LOG_DRIVE((0,"[DHD%u] cookie=%p callback=%p\n", m_unit, cookie, (void *)callback));
m_sector_callback_cookie = cookie;
m_sector_callback = callback;
}

View File

@ -76,7 +76,7 @@ protected:
private:
#if DIABLO_DEBUG
int m_log_level;
void logprintf(int level, const char* format, ...);
template <typename Format, typename... Params> void logprintf(int level, Format &&fmt, Params &&... args);
# define LOG_DRIVE(x) logprintf x
#else

View File

@ -340,7 +340,7 @@ void pci_device::add_map(UINT64 size, int flags, address_map_delegate &map)
bank_reg_infos[breg].hi = 0;
}
logerror("Device %s (%s) has 0x%" I64FMT "x bytes of %s named %s\n", tag(), name(), size, flags & M_IO ? "io" : "memory", bank_infos[bid].map.name());
logerror("Device %s (%s) has 0x%x bytes of %s named %s\n", tag(), name(), size, flags & M_IO ? "io" : "memory", bank_infos[bid].map.name());
}
void pci_device::add_rom(const UINT8 *rom, UINT32 size)

View File

@ -723,7 +723,7 @@ void pit8253_device::update(pit8253_timer *timer)
attotime elapsed_time = now - timer->last_updated;
INT64 elapsed_cycles = elapsed_time.as_double() * timer->clockin;
LOG1(("pit8253: update(): timer %d, %" I64FMT "d elapsed_cycles\n", timer->index, elapsed_cycles));
LOG1(("pit8253: update(): timer %d, %d elapsed_cycles\n", timer->index, elapsed_cycles));
if (timer->clockin)
timer->last_updated += elapsed_cycles * attotime::from_hz(timer->clockin);

View File

@ -149,13 +149,13 @@ void ram_device::device_validity_check(validity_checker &valid) const
if (!is_valid)
{
std::ostringstream output;
stream_format(output, "Cannot recognize the RAM option %s", ramsize_string);
stream_format(output, " (valid options are %s", m_default_size);
util::stream_format(output, "Cannot recognize the RAM option %s", ramsize_string);
util::stream_format(output, " (valid options are %s", m_default_size);
if (m_extra_options != nullptr)
stream_format(output, ",%s).\n", m_extra_options);
util::stream_format(output, ",%s).\n", m_extra_options);
else
stream_format(output, ").\n");
util::stream_format(output, ").\n");
osd_printf_error("%s", output.str().c_str());

View File

@ -840,7 +840,7 @@ void z80scc_channel::tra_callback()
{
if (!(m_wr5 & WR5_TX_ENABLE))
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit mark
if (m_index == z80scc_device::CHANNEL_A)
m_uart->m_out_txda_cb(1);
@ -849,7 +849,7 @@ void z80scc_channel::tra_callback()
}
else if (m_wr5 & WR5_SEND_BREAK)
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c send break 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c send break 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit break
if (m_index == z80scc_device::CHANNEL_A)
m_uart->m_out_txda_cb(0);
@ -860,7 +860,7 @@ void z80scc_channel::tra_callback()
{
int db = transmit_register_get_data_bit();
LOG(("%" I64FMT "d %s() \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, db, m_wr5));
LOG(("%d %s() \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, db, m_wr5));
// transmit data
if (m_index == z80scc_device::CHANNEL_A)
m_uart->m_out_txda_cb(db);
@ -869,7 +869,7 @@ void z80scc_channel::tra_callback()
}
else
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
logerror("%s \"%s \"Channel %c Failed to transmit\n", FUNCNAME, m_owner->tag(), 'A' + m_index);
}
}
@ -883,7 +883,7 @@ void z80scc_channel::tra_complete()
{
if ((m_wr5 & WR5_TX_ENABLE) && !(m_wr5 & WR5_SEND_BREAK) && !(m_rr0 & RR0_TX_BUFFER_EMPTY))
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_tx_data, m_wr5));
LOG(("%d %s() \"%s \"Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_tx_data, m_wr5));
transmit_register_setup(m_tx_data);
@ -895,7 +895,7 @@ void z80scc_channel::tra_complete()
}
else if (m_wr5 & WR5_SEND_BREAK)
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit break
if (m_index == z80scc_device::CHANNEL_A)
m_uart->m_out_txda_cb(0);
@ -904,7 +904,7 @@ void z80scc_channel::tra_complete()
}
else
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit mark
if (m_index == z80scc_device::CHANNEL_A)
m_uart->m_out_txda_cb(1);
@ -915,7 +915,7 @@ void z80scc_channel::tra_complete()
// if transmit buffer is empty
if (m_rr0 & RR0_TX_BUFFER_EMPTY)
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Transmit buffer empty m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c Transmit buffer empty m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// then all characters have been sent
m_rr1 |= RR1_ALL_SENT;
@ -939,7 +939,7 @@ void z80scc_channel::rcv_callback()
#if 1
else
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Received Data Bit but receiver is disabled\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index));
LOG(("%d %s() \"%s \"Channel %c Received Data Bit but receiver is disabled\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index));
logerror("Z80SCC %s() \"%s \"Channel %c Received data dit but receiver is disabled\n", __func__, m_owner->tag(), 'A' + m_index);
}
#endif
@ -956,7 +956,7 @@ void z80scc_channel::rcv_complete()
receive_register_extract();
data = get_received_char();
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Received Data %c\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, data));
LOG(("%d %s() \"%s \"Channel %c Received Data %c\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, data));
receive_data(data);
}
@ -2240,7 +2240,7 @@ void z80scc_channel::update_serial()
else
parity = PARITY_NONE;
LOG(("%" I64FMT "d %s() \"%s \"Channel %c setting data frame %d+%d%c%d\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, 1,
LOG(("%d %s() \"%s \"Channel %c setting data frame %d+%d%c%d\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, 1,
data_bit_count, parity == PARITY_NONE ? 'N' : parity == PARITY_EVEN ? 'E' : 'O', (stop_bits + 1) / 2));
set_data_frame(1, data_bit_count, parity, stop_bits);

View File

@ -596,7 +596,7 @@ void z80sio_channel::tra_callback()
{
if (!(m_wr5 & WR5_TX_ENABLE))
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit mark
if (m_index == z80sio_device::CHANNEL_A)
m_uart->m_out_txda_cb(1);
@ -605,7 +605,7 @@ void z80sio_channel::tra_callback()
}
else if (m_wr5 & WR5_SEND_BREAK)
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c send break 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c send break 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit break
if (m_index == z80sio_device::CHANNEL_A)
m_uart->m_out_txda_cb(0);
@ -616,7 +616,7 @@ void z80sio_channel::tra_callback()
{
int db = transmit_register_get_data_bit();
LOG(("%" I64FMT "d %s() \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, db, m_wr5));
LOG(("%d %s() \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, db, m_wr5));
// transmit data
if (m_index == z80sio_device::CHANNEL_A)
m_uart->m_out_txda_cb(db);
@ -625,7 +625,7 @@ void z80sio_channel::tra_callback()
}
else
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
logerror("%s \"%s \"Channel %c Failed to transmit\n", FUNCNAME, m_owner->tag(), 'A' + m_index);
}
}
@ -639,7 +639,7 @@ void z80sio_channel::tra_complete()
LOG(("%s %s\n",FUNCNAME, tag()));
if ((m_wr5 & WR5_TX_ENABLE) && !(m_wr5 & WR5_SEND_BREAK) && !(m_rr0 & RR0_TX_BUFFER_EMPTY))
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_tx_data, m_wr5));
LOG(("%d %s() \"%s \"Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_tx_data, m_wr5));
transmit_register_setup(m_tx_data);
@ -651,7 +651,7 @@ void z80sio_channel::tra_complete()
}
else if (m_wr5 & WR5_SEND_BREAK)
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit break
if (m_index == z80sio_device::CHANNEL_A)
m_uart->m_out_txda_cb(0);
@ -660,7 +660,7 @@ void z80sio_channel::tra_complete()
}
else
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit mark
if (m_index == z80sio_device::CHANNEL_A)
m_uart->m_out_txda_cb(1);
@ -671,7 +671,7 @@ void z80sio_channel::tra_complete()
// if transmit buffer is empty
if (m_rr0 & RR0_TX_BUFFER_EMPTY)
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Transmit buffer empty m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG(("%d %s() \"%s \"Channel %c Transmit buffer empty m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// then all characters have been sent
m_rr1 |= RR1_ALL_SENT;
@ -689,13 +689,13 @@ void z80sio_channel::rcv_callback()
{
if (m_wr3 & WR3_RX_ENABLE)
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Received Data Bit %d\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_rxd));
LOG(("%d %s() \"%s \"Channel %c Received Data Bit %d\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_rxd));
receive_register_update_bit(m_rxd);
}
#if 0
else
{
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Received Data Bit but receiver is disabled\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index));
LOG(("%d %s() \"%s \"Channel %c Received Data Bit but receiver is disabled\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index));
logerror("Z80SIO %s() \"%s \"Channel %c Received data dit but receiver is disabled\n", __func__, m_owner->tag(), 'A' + m_index);
}
#endif
@ -711,7 +711,7 @@ void z80sio_channel::rcv_complete()
receive_register_extract();
data = get_received_char();
LOG(("%" I64FMT "d %s() \"%s \"Channel %c Received Data %02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, data));
LOG(("%d %s() \"%s \"Channel %c Received Data %02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, data));
receive_data(data);
}

View File

@ -783,42 +783,6 @@ finder_base *device_t::register_auto_finder(finder_base &autodev)
return old;
}
void device_t::popmessage(const char *format, ...) const
{
// if the format is NULL, it is a signal to clear the popmessage
if (format == nullptr)
machine().ui().popup_time(0, " ");
// otherwise, generate the buffer and call the UI to display the message
else
{
std::string temp;
va_list arg;
// dump to the buffer
va_start(arg, format);
strvprintf(temp, format, arg);
va_end(arg);
// pop it in the UI
if (m_machine!=nullptr) machine().ui().popup_time(temp.length() / 40 + 2, "%s", temp.c_str());
}
}
void device_t::logerror(const char *format, ...) const
{
va_list arg;
va_start(arg, format);
vlogerror(format, arg);
va_end(arg);
}
void device_t::vlogerror(const char *format, va_list args) const
{
std::string fmt("[");
fmt += tag() + std::string("] ") + format;
if (m_machine!=nullptr) machine().vlogerror(fmt.c_str(), args);
}
//**************************************************************************
// LIVE DEVICE INTERFACES
//**************************************************************************

View File

@ -206,9 +206,8 @@ public:
bool findit(bool isvalidation = false) const;
// misc
void popmessage(const char *format, ...) const;
void logerror(const char *format, ...) const;
void vlogerror(const char *format, va_list args) const;
template <typename Format, typename... Params> void popmessage(Format &&fmt, Params &&... args) const;
template <typename Format, typename... Params> void logerror(Format &&fmt, Params &&... args) const;
protected:
// miscellaneous helpers

40
src/emu/device.ipp Normal file
View File

@ -0,0 +1,40 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
device.h
Device interface functions.
***************************************************************************/
#pragma once
#ifndef __EMU_H__
#error Dont include this file directly; include emu.h instead.
#endif
#ifndef __DEVICE_IPP__
#define __DEVICE_IPP__
#include "strformat.h"
//**************************************************************************
// MEMBER TEMPLATES
//**************************************************************************
template <typename Format, typename... Params>
inline void device_t::popmessage(Format &&fmt, Params &&... args) const
{
if (m_machine)
m_machine->popmessage(std::forward<Format>(fmt), std::forward<Params>(args)...);
}
template <typename Format, typename... Params>
inline void device_t::logerror(Format &&fmt, Params &&... args) const
{
if (m_machine)
m_machine->logerror(string_format("[%s] %s", std::forward<Format>(fmt)), std::forward<Params>(args)...);
}
#endif // __DEVICE_IPP__

View File

@ -107,6 +107,9 @@ typedef device_t * (*machine_config_constructor)(machine_config &config, device_
#include "sound.h"
#include "speaker.h"
// user interface
#include "ui/ui.h"
// generic helpers
#include "devcb.h"
#include "dispatch.h"
@ -114,4 +117,8 @@ typedef device_t * (*machine_config_constructor)(machine_config &config, device_
#include "bookkeeping.h"
#include "video/generic.h"
// member templates that don't like incomplete types
#include "device.ipp"
#include "machine.ipp"
#endif /* __EMU_H__ */

View File

@ -335,9 +335,9 @@ void emu_options::add_device_options()
// retrieve info about the device instance
std::ostringstream option_name;
stream_format(option_name, "%s;%s", image->instance_name(), image->brief_instance_name());
util::stream_format(option_name, "%s;%s", image->instance_name(), image->brief_instance_name());
if (strcmp(image->device_typename(image->image_type()), image->instance_name()) == 0)
stream_format(option_name, ";%s1;%s1", image->instance_name(), image->brief_instance_name());
util::stream_format(option_name, ";%s1;%s1", image->instance_name(), image->brief_instance_name());
// add the option
if (!exists(image->instance_name()))

View File

@ -564,13 +564,13 @@ void info_xml_creator::output_rom(device_t &device)
// add name, merge, bios, and size tags */
if (name != nullptr && name[0] != 0)
stream_format(output, " name=\"%s\"", xml_normalize_string(name));
util::stream_format(output, " name=\"%s\"", xml_normalize_string(name));
if (merge_name != nullptr)
stream_format(output, " merge=\"%s\"", xml_normalize_string(merge_name));
util::stream_format(output, " merge=\"%s\"", xml_normalize_string(merge_name));
if (bios_name[0] != 0)
stream_format(output, " bios=\"%s\"", xml_normalize_string(bios_name));
util::stream_format(output, " bios=\"%s\"", xml_normalize_string(bios_name));
if (!is_disk)
stream_format(output, " size=\"%d\"", rom_file_size(rom));
util::stream_format(output, " size=\"%d\"", rom_file_size(rom));
// dump checksum information only if there is a known dump
if (!hashes.flag(hash_collection::FLAG_NO_DUMP))
@ -582,17 +582,17 @@ void info_xml_creator::output_rom(device_t &device)
output << " status=\"nodump\"";
// append a region name
stream_format(output, " region=\"%s\"", ROMREGION_GETTAG(region));
util::stream_format(output, " region=\"%s\"", ROMREGION_GETTAG(region));
// for non-disk entries, print offset
if (!is_disk)
stream_format(output, " offset=\"%x\"", offset);
util::stream_format(output, " offset=\"%x\"", offset);
// for disk entries, add the disk index
else
{
stream_format(output, " index=\"%x\"", DISK_GETINDEX(rom));
stream_format(output, " writable=\"%s\"", DISK_ISREADONLY(rom) ? "no" : "yes");
util::stream_format(output, " index=\"%x\"", DISK_GETINDEX(rom));
util::stream_format(output, " writable=\"%s\"", DISK_ISREADONLY(rom) ? "no" : "yes");
}
// add optional flag
@ -1104,16 +1104,16 @@ void info_xml_creator::output_switches(const ioport_list &portlist, const char *
// output the switch name information
std::string normalized_field_name(xml_normalize_string(field->name()));
std::string normalized_newtag(xml_normalize_string(newtag.c_str()));
stream_format(output,"\t\t<%s name=\"%s\" tag=\"%s\" mask=\"%u\">\n", outertag, normalized_field_name.c_str(), normalized_newtag.c_str(), field->mask());
util::stream_format(output,"\t\t<%s name=\"%s\" tag=\"%s\" mask=\"%u\">\n", outertag, normalized_field_name.c_str(), normalized_newtag.c_str(), field->mask());
// loop over settings
for (ioport_setting *setting = field->first_setting(); setting != nullptr; setting = setting->next())
{
stream_format(output,"\t\t\t<%s name=\"%s\" value=\"%u\"%s/>\n", innertag, xml_normalize_string(setting->name()), setting->value(), setting->value() == field->defvalue() ? " default=\"yes\"" : "");
util::stream_format(output,"\t\t\t<%s name=\"%s\" value=\"%u\"%s/>\n", innertag, xml_normalize_string(setting->name()), setting->value(), setting->value() == field->defvalue() ? " default=\"yes\"" : "");
}
// terminate the switch entry
stream_format(output,"\t\t</%s>\n", outertag);
util::stream_format(output,"\t\t</%s>\n", outertag);
fprintf(m_output, "%s", output.str().c_str());
}

View File

@ -1347,11 +1347,11 @@ std::string natural_keyboard::dump()
std::string description = string_format("%08X (%s) ", code.ch, unicode_to_string(code.ch).c_str());
// pad with spaces
stream_format(buffer, "%-*s", left_column_width, description);
util::stream_format(buffer, "%-*s", left_column_width, description);
// identify the keys used
for (int field = 0; field < ARRAY_LENGTH(code.field) && code.field[field] != nullptr; field++)
stream_format(buffer, "%s'%s'", (field > 0) ? ", " : "", code.field[field]->name());
util::stream_format(buffer, "%s'%s'", (field > 0) ? ", " : "", code.field[field]->name());
// carriage return
buffer << '\n';

View File

@ -94,15 +94,6 @@ void js_set_main_loop(running_machine * machine);
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// a giant string buffer for temporary strings
static char giant_string_buffer[65536] = { 0 };
//**************************************************************************
// RUNNING MACHINE
//**************************************************************************
@ -773,69 +764,6 @@ void running_machine::add_logerror_callback(logerror_callback callback)
m_logerror_list.push_back(std::make_unique<logerror_callback_item>(callback));
}
/*-------------------------------------------------
popmessage - pop up a user-visible message
-------------------------------------------------*/
void running_machine::popmessage(const char *format, ...) const
{
// if the format is NULL, it is a signal to clear the popmessage
if (format == nullptr)
ui().popup_time(0, " ");
// otherwise, generate the buffer and call the UI to display the message
else
{
std::string temp;
va_list arg;
// dump to the buffer
va_start(arg, format);
strvprintf(temp,format, arg);
va_end(arg);
// pop it in the UI
ui().popup_time(temp.length() / 40 + 2, "%s", temp.c_str());
}
}
/*-------------------------------------------------
logerror - log to the debugger and any other
OSD-defined output streams
-------------------------------------------------*/
void running_machine::logerror(const char *format, ...) const
{
va_list arg;
va_start(arg, format);
vlogerror(format, arg);
va_end(arg);
}
//-------------------------------------------------
// vlogerror - vprintf-style error logging
//-------------------------------------------------
void running_machine::vlogerror(const char *format, va_list args) const
{
// process only if there is a target
if (!m_logerror_list.empty())
{
g_profiler.start(PROFILER_LOGERROR);
// dump to the buffer
vsnprintf(giant_string_buffer, ARRAY_LENGTH(giant_string_buffer), format, args);
// log to all callbacks
for (auto& cb : m_logerror_list)
(cb->m_func)(*this, giant_string_buffer);
g_profiler.stop();
}
}
//-------------------------------------------------
// base_datetime - retrieve the time of the host
@ -1202,7 +1130,7 @@ std::string running_machine::nvram_filename(device_t &device) const
std::ostringstream result;
result << basename();
if (root_device().system_bios() != 0 && root_device().default_bios() != root_device().system_bios())
stream_format(result, "_%d", root_device().system_bios() - 1);
util::stream_format(result, "_%d", root_device().system_bios() - 1);
// device-based NVRAM gets its own name in a subdirectory
if (device.owner() != nullptr)

View File

@ -17,6 +17,8 @@
#ifndef __MACHINE_H__
#define __MACHINE_H__
#include "vecstream.h"
#include <time.h>
// forward declaration instead of osdepend.h
@ -73,6 +75,7 @@ const int DEBUG_FLAG_OSD_ENABLED = 0x00001000; // The OSD debugger is e
#define auto_alloc_array_clear(m, t, c) pool_alloc_array_clear(static_cast<running_machine &>(m).respool(), t, c)
#define auto_free(m, v) pool_free(static_cast<running_machine &>(m).respool(), v)
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@ -237,9 +240,9 @@ public:
INT32 get_vblank_watchdog_counter() const { return m_watchdog_counter; }
// misc
void popmessage(const char *format, ...) const;
void logerror(const char *format, ...) const;
void vlogerror(const char *format, va_list args) const;
void popmessage() const { popmessage(static_cast<char const *>(nullptr)); }
template <typename Format, typename... Params> void popmessage(Format &&fmt, Params &&... args) const;
template <typename Format, typename... Params> void logerror(Format &&fmt, Params &&... args) const;
UINT32 rand();
const char *describe_context();
@ -259,6 +262,8 @@ public:
private:
// internal helpers
template <typename T> struct is_null { template <typename U> static bool value(U &&x) { return false; } };
template <typename T> struct is_null<T *> { template <typename U> static bool value(U &&x) { return !x; } };
void start();
void set_saveload_filename(const char *filename);
std::string get_statename(const char *statename_opt) const;
@ -372,6 +377,9 @@ private:
std::unique_ptr<datfile_manager> m_datfile; // internal data from datfile.c
std::unique_ptr<inifile_manager> m_inifile; // internal data from inifile.c for INIs
std::unique_ptr<favorite_manager> m_favorite; // internal data from inifile.c for favorites
// string formatting buffer
mutable util::ovectorstream m_string_buffer;
};
#endif /* __MACHINE_H__ */

76
src/emu/machine.ipp Normal file
View File

@ -0,0 +1,76 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
machine.ipp
Controls execution of the core MAME system.
***************************************************************************/
#pragma once
#ifndef __EMU_H__
#error Dont include this file directly; include emu.h instead.
#endif
#ifndef __MACHINE_IPP__
#define __MACHINE_IPP__
#include "strformat.h"
//**************************************************************************
// MEMBER TEMPLATES
//**************************************************************************
/*-------------------------------------------------
popmessage - pop up a user-visible message
-------------------------------------------------*/
template <typename Format, typename... Params>
inline void running_machine::popmessage(Format &&fmt, Params &&... args) const
{
if (is_null<Format>::value(fmt))
{
// if the format is NULL, it is a signal to clear the popmessage
ui().popup_time(0, " ");
}
else
{
// otherwise, generate the buffer and call the UI to display the message
std::string const temp(string_format(std::forward<Format>(fmt), std::forward<Params>(args)...));
// pop it in the UI
ui().popup_time(temp.length() / 40 + 2, "%s", temp.c_str());
}
}
/*-------------------------------------------------
logerror - log to the debugger and any other
OSD-defined output streams
-------------------------------------------------*/
template <typename Format, typename... Params>
inline void running_machine::logerror(Format &&fmt, Params &&... args) const
{
// process only if there is a target
if (!m_logerror_list.empty())
{
g_profiler.start(PROFILER_LOGERROR);
// dump to the buffer
m_string_buffer.clear();
util::stream_format(m_string_buffer, std::forward<Format>(fmt), std::forward<Params>(args)...);
m_string_buffer.put('\0');
// log to all callbacks
char const *const str(&m_string_buffer.vec()[0]);
for (auto &cb : m_logerror_list)
(cb->m_func)(*this, str);
g_profiler.stop();
}
}
#endif // __MACHINE_IPP__

View File

@ -457,7 +457,7 @@ void device_scheduler::timeslice()
{
// compute how many cycles we want to execute
int ran = exec->m_cycles_running = divu_64x32((UINT64)delta >> exec->m_divshift, exec->m_divisor);
LOG((" cpu '%s': %" I64FMT"d (%d cycles)\n", exec->device().tag(), delta, exec->m_cycles_running));
LOG((" cpu '%s': %d (%d cycles)\n", exec->device().tag(), delta, exec->m_cycles_running));
// if we're not suspended, actually execute
if (exec->m_suspend == 0)

View File

@ -729,10 +729,10 @@ template <typename Format, typename... Params>
inline void softlist_parser::parse_error(Format &&fmt, Params &&... args)
{
// always start with filename(line.column):
stream_format(m_errors, "%s(%d.%d): ", filename(), line(), column());
util::stream_format(m_errors, "%s(%d.%d): ", filename(), line(), column());
// append the remainder of the string
stream_format(m_errors, std::forward<Format>(fmt), std::forward<Params>(args)...);
util::stream_format(m_errors, std::forward<Format>(fmt), std::forward<Params>(args)...);
// append a newline at the end
m_errors.put('\n');

View File

@ -168,13 +168,13 @@ std::string sound_stream::input_name(int inputnum) const
// start with our device name and tag
assert(inputnum >= 0 && inputnum < m_input.size());
stream_format(str, "%s '%s': ", m_device.name(), m_device.tag());
util::stream_format(str, "%s '%s': ", m_device.name(), m_device.tag());
// if we have a source, indicate where the sound comes from by device name and tag
if (m_input[inputnum].m_source != nullptr && m_input[inputnum].m_source->m_stream != nullptr)
{
device_t &source = m_input[inputnum].m_source->m_stream->device();
stream_format(str, "%s '%s'", source.name(), source.tag());
util::stream_format(str, "%s '%s'", source.name(), source.tag());
// get the sound interface; if there is more than 1 output we need to figure out which one
device_sound_interface *sound;
@ -187,7 +187,7 @@ std::string sound_stream::input_name(int inputnum) const
for (int outputnum = 0; (outstream = sound->output_to_stream_output(outputnum, streamoutputnum)) != nullptr; outputnum++)
if (outstream == m_input[inputnum].m_source->m_stream && m_input[inputnum].m_source == &outstream->m_output[streamoutputnum])
{
stream_format(str, " Ch.%d", outputnum);
util::stream_format(str, " Ch.%d", outputnum);
break;
}
}

View File

@ -179,21 +179,21 @@ void ui_menu_audit::save_available_machines()
// generate header
std::ostringstream buffer;
buffer << "#\n" << UI_VERSION_TAG << bare_build_version << "\n#\n\n";
stream_format(buffer, "%d\n", m_availablesorted.size());
stream_format(buffer, "%d\n", m_unavailablesorted.size());
util::stream_format(buffer, "%d\n", m_availablesorted.size());
util::stream_format(buffer, "%d\n", m_unavailablesorted.size());
// generate available list
for (size_t x = 0; x < m_availablesorted.size(); ++x)
{
int find = driver_list::find(m_availablesorted[x]->name);
stream_format(buffer, "%d\n", find);
util::stream_format(buffer, "%d\n", find);
}
// generate unavailable list
for (size_t x = 0; x < m_unavailablesorted.size(); ++x)
{
int find = driver_list::find(m_unavailablesorted[x]->name);
stream_format(buffer, "%d\n", find);
util::stream_format(buffer, "%d\n", find);
}
file.puts(buffer.str().c_str());
file.close();

View File

@ -31,7 +31,7 @@ void ui_menu_cheat::handle()
bool changed = false;
/* clear cheat comment on any movement or keypress */
machine().popmessage(nullptr);
machine().popmessage();
/* handle reset all + reset all cheats for reload all option */
if ((menu_event->itemref == ITEMREF_CHEATS_RESET_ALL || menu_event->itemref == ITEMREF_CHEATS_RELOAD_ALL) && menu_event->iptkey == IPT_UI_SELECT)

View File

@ -243,16 +243,16 @@ void ui_menu_custom_filter::save_custom_filters()
{
// generate custom filters info
std::ostringstream cinfo;
stream_format(cinfo, "Total filters = %d\n", (custfltr::numother + 1));
stream_format(cinfo, "Main filter = %s\n", main_filters::text[custfltr::main]);
util::stream_format(cinfo, "Total filters = %d\n", (custfltr::numother + 1));
util::stream_format(cinfo, "Main filter = %s\n", main_filters::text[custfltr::main]);
for (int x = 1; x <= custfltr::numother; x++)
{
stream_format(cinfo, "Other filter = %s\n", main_filters::text[custfltr::other[x]]);
util::stream_format(cinfo, "Other filter = %s\n", main_filters::text[custfltr::other[x]]);
if (custfltr::other[x] == FILTER_MANUFACTURER)
stream_format(cinfo, " Manufacturer filter = %s\n", c_mnfct::ui[custfltr::mnfct[x]]);
util::stream_format(cinfo, " Manufacturer filter = %s\n", c_mnfct::ui[custfltr::mnfct[x]]);
else if (custfltr::other[x] == FILTER_YEAR)
stream_format(cinfo, " Year filter = %s\n", c_year::ui[custfltr::year[x]]);
util::stream_format(cinfo, " Year filter = %s\n", c_year::ui[custfltr::year[x]]);
}
file.puts(cinfo.str().c_str());
file.close();
@ -556,22 +556,22 @@ void ui_menu_swcustom_filter::save_sw_custom_filters()
{
// generate custom filters info
std::ostringstream cinfo;
stream_format(cinfo, "Total filters = %d\n", (sw_custfltr::numother + 1));
stream_format(cinfo, "Main filter = %s\n", sw_filters::text[sw_custfltr::main]);
util::stream_format(cinfo, "Total filters = %d\n", (sw_custfltr::numother + 1));
util::stream_format(cinfo, "Main filter = %s\n", sw_filters::text[sw_custfltr::main]);
for (int x = 1; x <= sw_custfltr::numother; x++)
{
stream_format(cinfo, "Other filter = %s\n", sw_filters::text[sw_custfltr::other[x]]);
util::stream_format(cinfo, "Other filter = %s\n", sw_filters::text[sw_custfltr::other[x]]);
if (sw_custfltr::other[x] == UI_SW_PUBLISHERS)
stream_format(cinfo, " Manufacturer filter = %s\n", m_filter.publisher.ui[sw_custfltr::mnfct[x]]);
util::stream_format(cinfo, " Manufacturer filter = %s\n", m_filter.publisher.ui[sw_custfltr::mnfct[x]]);
else if (sw_custfltr::other[x] == UI_SW_LIST)
stream_format(cinfo, " Software List filter = %s\n", m_filter.swlist.name[sw_custfltr::list[x]]);
util::stream_format(cinfo, " Software List filter = %s\n", m_filter.swlist.name[sw_custfltr::list[x]]);
else if (sw_custfltr::other[x] == UI_SW_YEARS)
stream_format(cinfo, " Year filter = %s\n", m_filter.year.ui[sw_custfltr::year[x]]);
util::stream_format(cinfo, " Year filter = %s\n", m_filter.year.ui[sw_custfltr::year[x]]);
else if (sw_custfltr::other[x] == UI_SW_TYPE)
stream_format(cinfo, " Type filter = %s\n", m_filter.type.ui[sw_custfltr::type[x]]);
util::stream_format(cinfo, " Type filter = %s\n", m_filter.type.ui[sw_custfltr::type[x]]);
else if (sw_custfltr::other[x] == UI_SW_REGION)
stream_format(cinfo, " Region filter = %s\n", m_filter.region.ui[sw_custfltr::region[x]]);
util::stream_format(cinfo, " Region filter = %s\n", m_filter.region.ui[sw_custfltr::region[x]]);
}
file.puts(cinfo.str().c_str());
file.close();

View File

@ -42,12 +42,12 @@ void ui_menu_device_config::populate()
std::ostringstream str;
device_t *dev;
stream_format(str, "[This option is%s currently mounted in the running system]\n\n", m_mounted ? "" : " NOT");
stream_format(str, "Option: %s\n", m_option->name());
util::stream_format(str, "[This option is%s currently mounted in the running system]\n\n", m_mounted ? "" : " NOT");
util::stream_format(str, "Option: %s\n", m_option->name());
dev = const_cast<machine_config &>(machine().config()).device_add(&machine().config().root_device(), m_option->name(), m_option->devtype(), 0);
stream_format(str, "Device: %s\n", dev->name());
util::stream_format(str, "Device: %s\n", dev->name());
if (!m_mounted)
str << "\nIf you select this option, the following items will be enabled:\n";
else
@ -80,16 +80,16 @@ void ui_menu_device_config::populate()
// if more than one, prepend a #x in front of the CPU name
if (count > 1)
stream_format(str, " %d" UTF8_MULTIPLY, count);
util::stream_format(str, " %d" UTF8_MULTIPLY, count);
else
str << " ";
str << name;
// display clock in kHz or MHz
if (clock >= 1000000)
stream_format(str, " %d.%06d" UTF8_NBSP "MHz\n", clock / 1000000, clock % 1000000);
util::stream_format(str, " %d.%06d" UTF8_NBSP "MHz\n", clock / 1000000, clock % 1000000);
else
stream_format(str, " %d.%03d" UTF8_NBSP "kHz\n", clock / 1000, clock % 1000);
util::stream_format(str, " %d.%03d" UTF8_NBSP "kHz\n", clock / 1000, clock % 1000);
}
}
@ -100,7 +100,7 @@ void ui_menu_device_config::populate()
str << "* Video:\n";
for (screen_device *screen = scriter.first(); screen != nullptr; screen = scriter.next())
{
stream_format(str, " Screen '%s': ", screen->tag());
util::stream_format(str, " Screen '%s': ", screen->tag());
if (screen->screen_type() == SCREEN_TYPE_VECTOR)
str << "Vector\n";
@ -108,7 +108,7 @@ void ui_menu_device_config::populate()
{
const rectangle &visarea = screen->visible_area();
stream_format(str, "%d " UTF8_MULTIPLY " %d (%s) %f" UTF8_NBSP "Hz\n",
util::stream_format(str, "%d " UTF8_MULTIPLY " %d (%s) %f" UTF8_NBSP "Hz\n",
visarea.width(), visarea.height(),
(machine().system().flags & ORIENTATION_SWAP_XY) ? "V" : "H",
ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds()));
@ -138,7 +138,7 @@ void ui_menu_device_config::populate()
}
// if more than one, prepend a #x in front of the CPU name
if (count > 1)
stream_format(str," %d" UTF8_MULTIPLY, count);
util::stream_format(str," %d" UTF8_MULTIPLY, count);
else
str << " ";
str << sound->device().name();
@ -146,9 +146,9 @@ void ui_menu_device_config::populate()
// display clock in kHz or MHz
int clock = sound->device().clock();
if (clock >= 1000000)
stream_format(str," %d.%06d" UTF8_NBSP "MHz\n", clock / 1000000, clock % 1000000);
util::stream_format(str," %d.%06d" UTF8_NBSP "MHz\n", clock / 1000000, clock % 1000000);
else if (clock != 0)
stream_format(str," %d.%03d" UTF8_NBSP "kHz\n", clock / 1000, clock % 1000);
util::stream_format(str," %d.%03d" UTF8_NBSP "kHz\n", clock / 1000, clock % 1000);
else
str << '\n';
}
@ -176,7 +176,7 @@ void ui_menu_device_config::populate()
}
if (bios)
stream_format(str, "* BIOS settings:\n %d options [default: %s]\n", bios, bios_str.c_str());
util::stream_format(str, "* BIOS settings:\n %d options [default: %s]\n", bios, bios_str.c_str());
}
int input = 0, input_mj = 0, input_hana = 0, input_gamble = 0, input_analog = 0, input_adjust = 0;
@ -216,7 +216,7 @@ void ui_menu_device_config::populate()
{
if (setting->value() == field->defvalue())
{
stream_format(dips_opt, " [default: %s]\n", setting->name());
util::stream_format(dips_opt, " [default: %s]\n", setting->name());
break;
}
}
@ -229,7 +229,7 @@ void ui_menu_device_config::populate()
{
if (setting->value() == field->defvalue())
{
stream_format(confs_opt, " [default: %s]\n", setting->name());
util::stream_format(confs_opt, " [default: %s]\n", setting->name());
break;
}
}
@ -243,28 +243,28 @@ void ui_menu_device_config::populate()
if (input + input_mj + input_hana + input_gamble + input_analog + input_adjust + input_keypad + input_keyboard)
str << "* Input device(s):\n";
if (input)
stream_format(str, " User inputs [%d inputs]\n", input);
util::stream_format(str, " User inputs [%d inputs]\n", input);
if (input_mj)
stream_format(str, " Mahjong inputs [%d inputs]\n", input_mj);
util::stream_format(str, " Mahjong inputs [%d inputs]\n", input_mj);
if (input_hana)
stream_format(str, " Hanafuda inputs [%d inputs]\n", input_hana);
util::stream_format(str, " Hanafuda inputs [%d inputs]\n", input_hana);
if (input_gamble)
stream_format(str, " Gambling inputs [%d inputs]\n", input_gamble);
util::stream_format(str, " Gambling inputs [%d inputs]\n", input_gamble);
if (input_analog)
stream_format(str, " Analog inputs [%d inputs]\n", input_analog);
util::stream_format(str, " Analog inputs [%d inputs]\n", input_analog);
if (input_adjust)
stream_format(str, " Adjuster inputs [%d inputs]\n", input_adjust);
util::stream_format(str, " Adjuster inputs [%d inputs]\n", input_adjust);
if (input_keypad)
stream_format(str, " Keypad inputs [%d inputs]\n", input_keypad);
util::stream_format(str, " Keypad inputs [%d inputs]\n", input_keypad);
if (input_keyboard)
stream_format(str, " Keyboard inputs [%d inputs]\n", input_keyboard);
util::stream_format(str, " Keyboard inputs [%d inputs]\n", input_keyboard);
image_interface_iterator imgiter(*dev);
if (imgiter.count() > 0)
{
str << "* Media Options:\n";
for (const device_image_interface *imagedev = imgiter.first(); imagedev != nullptr; imagedev = imgiter.next())
stream_format(str, " %s [tag: %s]\n", imagedev->image_type_name(), imagedev->device().tag());
util::stream_format(str, " %s [tag: %s]\n", imagedev->image_type_name(), imagedev->device().tag());
}
slot_interface_iterator slotiter(*dev);
@ -272,7 +272,7 @@ void ui_menu_device_config::populate()
{
str << "* Slot Options:\n";
for (const device_slot_interface *slot = slotiter.first(); slot != nullptr; slot = slotiter.next())
stream_format(str, " %s [default: %s]\n", slot->device().tag(), slot->default_option() ? slot->default_option() : "----");
util::stream_format(str, " %s [default: %s]\n", slot->device().tag(), slot->default_option() ? slot->default_option() : "----");
}
if ((execiter.count() + scriter.count() + snditer.count() + imgiter.count() + slotiter.count() + bios + dips + confs

View File

@ -437,17 +437,17 @@ void favorite_manager::save_favorite_games()
text << elem.parentname << '\n';
text << elem.year << '\n';
text << elem.publisher << '\n';
stream_format(text, "%d\n", elem.supported);
util::stream_format(text, "%d\n", elem.supported);
text << elem.part << '\n';
stream_format(text, "%s\n", elem.driver->name);
util::stream_format(text, "%s\n", elem.driver->name);
text << elem.listname << '\n';
text << elem.interface << '\n';
text << elem.instance << '\n';
stream_format(text, "%d\n", elem.startempty);
util::stream_format(text, "%d\n", elem.startempty);
text << elem.parentlongname << '\n';
text << elem.usage << '\n';
text << elem.devicetype << '\n';
stream_format(text, "%d\n", elem.available);
util::stream_format(text, "%d\n", elem.available);
}
file.puts(text.str().c_str());
file.close();

View File

@ -236,13 +236,13 @@ void ui_menu_bookkeeping::populate()
/* show total time first */
if (prevtime.seconds() >= (60 * 60))
stream_format(tempstring, _("Uptime: %1$d:%2$02d:%3$02d\n\n"), prevtime.seconds() / (60 * 60), (prevtime.seconds() / 60) % 60, prevtime.seconds() % 60);
util::stream_format(tempstring, _("Uptime: %1$d:%2$02d:%3$02d\n\n"), prevtime.seconds() / (60 * 60), (prevtime.seconds() / 60) % 60, prevtime.seconds() % 60);
else
stream_format(tempstring, _("Uptime: %1$d:%2$02d\n\n"), (prevtime.seconds() / 60) % 60, prevtime.seconds() % 60);
util::stream_format(tempstring, _("Uptime: %1$d:%2$02d\n\n"), (prevtime.seconds() / 60) % 60, prevtime.seconds() % 60);
/* show tickets at the top */
if (tickets > 0)
stream_format(tempstring, _("Tickets dispensed: %1$d\n\n"), tickets);
util::stream_format(tempstring, _("Tickets dispensed: %1$d\n\n"), tickets);
/* loop over coin counters */
for (ctrnum = 0; ctrnum < COIN_COUNTERS; ctrnum++)
@ -252,7 +252,7 @@ void ui_menu_bookkeeping::populate()
/* display the coin counter number */
/* display how many coins */
/* display whether or not we are locked out */
stream_format(tempstring,
util::stream_format(tempstring,
(count == 0) ? _("Coin %1$c: NA%3$s\n") : _("Coin %1$c: %2$d%3$s\n"),
ctrnum + 'A',
count,
@ -767,7 +767,7 @@ void ui_menu_export::handle()
// iterate through drivers and output the info
while (drvlist.next())
if ((drvlist.driver().flags & MACHINE_NO_STANDALONE) == 0)
stream_format(buffer, "%-18s\"%s\"\n", drvlist.driver().name, drvlist.driver().description);
util::stream_format(buffer, "%-18s\"%s\"\n", drvlist.driver().name, drvlist.driver().description);
file.puts(buffer.str().c_str());
file.close();
machine().popmessage(_("%s.txt saved under ui folder."), filename.c_str());

View File

@ -1469,13 +1469,13 @@ void ui_menu_select_game::general_info(const game_driver *driver, std::string &b
{
std::ostringstream str;
stream_format(str, _("Romset: %1$-.100s\n"), driver->name);
stream_format(str, _("Year: %1$s\n"), driver->year);
stream_format(str, _("Manufacturer: %1$-.100s\n"), driver->manufacturer);
util::stream_format(str, _("Romset: %1$-.100s\n"), driver->name);
util::stream_format(str, _("Year: %1$s\n"), driver->year);
util::stream_format(str, _("Manufacturer: %1$-.100s\n"), driver->manufacturer);
int cloneof = driver_list::non_bios_clone(*driver);
if (cloneof != -1)
stream_format(str, _("Driver is Clone of: %1$-.100s\n"), driver_list::driver(cloneof).description);
util::stream_format(str, _("Driver is Clone of: %1$-.100s\n"), driver_list::driver(cloneof).description);
else
str << _("Driver is Parent\n");
@ -1502,14 +1502,14 @@ void ui_menu_select_game::general_info(const game_driver *driver, std::string &b
else
str << _("Sound: OK\n");
stream_format(str, _("Driver is Skeleton: %1$s\n"), ((driver->flags & MACHINE_IS_SKELETON) ? _("Yes") : _("No")));
stream_format(str, _("Game is Mechanical: %1$s\n"), ((driver->flags & MACHINE_MECHANICAL) ? _("Yes") : _("No")));
stream_format(str, _("Requires Artwork: %1$s\n"), ((driver->flags & MACHINE_REQUIRES_ARTWORK) ? _("Yes") : _("No")));
stream_format(str, _("Requires Clickable Artwork: %1$s\n"), ((driver->flags & MACHINE_CLICKABLE_ARTWORK) ? _("Yes") : _("No")));
stream_format(str, _("Support Cocktail: %1$s\n"), ((driver->flags & MACHINE_NO_COCKTAIL) ? _("Yes") : _("No")));
stream_format(str, _("Driver is Bios: %1$s\n"), ((driver->flags & MACHINE_IS_BIOS_ROOT) ? _("Yes") : _("No")));
stream_format(str, _("Support Save: %1$s\n"), ((driver->flags & MACHINE_SUPPORTS_SAVE) ? _("Yes") : _("No")));
stream_format(str, _("Screen Orentation: %1$s\n"), ((driver->flags & ORIENTATION_SWAP_XY) ? _("Vertical") : _("Horizontal")));
util::stream_format(str, _("Driver is Skeleton: %1$s\n"), ((driver->flags & MACHINE_IS_SKELETON) ? _("Yes") : _("No")));
util::stream_format(str, _("Game is Mechanical: %1$s\n"), ((driver->flags & MACHINE_MECHANICAL) ? _("Yes") : _("No")));
util::stream_format(str, _("Requires Artwork: %1$s\n"), ((driver->flags & MACHINE_REQUIRES_ARTWORK) ? _("Yes") : _("No")));
util::stream_format(str, _("Requires Clickable Artwork: %1$s\n"), ((driver->flags & MACHINE_CLICKABLE_ARTWORK) ? _("Yes") : _("No")));
util::stream_format(str, _("Support Cocktail: %1$s\n"), ((driver->flags & MACHINE_NO_COCKTAIL) ? _("Yes") : _("No")));
util::stream_format(str, _("Driver is Bios: %1$s\n"), ((driver->flags & MACHINE_IS_BIOS_ROOT) ? _("Yes") : _("No")));
util::stream_format(str, _("Support Save: %1$s\n"), ((driver->flags & MACHINE_SUPPORTS_SAVE) ? _("Yes") : _("No")));
util::stream_format(str, _("Screen Orentation: %1$s\n"), ((driver->flags & ORIENTATION_SWAP_XY) ? _("Vertical") : _("Horizontal")));
bool found = false;
for (const rom_entry *rom = driver->rom; !ROMENTRY_ISEND(rom); ++rom)
if (ROMENTRY_ISREGION(rom) && ROMREGION_ISDISKDATA(rom))
@ -1517,7 +1517,7 @@ void ui_menu_select_game::general_info(const game_driver *driver, std::string &b
found = true;
break;
}
stream_format(str, _("Requires CHD: %1$s\n"), found ? _("Yes") : _("No"));
util::stream_format(str, _("Requires CHD: %1$s\n"), found ? _("Yes") : _("No"));
// audit the game first to see if we're going to work
if (machine().ui().options().info_audit())

View File

@ -1189,7 +1189,7 @@ std::string &ui_manager::game_info_astring(std::string &str)
std::ostringstream buf;
// print description, manufacturer, and CPU:
stream_format(buf, _("%1$s\n%2$s %3$s\nDriver: %4$s\n\nCPU:\n"),
util::stream_format(buf, _("%1$s\n%2$s %3$s\nDriver: %4$s\n\nCPU:\n"),
machine().system().description,
machine().system().year,
machine().system().manufacturer,
@ -1218,7 +1218,7 @@ std::string &ui_manager::game_info_astring(std::string &str)
// if more than one, prepend a #x in front of the CPU name
// display clock in kHz or MHz
stream_format(buf,
util::stream_format(buf,
(count > 1) ? "%1$d" UTF8_MULTIPLY "%2$s %3$d.%4$0*5$d%6$s\n" : "%2$s %3$d.%4$0*5$d%6$s\n",
count,
name,
@ -1255,7 +1255,7 @@ std::string &ui_manager::game_info_astring(std::string &str)
// if more than one, prepend a #x in front of the CPU name
// display clock in kHz or MHz
int clock = sound->device().clock();
stream_format(buf,
util::stream_format(buf,
(count > 1)
? ((clock != 0) ? "%1$d" UTF8_MULTIPLY "%2$s %3$d.%4$0*5$d%6$s\n" : "%1$d" UTF8_MULTIPLY "%2$s\n")
: ((clock != 0) ? "%2$s %3$d.%4$0*5$d%6$s\n" : "%2$s\n"),
@ -1289,7 +1289,7 @@ std::string &ui_manager::game_info_astring(std::string &str)
ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds()));
}
stream_format(buf,
util::stream_format(buf,
(scrcount > 1) ? _("%1$s: %2$s\n") : _("%2$s\n"),
slider_get_screen_desc(*screen), detail);
}

View File

@ -247,7 +247,7 @@ int get_font_rows(running_machine *machine = nullptr);
//-------------------------------------------------
template <typename Format, typename... Params>
void ui_manager::popup_time(int seconds, Format &&fmt, Params &&... args)
inline void ui_manager::popup_time(int seconds, Format &&fmt, Params &&... args)
{
// extract the text
messagebox_poptext = string_format(std::forward<Format>(fmt), std::forward<Params>(args)...);

View File

@ -280,15 +280,15 @@ std::string video_manager::speed_text()
// if we're auto frameskipping, display that plus the level
else if (effective_autoframeskip())
stream_format(str, "auto%2d/%d", effective_frameskip(), MAX_FRAMESKIP);
util::stream_format(str, "auto%2d/%d", effective_frameskip(), MAX_FRAMESKIP);
// otherwise, just display the frameskip plus the level
else
stream_format(str, "skip %d/%d", effective_frameskip(), MAX_FRAMESKIP);
util::stream_format(str, "skip %d/%d", effective_frameskip(), MAX_FRAMESKIP);
// append the speed for all cases except paused
if (!paused)
stream_format(str, "%4d%%", (int)(100 * m_speed_percent + 0.5));
util::stream_format(str, "%4d%%", (int)(100 * m_speed_percent + 0.5));
// display the number of partial updates as well
int partials = 0;
@ -296,7 +296,7 @@ std::string video_manager::speed_text()
for (screen_device *screen = iter.first(); screen != nullptr; screen = iter.next())
partials += screen->partial_updates();
if (partials > 1)
stream_format(str, "\n%d partial updates", partials);
util::stream_format(str, "\n%d partial updates", partials);
return str.str();
}

View File

@ -15,6 +15,9 @@
#include "osdcore.h"
#include "strformat.h"
#include <string>
#include <string.h>
@ -63,8 +66,6 @@ char *core_i64_format(UINT64 value, UINT8 mindigits, bool is_octal);
char *core_i64_hex_format(UINT64 value, UINT8 mindigits);
char *core_i64_oct_format(UINT64 value, UINT8 mindigits);
#include <string>
int strvprintf(std::string &str, const char *format, va_list args);
int strcatvprintf(std::string &str, const char *format, va_list args);

View File

@ -519,7 +519,7 @@ std::string core_options::output_ini(const core_options *diff) const
{
if (num_valid_headers++)
buffer << '\n';
stream_format(buffer, "#\n# %s\n#\n", last_header);
util::stream_format(buffer, "#\n# %s\n#\n", last_header);
last_header = nullptr;
}
@ -527,9 +527,9 @@ std::string core_options::output_ini(const core_options *diff) const
if (!is_unadorned)
{
if (strchr(value, ' ') != nullptr)
stream_format(buffer, "%-25s \"%s\"\n", name, value);
util::stream_format(buffer, "%-25s \"%s\"\n", name, value);
else
stream_format(buffer, "%-25s %s\n", name, value);
util::stream_format(buffer, "%-25s %s\n", name, value);
}
}
}
@ -553,11 +553,11 @@ std::string core_options::output_help() const
{
// header: just print
if (curentry->is_header())
stream_format(buffer, "\n#\n# %s\n#\n", curentry->description());
util::stream_format(buffer, "\n#\n# %s\n#\n", curentry->description());
// otherwise, output entries for all non-deprecated items
else if (curentry->description() != nullptr)
stream_format(buffer, "-%-20s%s\n", curentry->name(), curentry->description());
util::stream_format(buffer, "-%-20s%s\n", curentry->name(), curentry->description());
}
return buffer.str();
}

View File

@ -91,6 +91,8 @@
widening or narrowing
- s/S: default stream output behaviour for argument
- p/P: cast any integer/char/bool/pointer/array to void const *
- n: store characters printed so far, produces no output, argument
must be pointer to type that std::streamoff is convertible to
- m: output of std::strerror(errno), no automatic widening or
narrowing, does not consume an argument
- %: literal %, field width applied, does not consume an argument
@ -128,13 +130,13 @@
- Out-of-range argument/width/precision position
- Inappropriate type for parameterised width/precision
- Positional width/precision specifier not terminated with $
- Inappropriate type for n conversion
Some limitations have been described in passing. Major limitations
and bugs include:
- No automatic widening/narrowing support, so no simple way to
output wide characters/strings to narrow streams/strings and vice
versa.
- No support for n conversion (store characters printed so far)
- Precision ignored for d/i/u/o/x/X conversions (should set minimum
digits to print).
- Precisoin for s/S conversion is only honoured for string-like
@ -183,7 +185,7 @@
#include <type_traits>
#include <utility>
namespace util {
namespace detail {
template <typename Character>
class format_chars
@ -221,6 +223,7 @@ public:
l = Character('l'),
L = Character('L'),
m = Character('m'),
n = Character('n'),
o = Character('o'),
p = Character('p'),
s = Character('s'),
@ -270,6 +273,7 @@ public:
l = L'l',
L = L'L',
m = L'm',
n = L'n',
o = L'o',
p = L'p',
s = L's',
@ -320,6 +324,7 @@ public:
character, // c, C
string, // s, S
pointer, // p
tell, // n
strerror, // m
percent // %
};
@ -389,6 +394,7 @@ public:
case conversion::character:
case conversion::string:
case conversion::pointer:
case conversion::tell:
case conversion::strerror:
case conversion::percent:
break;
@ -839,6 +845,9 @@ public:
case format_helper::p:
flags.set_conversion(format_flags::conversion::pointer);
break;
case format_helper::n:
flags.set_conversion(format_flags::conversion::tell);
break;
case format_helper::m:
flags.set_conversion(format_flags::conversion::strerror);
break;
@ -1256,6 +1265,39 @@ public:
}
};
template <typename T>
class format_store_integer
{
private:
template <typename U> struct is_non_const_ptr
{ static constexpr bool value = std::is_pointer<U>::value && !std::is_const<std::remove_pointer_t<U> >::value; };
template <typename U> struct is_unsigned_ptr
{ static constexpr bool value = std::is_pointer<U>::value && std::is_unsigned<std::remove_pointer_t<U> >::value; };
template <typename U> struct use_unsigned_cast
{ static constexpr bool value = is_non_const_ptr<U>::value && is_unsigned_ptr<U>::value && std::is_convertible<std::make_unsigned_t<std::streamoff>, std::remove_pointer_t<U> >::value; };
template <typename U> struct use_signed_cast
{ static constexpr bool value = is_non_const_ptr<U>::value && !use_unsigned_cast<U>::value && std::is_convertible<std::streamoff, std::remove_pointer_t<U> >::value; };
template <typename U> struct disable
{ static constexpr bool value = !use_unsigned_cast<U>::value && !use_signed_cast<U>::value; };
public:
template <typename U> static std::enable_if_t<use_unsigned_cast<U>::value, bool> apply(U const &value, std::streamoff data)
{
*value = std::remove_pointer_t<U>(std::make_unsigned_t<std::streamoff>(data));
return true;
}
template <typename U> static std::enable_if_t<use_signed_cast<U>::value, bool> apply(U const &value, std::streamoff data)
{
*value = std::remove_pointer_t<U>(std::make_signed_t<std::streamoff>(data));
return true;
}
template <typename U> static std::enable_if_t<disable<U>::value, bool> apply(U const &value, std::streamoff data)
{
assert(false); // inappropriate type for storing characters written so far
return false;
}
};
template <typename Stream>
class format_argument
{
@ -1264,6 +1306,7 @@ public:
: m_value(nullptr)
, m_output_function(nullptr)
, m_make_integer_function(nullptr)
, m_store_integer_function(nullptr)
{
}
@ -1272,15 +1315,18 @@ public:
: m_value(reinterpret_cast<void const *>(&value))
, m_output_function(&static_output<T>)
, m_make_integer_function(&static_make_integer<T>)
, m_store_integer_function(&static_store_integer<T>)
{
}
void output(Stream &str, format_flags const &flags) const { m_output_function(str, flags, m_value); }
bool make_integer(int &result) const { return m_make_integer_function(m_value, result); }
void store_integer(std::streamoff data) const { m_store_integer_function(m_value, data); }
private:
typedef void (*output_function)(Stream &str, format_flags const &flags, void const *value);
typedef bool (*make_integer_function)(void const *value, int &result);
typedef void (*store_integer_function)(void const *value, std::streamoff data);
template <typename T> static void static_output(Stream &str, format_flags const &flags, void const *value)
{
@ -1292,9 +1338,15 @@ private:
return format_make_integer<T>::apply(*reinterpret_cast<T const *>(value), result);
}
template <typename T> static void static_store_integer(void const *value, std::streamoff data)
{
format_store_integer<T>::apply(*reinterpret_cast<T const *>(value), data);
}
void const *m_value;
output_function m_output_function;
make_integer_function m_make_integer_function;
store_integer_function m_store_integer_function;
};
template <typename Stream, typename... Params>
@ -1304,7 +1356,7 @@ inline std::array<format_argument<Stream>, sizeof...(Params)> make_format_argume
}
template <typename Stream, typename Format, std::size_t Count>
void stream_format(Stream &str, Format const &fmt, std::array<format_argument<Stream>, Count> const &args)
typename Stream::off_type stream_format(Stream &str, Format const &fmt, std::array<format_argument<Stream>, Count> const &args)
{
typedef format_helper<std::remove_reference_t<Format> > format_helper;
typedef typename format_helper::iterator iterator;
@ -1334,7 +1386,8 @@ void stream_format(Stream &str, Format const &fmt, std::array<format_argument<St
std::streamsize m_width;
};
stream_preserver preserver(str);
typename Stream::pos_type const begin(str.tellp());
stream_preserver const preserver(str);
int next_pos(1);
iterator start = format_helper::begin(fmt);
for (iterator it = start; !format_helper::at_end(fmt, start); )
@ -1415,20 +1468,35 @@ void stream_format(Stream &str, Format const &fmt, std::array<format_argument<St
assert(args.size() >= unsigned(arg_pos));
if ((0 >= arg_pos) || (args.size() < unsigned(arg_pos)))
continue;
args[arg_pos - 1].output(str, flags);
if (format_flags::conversion::tell == flags.get_conversion())
{
typename Stream::pos_type const current(str.tellp());
args[arg_pos - 1].store_integer(
((typename Stream::pos_type(-1) == begin) || (typename Stream::pos_type(-1) == current))
? typename Stream::off_type(-1)
: (current - begin));
}
else
{
args[arg_pos - 1].output(str, flags);
}
start = it;
}
}
}
typename Stream::pos_type const end(str.tellp());
return ((typename Stream::pos_type(-1) == begin) || (typename Stream::pos_type(-1) == end))
? typename Stream::off_type(-1)
: (end - begin);
}
} // namespace detail
template <typename Stream, typename Format, typename... Params>
inline void stream_format(Stream &str, Format const &fmt, Params &&... args)
inline typename Stream::off_type stream_format(Stream &str, Format const &fmt, Params &&... args)
{
auto const arg_pack(detail::make_format_arguments<Stream>(std::forward<Params>(args)...));
detail::stream_format(str, fmt, arg_pack);
return detail::stream_format(str, fmt, arg_pack);
}
template <typename String = std::string, typename Format, typename... Params>
@ -1450,4 +1518,8 @@ inline String string_format(std::locale const &locale, Format const &fmt, Params
return str.str();
};
} // namespace util
using util::string_format;
#endif // __MAME_UTIL_STRFORMAT_H__

362
src/lib/util/vecstream.h Normal file
View File

@ -0,0 +1,362 @@
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
/***************************************************************************
vecstream.h
streams with vector storage
These types are useful if you want a persistent buffer for formatted
text and you need to use it like a character array or character
pointer, as you get read-only access to it without copying. The
storage is always guaranteed to be contiguous. Writing to the
stream may invalidate pointers to storage.
***************************************************************************/
#ifndef __MAME_UTIL_VECSTREAM_H__
#define __MAME_UTIL_VECSTREAM_H__
#include <cassert>
#include <ostream>
#include <streambuf>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
namespace util {
template <typename CharT, typename Traits = std::char_traits<CharT>, typename Allocator = std::allocator<CharT> >
class basic_vectorbuf : public std::basic_streambuf<CharT, Traits>
{
public:
typedef typename std::basic_streambuf<CharT, Traits>::char_type char_type;
typedef typename std::basic_streambuf<CharT, Traits>::int_type int_type;
typedef typename std::basic_streambuf<CharT, Traits>::pos_type pos_type;
typedef typename std::basic_streambuf<CharT, Traits>::off_type off_type;
typedef Allocator allocator_type;
typedef std::vector<char_type, Allocator> vector_type;
basic_vectorbuf(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_streambuf<CharT, Traits>(), m_mode(mode), m_storage(), m_threshold(nullptr)
{
setup();
}
basic_vectorbuf(vector_type const &content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_streambuf<CharT, Traits>(), m_mode(mode), m_storage(content), m_threshold(nullptr)
{
setup();
}
basic_vectorbuf(vector_type &&content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_streambuf<CharT, Traits>(), m_mode(mode), m_storage(std::move(content)), m_threshold(nullptr)
{
setup();
}
basic_vectorbuf(basic_vectorbuf const &that) : std::basic_streambuf<CharT, Traits>(that), m_mode(that.m_mode), m_storage(that.m_storage), m_threshold(nullptr)
{
adjust();
}
basic_vectorbuf(basic_vectorbuf &&that) : std::basic_streambuf<CharT, Traits>(that), m_mode(that.m_mode), m_storage(std::move(that.m_storage)), m_threshold(that.m_threshold)
{
that.clear();
}
vector_type const &vec() const
{
if (m_mode & std::ios_base::out)
{
if (this->pptr() > m_threshold) m_threshold = this->pptr();
auto const base(this->pbase());
auto const end(m_threshold - base);
if (m_storage.size() > std::make_unsigned_t<decltype(end)>(end))
{
m_storage.resize(std::make_unsigned_t<decltype(end)>(end));
assert(&m_storage[0] == base);
auto const put_offset(this->pptr() - base);
const_cast<basic_vectorbuf *>(this)->setp(base, base + put_offset);
const_cast<basic_vectorbuf *>(this)->pbump(put_offset);
}
}
return m_storage;
}
void vec(const vector_type &content)
{
m_storage = content;
setup();
}
void vec(vector_type &&content)
{
m_storage = std::move(content);
setup();
}
void clear()
{
m_storage.clear();
setup();
}
void reserve(typename vector_type::size_type size)
{
if ((m_mode & std::ios_base::out) && (m_storage.size() < size))
{
m_storage.reserve(size);
adjust();
}
}
basic_vectorbuf &operator=(basic_vectorbuf const &that)
{
std::basic_streambuf<CharT, Traits>::operator=(that);
m_mode = that.m_mode;
m_storage = that.m_storage;
m_threshold = that.m_threshold;
adjust();
return *this;
}
basic_vectorbuf &operator=(basic_vectorbuf &&that)
{
std::basic_streambuf<CharT, Traits>::operator=(that);
m_mode = that.m_mode;
m_storage = std::move(that.m_storage);
m_threshold = that.m_threshold;
that.clear();
return *this;
}
protected:
pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override
{
bool const in(which & std::ios_base::in);
bool const out(which & std::ios_base::out);
if ((!in && !out) ||
(in && out && (std::ios_base::cur == dir)) ||
(in && (!(m_mode & std::ios_base::in) || !this->gptr())) ||
(out && (!(m_mode & std::ios_base::out) || !this->pptr())))
{
return pos_type(off_type(-1));
}
maximise_egptr();
off_type const end((m_mode & std::ios_base::out) ? off_type(m_threshold - this->pbase()) : off_type(m_storage.size()));
switch (dir)
{
case std::ios_base::beg:
break;
case std::ios_base::end:
off += end;
break;
case std::ios_base::cur:
off += off_type(in ? (this->gptr() - this->eback()) : (this->pptr() - this->pbase()));
break;
default:
return pos_type(off_type(-1));
}
if ((off_type(0) > off) || (end < off) || ((m_mode & std::ios_base::app) && out && (end != off)))
return pos_type(off_type(-1));
if (in) this->setg(this->eback(), this->eback() + off, this->egptr());
if (out)
{
this->setp(this->pbase(), this->epptr());
this->pbump(off);
}
return pos_type(off);
}
virtual pos_type seekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in |std:: ios_base::out) override
{
return seekoff(off_type(pos), std::ios_base::beg, which);
}
virtual int_type underflow() override
{
if (!this->gptr()) return Traits::eof();
maximise_egptr();
return (this->gptr() < this->egptr()) ? Traits::to_int_type(*this->gptr()) : Traits::eof();
}
virtual int_type overflow(int_type ch = Traits::eof()) override
{
if (!(m_mode & std::ios_base::out)) return Traits::eof();
if (Traits::eq_int_type(ch, Traits::eof())) return Traits::not_eof(ch);
auto const put_offset(this->pptr() - this->pbase() + 1);
auto const threshold_offset((std::max)(m_threshold - this->pbase(), put_offset));
m_storage.push_back(Traits::to_char_type(ch));
m_storage.resize(m_storage.capacity());
auto const base(&m_storage[0]);
this->setp(base, base + m_storage.size());
m_threshold = base + threshold_offset;
if (m_mode & std::ios_base::in) this->setg(base, base + (this->gptr() - this->eback()), m_threshold);
this->pbump(int(put_offset));
return ch;
}
virtual int_type pbackfail(int_type ch = Traits::eof()) override
{
if (this->gptr() != this->eback())
{
if (Traits::eq_int_type(ch, Traits::eof()))
{
this->gbump(-1);
return Traits::not_eof(ch);
}
else if (Traits::eq(Traits::to_char_type(ch), this->gptr()[-1]))
{
this->gbump(-1);
return ch;
}
else if (m_mode & std::ios_base::out)
{
this->gbump(-1);
*this->gptr() = Traits::to_char_type(ch);
return ch;
}
}
return Traits::eof();
}
private:
void setup()
{
if (m_mode & std::ios_base::out)
{
auto const end(m_storage.size());
m_storage.resize(m_storage.capacity());
if (m_storage.empty())
{
m_threshold = nullptr;
this->setg(nullptr, nullptr, nullptr);
this->setp(nullptr, nullptr);
}
else
{
auto const base(&m_storage[0]);
m_threshold = base + end;
this->setp(base, base + m_storage.size());
if (m_mode & std::ios_base::in) this->setg(base, base, m_threshold);
}
if (m_mode & (std::ios_base::app | std::ios_base::ate)) this->pbump(int(unsigned(end)));
}
else if (m_storage.empty())
{
this->setg(nullptr, nullptr, nullptr);
}
else if (m_mode & std::ios_base::in)
{
auto const base(&m_storage[0]);
this->setg(base, base, base + m_storage.size());
}
}
void adjust()
{
auto const put_offset(this->pptr() - this->pbase());
auto const get_offset(this->gptr() - this->eback());
setup();
if (m_mode & std::ios_base::out)
{
this->pbump(int(put_offset));
m_threshold = this->pptr();
if (m_mode & std::ios_base::in)
{
auto const base(&m_storage[0]);
this->setg(base, base + get_offset, m_threshold);
}
}
else if (m_mode & std::ios_base::in)
{
this->gbump(int(get_offset));
}
}
void maximise_egptr()
{
if (m_mode & std::ios_base::out)
{
if (m_threshold < this->pptr()) m_threshold = this->pptr();
if ((m_mode & std::ios_base::in) && (this->egptr() < m_threshold)) this->setg(this->eback(), this->gptr(), m_threshold);
}
}
std::ios_base::openmode m_mode;
mutable vector_type m_storage;
mutable CharT *m_threshold;
};
template <typename CharT, typename Traits = std::char_traits<CharT>, typename Allocator = std::allocator<CharT> >
class basic_ivectorstream : public std::basic_istream<CharT, Traits>
{
public:
typedef typename basic_vectorbuf<CharT, Traits, Allocator>::vector_type vector_type;
basic_ivectorstream(std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream<CharT, Traits>(&m_rdbuf), m_rdbuf(mode) { }
basic_ivectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { }
basic_ivectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { }
basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return reinterpret_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_istream<CharT, Traits>::rdbuf()); }
vector_type const &vec() const { return rdbuf()->vec(); }
void vec(const vector_type &content) { rdbuf()->vec(content); }
void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); }
void clear() { rdbuf()->clear(); }
private:
basic_vectorbuf<CharT, Traits, Allocator> m_rdbuf;
};
template <typename CharT, typename Traits = std::char_traits<CharT>, typename Allocator = std::allocator<CharT> >
class basic_ovectorstream : public std::basic_ostream<CharT, Traits>
{
public:
typedef typename basic_vectorbuf<CharT, Traits, Allocator>::vector_type vector_type;
basic_ovectorstream(std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream<CharT, Traits>(&m_rdbuf), m_rdbuf(mode) { }
basic_ovectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { }
basic_ovectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { }
basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return reinterpret_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_ostream<CharT, Traits>::rdbuf()); }
vector_type const &vec() const { return rdbuf()->vec(); }
void vec(const vector_type &content) { rdbuf()->vec(content); }
void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); }
void clear() { rdbuf()->clear(); }
void reserve(typename vector_type::size_type size) { rdbuf->reserve(size); }
private:
basic_vectorbuf<CharT, Traits, Allocator> m_rdbuf;
};
template <typename CharT, typename Traits = std::char_traits<CharT>, typename Allocator = std::allocator<CharT> >
class basic_vectorstream : public std::basic_iostream<CharT, Traits>
{
public:
typedef typename basic_vectorbuf<CharT, Traits, Allocator>::vector_type vector_type;
basic_vectorstream(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream<CharT, Traits>(&m_rdbuf), m_rdbuf(mode) { }
basic_vectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { }
basic_vectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { }
basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return reinterpret_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_iostream<CharT, Traits>::rdbuf()); }
vector_type const &vec() const { return rdbuf()->vec(); }
void vec(const vector_type &content) { rdbuf()->vec(content); }
void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); }
void clear() { rdbuf()->clear(); }
void reserve(typename vector_type::size_type size) { rdbuf->reserve(size); }
private:
basic_vectorbuf<CharT, Traits, Allocator> m_rdbuf;
};
typedef basic_ivectorstream<char> ivectorstream;
typedef basic_ivectorstream<wchar_t> wivectorstream;
typedef basic_ovectorstream<char> ovectorstream;
typedef basic_ovectorstream<wchar_t> wovectorstream;
typedef basic_vectorstream<char> vectorstream;
typedef basic_vectorstream<wchar_t> wvectorstream;
} // namespace util
#endif // __MAME_UTIL_VECSTREAM_H__

View File

@ -307,7 +307,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(kcgd_state::scanline_callback)
offset = BIT(m_video.status, KCGD_STATUS_PAGE) ? (KCGD_PAGE_1 >> 1) : (KCGD_PAGE_0 >> 1);
DBG_LOG(2,"scanline_cb", ("frame %" I64FMT "d y %.3d page %d offset %04X *offset %04X\n",
DBG_LOG(2,"scanline_cb", ("frame %d y %.3d page %d offset %04X *offset %04X\n",
m_screen->frame_number(), BIT(m_video.status, KCGD_STATUS_PAGE),
y, offset + y, m_videoram[offset + y]));

View File

@ -243,7 +243,7 @@ INPUT_PORTS_END
/* Start it up */
void hk68v10_state::machine_start ()
{
LOG (("%" I64FMT "d %s\n", m_maincpu->total_cycles(), __func__));
LOG (("%d %s\n", m_maincpu->total_cycles(), __func__));
/* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */
m_sysrom = (UINT16*)(memregion ("maincpu")->base () + 0x0fc0000);
@ -257,7 +257,7 @@ void hk68v10_state::machine_start ()
*/
void hk68v10_state::machine_reset ()
{
LOG (("%" I64FMT "d %s\n", m_maincpu->total_cycles(), __func__));
LOG (("%d %s\n", m_maincpu->total_cycles(), __func__));
/* Reset pointer to bootvector in ROM for bootvector handler bootvect_r */
if (m_sysrom == &m_sysram[0]) /* Condition needed because memory map is not setup first time */

View File

@ -1619,7 +1619,7 @@ WRITE64_MEMBER(model3_state::model3_sys_w)
}
else
{
logerror("Unknown 0x18/8 write %" I64FMT "x mask %" I64FMT"x\n", data, mem_mask);
logerror("Unknown 0x18/8 write %x mask %x\n", data, mem_mask);
}
break;
case 0x08/8:

View File

@ -974,7 +974,7 @@ bool apollo_ni::call_load()
UINT64 size = length();
if (size != 32)
{
CLOG(("apollo_ni::call_load: %s has unexpected file size %" I64FMT "d", filename(), size));
CLOG(("apollo_ni::call_load: %s has unexpected file size %d", filename(), size));
}
else
{

View File

@ -53,8 +53,8 @@ static void log_quickload(running_machine &machine, const char *type, UINT32 sta
state->logerror("Loading %04X bytes of RAM at %04X\n", length, start);
stream_format(tempstring,"Quickload type: %s Length: %d bytes\n", type, length);
stream_format(tempstring,"Start: 0x%04X End: 0x%04X Exec: ", start, start + length - 1);
util::stream_format(tempstring, "Quickload type: %s Length: %d bytes\n", type, length);
util::stream_format(tempstring, "Start: 0x%04X End: 0x%04X Exec: ", start, start + length - 1);
state->logerror("Quickload loaded.\n");
if (!core_stricmp(exec_format, EXEC_NA))
@ -64,10 +64,10 @@ static void log_quickload(running_machine &machine, const char *type, UINT32 sta
state->logerror("Execution can resume with ");
state->logerror(exec_format, exec);
state->logerror("\n");
stream_format(tempstring,exec_format, exec);
util::stream_format(tempstring, exec_format, exec);
}
machine.ui().popup_time(10, "%s", tempstring.str().c_str());
machine.ui().popup_time(10, "%s", tempstring.str());
}
/*******************************************************************

View File

@ -2698,7 +2698,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
}
}
else {
machine().logerror("Unsupported primitive %d for method 0x1810\n", primitive_type);
machine().logerror("Unsupported primitive %d for method 0x1810\n", int(primitive_type));
}
countlen--;
}
@ -2845,7 +2845,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
}
}
else {
machine().logerror("Unsupported primitive %d for method 0x1800/8\n", primitive_type);
machine().logerror("Unsupported primitive %d for method 0x1800/8\n", int(primitive_type));
countlen = 0;
}
while (countlen > 0) {
@ -3025,7 +3025,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
}
}
else {
machine().logerror("Unsupported primitive %d for method 0x1818\n", primitive_type);
machine().logerror("Unsupported primitive %d for method 0x1818\n", int(primitive_type));
countlen = 0;
}
}
@ -3164,7 +3164,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
bytespixel_rendertarget = 1;
break;
default:
machine().logerror("Unknown render target color format %d\n\r", colorformat_rendertarget);
machine().logerror("Unknown render target color format %d\n\r", int(colorformat_rendertarget));
bytespixel_rendertarget = 4;
break;
}
@ -3174,7 +3174,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
pitch_rendertarget=data & 0xffff;
pitch_depthbuffer=(data >> 16) & 0xffff;
#ifdef LOG_NV2A
printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer);
printf("Pitch color %04X zbuffer %04X\n\r", pitch_rendertarget, pitch_depthbuffer);
#endif
countlen--;
}

View File

@ -549,7 +549,7 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri
{
// start with the line number
dstline.str("");
stream_format(dstline, "<span class=\"linenum\">%5d</span>&nbsp;&nbsp;", linenum++);
util::stream_format(dstline, "<span class=\"linenum\">%5d</span>&nbsp;&nbsp;", linenum++);
// iterate over characters in the source line
bool escape = false;
@ -569,7 +569,7 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri
{
if (!in_comment && ch == comment_start[0] && strncmp(srcptr - 1, comment_start, strlen(comment_start)) == 0)
{
stream_format(dstline, "<span class=\"comment\">%s", comment_start_esc);
util::stream_format(dstline, "<span class=\"comment\">%s", comment_start_esc);
curcol += strlen(comment_start);
srcptr += strlen(comment_start) - 1;
ch = 0;
@ -577,7 +577,7 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri
}
else if (in_comment && ch == comment_end[0] && strncmp(srcptr - 1, comment_end, strlen(comment_end)) == 0)
{
stream_format(dstline, "%s</span>", comment_end_esc);
util::stream_format(dstline, "%s</span>", comment_end_esc);
curcol += strlen(comment_end);
srcptr += strlen(comment_end) - 1;
ch = 0;
@ -588,7 +588,7 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri
// track whether or not we are within an inline (C++-style) comment
if (!in_quotes && !in_comment && !in_inline_comment && ch == comment_inline[0] && strncmp(srcptr - 1, comment_inline, strlen(comment_inline)) == 0)
{
stream_format(dstline, "<span class=\"comment\">%s", comment_inline_esc);
util::stream_format(dstline, "<span class=\"comment\">%s", comment_inline_esc);
curcol += strlen(comment_inline);
srcptr += strlen(comment_inline) - 1;
ch = 0;
@ -612,7 +612,7 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri
for (curtoken = token_table; curtoken->token != nullptr; curtoken++)
if (strncmp(srcptr - 1, curtoken->token, toklength) == 0 && strlen(curtoken->token) == toklength)
{
stream_format(dstline, "<span class=\"%s\">%s</span>", curtoken->color, curtoken->token);
util::stream_format(dstline, "<span class=\"%s\">%s</span>", curtoken->color, curtoken->token);
curcol += strlen(curtoken->token);
srcptr += strlen(curtoken->token) - 1;
ch = 0;
@ -644,7 +644,7 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri
if (!in_comment && !in_inline_comment && !in_quotes && (ch == '"' || ch == '\''))
{
if (color_quotes)
stream_format(dstline, "<span class=\"string\">%c", ch);
util::stream_format(dstline, "<span class=\"string\">%c", ch);
else
dstline.put(ch);
in_quotes = true;
@ -660,7 +660,7 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri
std::string target;
if (find_include_file(target, srcrootlen, dstrootlen, srcfile, dstfile, filename))
{
stream_format(dstline, "<a href=\"%s\">", target.c_str());
util::stream_format(dstline, "<a href=\"%s\">", target.c_str());
quotes_are_linked = true;
}
}
@ -673,7 +673,7 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri
if (quotes_are_linked)
dstline << "</a>";
if (color_quotes)
stream_format(dstline, "%c</span>", ch);
util::stream_format(dstline, "%c</span>", ch);
else
dstline.put(ch);
in_quotes = false;