diff options
| author | 2016-09-07 14:27:35 +0200 | |
|---|---|---|
| committer | 2016-09-07 14:27:35 +0200 | |
| commit | fa4b5bdee60e7aa95b435f0a1198a314de815fb1 (patch) | |
| tree | 2ee3ba6bfc502db21c8454eb4648fc0219419568 | |
| parent | 42ab14dc64fec61d27cd9c6da7d8e7bb8e5f24f1 (diff) | |
| parent | 9d101cad6a9834c5645f20c152466267ab13845f (diff) | |
Merge pull request #1368 from cracyc/lua_dats
Move UI dats to lua plugin
31 files changed, 1742 insertions, 1268 deletions
diff --git a/plugins/data/button_char.lua b/plugins/data/button_char.lua new file mode 100644 index 00000000000..cee756c2603 --- /dev/null +++ b/plugins/data/button_char.lua @@ -0,0 +1,245 @@ +local default_text = +{ + -- Alphabetic Buttons (NeoGeo): A~D,H,Z + ["A"] = 1, -- BTN_A + ["B"] = 2, -- BTN_B + ["C"] = 3, -- BTN_C + ["D"] = 4, -- BTN_D + ["H"] = 8, -- BTN_H + ["Z"] = 26, -- BTN_Z + -- Numerical Buttons (Capcom): 1~10 + ["a"] = 27, -- BTN_1 + ["b"] = 28, -- BTN_2 + ["c"] = 29, -- BTN_3 + ["d"] = 30, -- BTN_4 + ["e"] = 31, -- BTN_5 + ["f"] = 32, -- BTN_6 + ["g"] = 33, -- BTN_7 + ["h"] = 34, -- BTN_8 + ["i"] = 35, -- BTN_9 + ["j"] = 36, -- BTN_10 + -- Directions of Arrow, Joystick Ball + ["+"] = 39, -- BTN_+ + ["."] = 40, -- DIR_... + ["1"] = 41, -- DIR_1 + ["2"] = 42, -- DIR_2 + ["3"] = 43, -- DIR_3 + ["4"] = 44, -- DIR_4 + ["5"] = 45, -- Joystick Ball + ["6"] = 46, -- DIR_6 + ["7"] = 47, -- DIR_7 + ["8"] = 48, -- DIR_8 + ["9"] = 49, -- DIR_9 + ["N"] = 50, -- DIR_N + -- Special Buttons + ["S"] = 51, -- BTN_START + ["P"] = 53, -- BTN_PUNCH + ["K"] = 54, -- BTN_KICK + ["G"] = 55, -- BTN_GUARD + -- Composition of Arrow Directions + ["!"] = 90, -- Arrow + ["k"] = 100, -- Half Circle Back + ["l"] = 101, -- Half Circle Front Up + ["m"] = 102, -- Half Circle Front + ["n"] = 103, -- Half Circle Back Up + ["o"] = 104, -- 1/4 Cir For 2 Down + ["p"] = 105, -- 1/4 Cir Down 2 Back + ["q"] = 106, -- 1/4 Cir Back 2 Up + ["r"] = 107, -- 1/4 Cir Up 2 For + ["s"] = 108, -- 1/4 Cir Back 2 Down + ["t"] = 109, -- 1/4 Cir Down 2 For + ["u"] = 110, -- 1/4 Cir For 2 Up + ["v"] = 111, -- 1/4 Cir Up 2 Back + ["w"] = 112, -- Full Clock Forward + ["x"] = 113, -- Full Clock Back + ["y"] = 114, -- Full Count Forward + ["z"] = 115, -- Full Count Back + ["L"] = 116, -- 2x Forward + ["M"] = 117, -- 2x Back + ["Q"] = 118, -- Dragon Screw Forward + ["R"] = 119, -- Dragon Screw Back + -- Big letter Text + ["^"] = 121, -- AIR + ["?"] = 122, -- DIR + ["X"] = 124, -- TAP + -- Condition of Positions + ["|"] = 125, -- Jump + ["O"] = 126, -- Hold + ["-"] = 127, -- Air + ["="] = 128, -- Squatting + ["~"] = 131, -- Charge + -- Special Character Text + ["`"] = 135, -- Small Dot + ["@"] = 136, -- Double Ball + [")"] = 137, -- Single Ball + ["("] = 138, -- Solid Ball + ["*"] = 139, -- Star + ["&"] = 140, -- Solid star + ["%"] = 141, -- Triangle + ["$"] = 142, -- Solid Triangle + ["#"] = 143, -- Double Square + ["]"] = 144, -- Single Square + ["["] = 145, -- Solid Square + ["{"] = 146, -- Down Triangle + ["}"] = 147, -- Solid Down Triangle + ["<"] = 148, -- Diamond + [">"] = 149, -- Solid Diamond +} + +local expand_text = +{ + -- Alphabetic Buttons (NeoGeo): S (Slash Button) + ["s"] = 19, -- BTN_S + -- Special Buttons + ["S"] = 52, -- BTN_SELECT + -- Multiple Punches & Kicks + ["E"] = 57, -- Light Punch + ["F"] = 58, -- Middle Punch + ["G"] = 59, -- Strong Punch + ["H"] = 60, -- Light Kick + ["I"] = 61, -- Middle Kick + ["J"] = 62, -- Strong Kick + ["T"] = 63, -- 3 Kick + ["U"] = 64, -- 3 Punch + ["V"] = 65, -- 2 Kick + ["W"] = 66, -- 2 Pick + -- Composition of Arrow Directions + ["!"] = 91, -- Continue Arrow + -- Charge of Arrow Directions + ["1"] = 92, -- Charge DIR_1 + ["2"] = 93, -- Charge DIR_2 + ["3"] = 94, -- Charge DIR_3 + ["4"] = 95, -- Charge DIR_4 + ["6"] = 96, -- Charge DIR_6 + ["7"] = 97, -- Charge DIR_7 + ["8"] = 98, -- Charge DIR_8 + ["9"] = 99, -- Charge DIR_9 + -- Big letter Text + ["M"] = 123, -- MAX + -- Condition of Positions + ["-"] = 129, -- Close + ["="] = 130, -- Away + ["*"] = 132, -- Serious Tap + ["?"] = 133, -- Any Button +} + +local convert_text = +{ + -- Alphabetic Buttons: A~Z + ["A-button"] = 1, -- BTN_A + ["B-button"] = 2, -- BTN_B + ["C-button"] = 3, -- BTN_C + ["D-button"] = 4, -- BTN_D + ["E-button"] = 5, -- BTN_E + ["F-button"] = 6, -- BTN_F + ["G-button"] = 7, -- BTN_G + ["H-button"] = 8, -- BTN_H + ["I-button"] = 9, -- BTN_I + ["J-button"] = 10, -- BTN_J + ["K-button"] = 11, -- BTN_K + ["L-button"] = 12, -- BTN_L + ["M-button"] = 13, -- BTN_M + ["N-button"] = 14, -- BTN_N + ["O-button"] = 15, -- BTN_O + ["P-button"] = 16, -- BTN_P + ["Q-button"] = 17, -- BTN_Q + ["R-button"] = 18, -- BTN_R + ["S-button"] = 19, -- BTN_S + ["T-button"] = 20, -- BTN_T + ["U-button"] = 21, -- BTN_U + ["V-button"] = 22, -- BTN_V + ["W-button"] = 23, -- BTN_W + ["X-button"] = 24, -- BTN_X + ["Y-button"] = 25, -- BTN_Y + ["Z-button"] = 26, -- BTN_Z + -- Special Moves and Buttons + ["decrease"] = 37, -- BTN_DEC + ["increase"] = 38, -- BTN_INC + ["BALL"] = 45, -- Joystick Ball + ["start"] = 51, -- BTN_START + ["select"] = 52, -- BTN_SELECT + ["punch"] = 53, -- BTN_PUNCH + ["kick"] = 54, -- BTN_KICK + ["guard"] = 55, -- BTN_GUARD + ["L-punch"] = 57, -- Light Punch + ["M-punch"] = 58, -- Middle Punch + ["S-punch"] = 59, -- Strong Punch + ["L-kick"] = 60, -- Light Kick + ["M-kick"] = 61, -- Middle Kick + ["S-kick"] = 62, -- Strong Kick + ["3-kick"] = 63, -- 3 Kick + ["3-punch"] = 64, -- 3 Punch + ["2-kick"] = 65, -- 2 Kick + ["2-punch"] = 66, -- 2 Pick + -- Custom Buttons and Cursor Buttons + ["custom1"] = 67, -- CUSTOM_1 + ["custom2"] = 68, -- CUSTOM_2 + ["custom3"] = 69, -- CUSTOM_3 + ["custom4"] = 70, -- CUSTOM_4 + ["custom5"] = 71, -- CUSTOM_5 + ["custom6"] = 72, -- CUSTOM_6 + ["custom7"] = 73, -- CUSTOM_7 + ["custom8"] = 74, -- CUSTOM_8 + ["up"] = 75, -- (Cursor Up) + ["down"] = 76, -- (Cursor Down) + ["left"] = 77, -- (Cursor Left) + ["right"] = 78, -- (Cursor Right) + -- Player Lever + ["lever"] = 79, -- Non Player Lever + ["nplayer"] = 80, -- Gray Color Lever + ["1player"] = 81, -- 1 Player Lever + ["2player"] = 82, -- 2 Player Lever + ["3player"] = 83, -- 3 Player Lever + ["4player"] = 84, -- 4 Player Lever + ["5player"] = 85, -- 5 Player Lever + ["6player"] = 86, -- 6 Player Lever + ["7player"] = 87, -- 7 Player Lever + ["8player"] = 88, -- 8 Player Lever + -- Composition of Arrow Directions + ["-->"] = 90, -- Arrow + ["==>"] = 91, -- Continue Arrow + ["hcb"] = 100, -- Half Circle Back + ["huf"] = 101, -- Half Circle Front Up + ["hcf"] = 102, -- Half Circle Front + ["hub"] = 103, -- Half Circle Back Up + ["qfd"] = 104, -- 1/4 Cir For 2 Down + ["qdb"] = 105, -- 1/4 Cir Down 2 Back + ["qbu"] = 106, -- 1/4 Cir Back 2 Up + ["quf"] = 107, -- 1/4 Cir Up 2 For + ["qbd"] = 108, -- 1/4 Cir Back 2 Down + ["qdf"] = 109, -- 1/4 Cir Down 2 For + ["qfu"] = 110, -- 1/4 Cir For 2 Up + ["qub"] = 111, -- 1/4 Cir Up 2 Back + ["fdf"] = 112, -- Full Clock Forward + ["fub"] = 113, -- Full Clock Back + ["fuf"] = 114, -- Full Count Forward + ["fdb"] = 115, -- Full Count Back + ["xff"] = 116, -- 2x Forward + ["xbb"] = 117, -- 2x Back + ["dsf"] = 118, -- Dragon Screw Forward + ["dsb"] = 119, -- Dragon Screw Back + -- Big letter Text + ["AIR"] = 121, -- AIR + ["DIR"] = 122, -- DIR + ["MAX"] = 123, -- MAX + ["TAP"] = 124, -- TAP + -- Condition of Positions + ["jump"] = 125, -- Jump + ["hold"] = 126, -- Hold + ["air"] = 127, -- Air + ["sit"] = 128, -- Squatting + ["close"] = 129, -- Close + ["away"] = 130, -- Away + ["charge"] = 131, -- Charge + ["tap"] = 132, -- Serious Tap + ["button"] = 133, -- Any Button +} + +local function convert_char(str) + str = str:gsub("@([a-zA-Z%-]+)", function(s) if convert_text[s] then return utf8.char(convert_text[s] + 0xe000) end return s end) + str = str:gsub("_(.)", function(s) if default_text[s] then return utf8.char(default_text[s] + 0xe000) end return s end) + str = str:gsub("%^(.)", function(s) if expand_text[s] then return utf8.char(expand_text[s] + 0xe000) end return s end) + return str +end + +return convert_char diff --git a/plugins/data/data_command.lua b/plugins/data/data_command.lua new file mode 100644 index 00000000000..a868b792c22 --- /dev/null +++ b/plugins/data/data_command.lua @@ -0,0 +1,25 @@ +local dat = {} +local info, ver + +local datread = require("data/load_dat") +datread, ver = datread.open("command.dat", nil) + +function dat.check(set, softlist) + if softlist or not datread then + return nil + end + local status + status, info = pcall(datread, "cmd", "info", set) + if not status or not info then + return nil + end + local convert = require("data/button_char") + info = "#jf\n" .. convert(info) + return "Command" +end + +function dat.get() + return info +end + +return dat diff --git a/plugins/data/data_gameinit.lua b/plugins/data/data_gameinit.lua new file mode 100644 index 00000000000..13e2489a19d --- /dev/null +++ b/plugins/data/data_gameinit.lua @@ -0,0 +1,27 @@ +local dat = {} +local ver, info + +local datread = require("data/load_dat") +datread, ver = datread.open("gameinit.dat", "# GAMEINIT.DAT") + +function dat.check(set, softlist) + if softlist or not datread then + return nil + end + local status + status, info = pcall(datread, "mame", "info", set) + if not status or not info then + return nil + end + return "Gameinit" +end + +function dat.get() + return info +end + +function dat.ver() + return ver +end + +return dat diff --git a/plugins/data/data_hiscore.lua b/plugins/data/data_hiscore.lua new file mode 100644 index 00000000000..5f1a0f70521 --- /dev/null +++ b/plugins/data/data_hiscore.lua @@ -0,0 +1,803 @@ +-- to use this get the package from http://greatstone.free.fr/hi2txt/ +-- extract the hi2txt.zip and place it in your history path + +local dat = {} +local env = {} +local output +local curset + +function dat.check(set, softlist) + if softlist then + return nil + end + local datpath + local function xml_parse() + local file = emu.file(lfs.env_replace(mame_manager:ui():options().entries.historypath:value():gsub("([^;]+)", "%1/hi2txt")), 1) + local ret = file:open(set .. ".xml") + local table + if ret then + return nil + end + datpath = file:fullpath():gsub(".zip", "/") + local data = file:read(file:size()) + data = data:match("<hi2txt>(.*)</ *hi2txt>") + local function get_tags(str, parent) + local arr = {} + while str ~= "" do + local tag, attr, stop + tag, attr, stop, str = str:match("<([%w!_%-]+) ?(.-)(/?)[ %-]->(.*)") + + if not tag then + return arr + end + if tag:sub(0, 3) ~= "!--" then + local block = {} + if stop ~= "/" then + local nest + nest, str = str:match("(.-)</ *" .. tag .. " *>(.*)") + local children = get_tags(nest, tag) + if not next(children) then + nest = nest:gsub("<!--.-%-%->", "") + nest = nest:gsub("^%s*(.-)%s*$", "%1") + block["text"] = nest + else + block = children + end + end + if attr then + for name, value in attr:gmatch("([-%w]-)=\"(.-)\"") do + block[name] = value:gsub("^(.-)$", "%1") + end + end + if not arr[tag] then + arr[tag] = {} + end + if parent == "structure" or parent == "output" or parent == "format" or parent == "loop" or parent == "concat" then + block["tag"] = tag + arr[#arr + 1] = block + elseif tag == "charset" or tag == "bitmask" then + arr[tag][block["id"]] = block + elseif tag == "case" or tag == "char" then + arr[tag][block["src"]] = block + else + arr[tag][#arr[tag] + 1] = block + end + end + end + return arr + end + return get_tags(data, "") + end + + local function parse_table(xml) + local total_size = 0 + local s = { "data = open('" .. xml.structure[1].file .. "', size)\noffset = 1\narr = {}" } + local fparam = {} + if xml.bitmask then + local bitmask = "bitmask = {" + for id, masks in pairs(xml.bitmask) do + bitmask = bitmask .. "['" .. id .. "'] = {" + for num, mask in ipairs(masks.character) do + mask = mask:gsub("( )", "") + local newmask = tonumber(mask, 2) + local shift = 0 + local count = 8 + while (newmask & 1) == 0 do + newmask = newmask >> 1 + shift = shift + 1 + end + if masks.byte-completion and masks.byte-completion == "no" then + count = 0 + while (newmask >> count) & 1 == 1 do + count = count + 1 + end + end + bitmask = bitmask .. "{ mask = " .. newmask .. ", ishift = " .. shift .. ", oshift = " .. count .. "}," + end + bitmask = bitmask .. "}," + end + s[#s + 1] = bitmask .. "}" + end + if xml.charset then + local charset = "charset = {" + for id, set in pairs(xml.charset) do + local default + charset = charset .. "['" .. id .. "'] = {" + for src, char in pairs(set.char) do + if char.default and char.default == "yes" then + default = char.dst + end + charset = charset .. "[" .. src .. "]" .. " = '" .. char.dst .. "'," + end + if default then + charset = charset .. "default = " .. default + end + charset = charset .. "}," + end + s[#s + 1] = charset .. "}" + end + + local function check_format(formstr) + local formats = {} + local ret = " function tempform(val)" + formstr = formstr:gsub(">", ">") + formstr:gsub("([^;]+)", function(s) formats[#formats + 1] = s end) + for num, form in ipairs(formats) do + local oper + local first, rest = form:match("^(.)(.*)$") + if first == "*" and tonumber(rest) then + oper = " val = val * " .. rest + elseif first == "/" and tonumber(rest) then + oper = " val = val / " .. rest + elseif first == "d" and tonumber(rest) then + oper = " val = math.floor(val / " .. rest .. ")" + elseif first == "D" and tonumber(rest) then + oper = " val = math.floor((val / " .. rest .. ") + 0.5)" + elseif first == "-" and tonumber(rest) then + oper = " val = val - " .. rest + elseif first == "+" and tonumber(rest) then + oper = " val = val + " .. rest + elseif first == "%" and tonumber(rest) then + oper = " val = val % " .. rest + elseif first == ">" and tonumber(rest) then + oper = " val = val << " .. rest + elseif first == "L" and (rest == "C" or rest == "owercase") then + oper = " val = val:lower()" + elseif first == "U" and (rest == "C" or rest == "ppercase") then + oper = " val = val:upper()" + elseif first == "C" and rest == "apitalize" then + oper = " val = val:gsub('^(.)', function(s) return s:upper() end)" + elseif first == "R" and (rest == "" or rest == "ound") then + oper = " val = math.floor(" .. var .. " + 0.5)" + elseif first == "T" then + local trim, char = rest:match("rim(L?R?)(.)$") + if trim == "L" or trim == "" then + oper = " val = val:gsub('^(" .. char .. "*)', '')" + end + if trim == "R" or trim == "" then + oper = " val = val:gsub('(" .. char .. "*)$', '')" + end + elseif first == "P" then + local pad, count, char = rest:match("ad(L?R?)(%d-)(.)$") + if pad == "L" then + oper = " val = string.rep('" .. char .. "', " .. count .. " - #val) .. val" + elseif pad == "R" then + oper = "val = val .. string.rep('" .. char .. "', " .. count .. " - #val)" + elseif pad == nil then + local prefix = rest:match("refix(.*)") + if prefix then + oper = " val = '" .. rest .. "' .. val" + end + end + elseif first == "S" then + local suffix = rest:match("uffix(.*)") + if suffix then + oper = " val = val .. '" .. rest .. "'" + end + elseif (first == "h" and rest == "exadecimal_string") or (first == "0" and rest == "x") then + oper = " val = string.format('0x%x', val)" + elseif (first == "L" and rest == "oopIndex") then + oper = " val = index" + end + if not oper then + oper = " val = format['" .. form .. "'](val, {" + for num1, colpar in ipairs(fparam[form]) do + oper = oper .. "arr['" .. colpar .. "'][i].val or arr['" .. colpar .. "'][1].val," + end + oper = oper .. "})" + end + ret = ret .. oper + end + return ret .. " return val\nend" + end + + if xml.format then + local format = { "format = {" } + for num, form in ipairs(xml.format) do + local param = {} + format[#format + 1] = "['" .. form["id"] .. "'] = " + --[[if form["input-as-subcolumns-input"] then + format[#format + 1] = "input_as_subcolumns_input = '" .. form["input-as-subcolumns-input"] .. "'," + end]]-- + format[#format + 1] = "function(val, param) " + if form["formatter"] then + format[#format + 1] = "function tempform(val) " + end + if form["apply-to"] == "char" then + format[#format + 1] = "val = val:gsub('(.)', function(val) " + end + format[#format + 1] = "local temp = val" + for num1, op in ipairs(form) do + if op.tag == "add" then + format[#format + 1] = "val = val + " .. op.text + elseif op.tag == "prefix" then + format[#format + 1] = "val = '" .. op.text .. "' .. val " + elseif op.tag == "suffix" then + format[#format + 1] = "val = val .. '" .. op.text .. "'" + elseif op.tag == "multiply" then + format[#format + 1] = "val = val * " .. op.text + elseif op.tag == "divide" then + format[#format + 1] = "val = val / " .. op.text + elseif op.tag == "sum" then + format[#format + 1] = "val = 0" + for num2, col in ipairs(op) do + param[#param + 1] = col["id"] + if col["format"] then + local colform = check_format(col["format"]) + format[#format + 1] = colform .. " val = val + tempform(val)" + else + format[#format + 1] = "val = val + param[" .. #param .. "]" + end + end + elseif op.tag == "concat" then + format[#format + 1] = "val = ''" + for num2, col in ipairs(op) do + if col["tag"] == "txt" then + format[#format + 1] = "val = val .. '" .. col["text"] .. "'" + elseif col["format"] then + param[#param + 1] = col["id"] + local n = #param + format[#format + 1] = function() return " " .. check_format(col["format"]) .. " val = val .. tempform(param[" .. n .. "])" end + else + param[#param + 1] = col["id"] + format[#format + 1] = "val = val .. param[" .. #param .. "]" + end + end + elseif op.tag == "min" then + format[#format + 1] = "val = 0x7fffffffffffffff" + for num2, col in ipairs(op) do + param[#param + 1] = col["id"] + format[#format + 1] = "val = math.min(val, param[" .. #param .. "])" + end + elseif op.tag == "max" then + format[#format + 1] = "val = 0" + for num2, col in ipairs(op) do + param[#param + 1] = col["id"] + format[#format + 1] = "val = math.max(val, param[" .. #param .. "])" + end + elseif op.tag == "pad" then + format[#format + 1] = "if type(val) == 'number' then val = tostring(val) end" + format[#format + 1] = "if #val < " .. op.max .. " then" + if op.direction == "left" then + format[#format + 1] = "val = string.rep('" .. op.text .. "', " .. op.max .. " - #val) .. val" + elseif op.direction == "right" then + format[#format + 1] = "val = val .. string.rep('" .. op.text .. "', " .. op.max .. " - #val)" + end + format[#format + 1] = "end" + elseif op.tag == "trim" then + if op.direction == "left" or op.direction == "both" then + format[#format + 1] = "val = val:gsub('^(" .. op.text .. "*)', '')" + end + if op.direction == "right" or op.direction == "both" then + format[#format + 1] = "val = val:gsub('(" .. op.text .. "*)$', '')" + end + elseif op.tag == "substract" then + format[#format + 1] = "val = val - " .. op.text + elseif op.tag == "remainder" then + format[#format + 1] = "val = val % " .. op.text + elseif op.tag == "trunc" then + format[#format + 1] = "val = math.floor(val)" + elseif op.tag == "round" then + format[#format + 1] = "val = math.floor(val + 0.5)" + elseif op.tag == "divide_trunc" then + format[#format + 1] = "val = math.floor(val / " .. op.text .. ")" + elseif op.tag == "divide_round" then + format[#format + 1] = "val = math.floor((val / " .. op.text .. ") + 0.5)" + elseif op.tag == "replace" then + format[#format + 1] = "val = val:gsub('" .. op.src .. "', '" .. op.dst .. "')" + elseif op.tag == "shift" then + format[#format + 1] = "val = val << " .. op.text + elseif op.tag == "lowercase" then + format[#format + 1] = "val = val:lower()" + elseif op.tag == "uppercase" then + format[#format + 1] = "val = val:upper()" + elseif op.tag == "capitalize" then + format[#format + 1] = "val = val:gsub('^(.)', function(s) return s:upper() end)" + elseif op.tag == "loopindex" then + param[#param + 1] = "loopindex" + format[#format + 1] = "val = param[" .. #param .. "]" + elseif op.tag == "case" then + format[#format + 1] = "val = temp" + if not tonumber(op["src"]) then + op["src"] = "'" .. op["src"] .. "'" + end + if not tonumber(op["dst"]) then + op["dst"] = "'" .. op["dst"] .. "'" + end + if op["default"] == "yes" then + format[#format + 1] = "local default = " .. op["dst"] + end + if op["operator-format"] then + format[#format + 1] = function() return " val = ".. check_format(col["operator-format"]) end + end + if not op["operator"] then + op["operator"] = "==" + else + op["operator"] = op["operator"]:gsub("<", "<") + op["operator"] = op["operator"]:gsub(">", ">") + end + format[#format + 1] = "if val " .. op["operator"] .. " " .. op["src"] .. " then" + format[#format + 1] = "val = " .. op["dst"] + if op["format"] then + format[#format + 1] = function() return " val = ".. check_format(col["operator-format"]) end + end + format[#format + 1] = "return val\n end" + end + + end + fparam[form["id"]] = param + if form["apply-to"] == "char" then + format[#format + 1] = "if default then\nreturn default\nend\nreturn val\nend)\nreturn val\nend" + else + format[#format + 1] = "if default then\nreturn default\nend\nreturn val\nend" + end + if form["formatter"] then + format[#format + 1] = "return string.format('" .. form["formatter"] .. "', tempform(val))\nend" + end + format[#format + 1] = "," + end + for num, line in ipairs(format) do + if type(line) == "string" then + s[#s + 1] = line + elseif type(line) == "function" then + s[#s + 1] = line() + end + end + s[#s + 1] = "}" + end + local function parse_elem(elem, loopelem) + local ret = 0 + if elem["tag"] == "loop" then + if elem["skip-first-bytes"] then + s[#s + 1] = "offset = offset + " .. elem["skip-first-bytes"] + end + s[#s + 1] = "for i = 1, " .. elem["count"] .. " do" + for num, elt in ipairs(elem) do + index = parse_elem(elt, elem) + end + s[#s + 1] = "end" + if elem["skip-last-bytes"] then + s[#s + 1] = "offset = offset + " .. elem["skip-last-bytes"] + end + elseif elem["tag"] == "elt" then + s[#s + 1] = "if not arr['" .. elem["id"] .. "'] then arr['" .. elem["id"] .. "'] = {} end\nelem = {}" + s[#s + 1] = "bytes = table.pack(string.unpack('" .. string.rep("c1", elem["size"]) .. "', data, offset))" + if loopelem then + total_size = total_size + elem["size"] * loopelem["count"] + else + total_size = total_size + elem["size"] + end + s[#s + 1] = "offset = table.remove(bytes)" + if elem["decoding-profile"] then + if elem["decoding-profile"] == "base-40" then + elem["src-unit-size"] = 16 + elem["base"] = "40" + elem["dst-unit-size"] = 3 + elem["ascii-offset"] = 64 + elseif elem["decoding-profile"] == "base-32" then + elem["src-unit-size"] = 16 + elem["base"] = "32" + elem["dst-unit-size"] = 3 + elem["ascii-offset"] = 64 + elseif elem["decoding-profile"] == "bcd" then + elem["endianness"] = "big-endian" + elem["nibble-skip"] = "odd" + elem["base"] = "16" + elseif elem["decoding-profile"] == "bcd-le" then + elem["endianness"] = "big-endian" + elem["nibble-skip"] = "odd" + elem["base"] = "16" + end + end + local bytedec = elem["swap-skip-order"] or "byte-swap;bit-swap;byte-skip;endianness;byte-trim;nibble-skip;bitmask" + local bytedecl = {} + bytedec:gsub("([^;]*)", function(c) bytedecl[#bytedecl + 1] = c end) + for num, func in ipairs(bytedecl) do + if elem[func] then + fixfunc = func:gsub("-", "_") + if func == "bitmask" then + s[#s + 1] = "bytes = " .. fixfunc .. "(bytes, bitmask['" .. elem[func] .. "'])" + else + s[#s + 1] = "bytes = " .. fixfunc .. "(bytes, '" .. elem[func] .. "')" + end + end + end + if elem["type"] == "int" then + s[#s + 1] = "value = string.unpack('>I' .. #bytes, table.concat(bytes))" + elem["base"] = elem["base"] or "10" + if elem["base"] == "16" then + s[#s + 1] = "value = frombcd(value)" + end + s[#s + 1] = "elem.val = value" + elseif elem["type"] == "text" then + if elem["ascii-step"] then + s[#s + 1] = "bytes = ascii_step(bytes, " .. elem["ascii-step"] .. ")" + end + if elem["ascii-offset"] then + s[#s + 1] = "bytes = ascii_offset(bytes, " .. elem["ascii-offset"] .. ")" + end + if elem["base"] then + s[#s + 1] = "bytes = basechar(bytes, " .. elem["base"] .. ")" + end + if elem["charset"] then + local charsets = {} + elem["charset"]:gsub("([^;]*)", function(s) charsets[#charsets + 1] = s return "" end) + for num, charset in pairs(charsets) do + if charset:match("^CS_") then + s[#s + 1] = "bytes = charset_conv(bytes, " .. charset .. ")" + elseif charset ~= "" then + s[#s + 1] = "bytes = charset_conv(bytes, charset['" .. charset .. "'])" + end + end + end + s[#s + 1] = "elem.val = table.concat(bytes)" + end + local index + if elem["table-index"] then + index = tonumber(elem["table-index"]) + end + if not index and loopelem then + local total = loopelem["count"] + local start = loopelem["start"] or 0 + local step = loopelem["step"] or 1 + local ref, reftype + if elem["table-index"] then + elem["table-index"]:match("([%w ]*):([%a_]*)") + end + if not elem["table-index"] or elem["table-index"] == "loop_index" then + index = "(i - 1) * " .. step .. " + " .. start + elseif elem["table-index"] == "loop_reverse_index" then + index = "(" .. total .. "- i) * " .. step .. " + " .. start + elseif elem["table-index"] == "itself" then + index = "value" + elseif elem["table-index"] == "last" then + index = "lastindex" + elseif reftype then + index = reftype .. "(arr, '" .. ref .. "')" + end + end + if index then + s[#s + 1] = "elem.index = " .. index + s[#s + 1] = "lastindex = elem.index" + end + s[#s + 1] = "arr['" .. elem["id"] .. "'][#arr['" .. elem["id"] .. "'] + 1] = elem" + end + return index + end + for num, elem in ipairs(xml.structure[1]) do + if elem["tag"] == "loop" or elem["tag"] == "elt" then + parse_elem(elem) + end + end + table.insert(s, 1, "size = " .. total_size) + + s[#s + 1] = "output = ''" + + for num1, fld in ipairs(xml.output[1]) do + if not fld["display"] or fld["display"] == "always" then + if fld["tag"] == "field" then + if not fld["src"] then + fld["src"] = fld["id"] + end + s[#s + 1] = "output = output .. '" .. fld["id"] .. " '" + s[#s + 1] = "val = arr['" .. fld["src"] .. "'][1]" + if fld["format"] then + s[#s + 1] = check_format(fld["format"]) + s[#s + 1] = "val = tempform(val)" + end + s[#s + 1] = "output = output .. val .. '\\n'" + elseif fld["tag"] == "table" then + local head = {} + local dat = {} + local loopcnt + local igncol, ignval + if fld["line-ignore"] then + igncol, ignval = fld["line-ignore"]:match("([^:]*):(.*)") + end + for num2, col in ipairs(fld["column"]) do + if not col["display"] or col["display"] == "always" then + if not col["src"] then + col["src"] = col["id"] + end + if not loopcnt and col["src"] ~= "index" then + table.insert(dat, 1, "for i = 1, #arr['" .. col["src"] .. "'] do") + table.insert(dat, 2, "index = arr['" .. col["src"] .. "'][i].index") + table.insert(dat, 3, "line = ''") + loopcnt = true + end + head[#head + 1] = "output = output .. '" .. col["id"] .. "\\t'" + if col["src"] == "index" then + dat[#dat + 1] = "val = index" + else + dat[#dat + 1] = "if arr['" .. col["src"] .. "'] then val = arr['" .. col["src"] .. "'][i].val end" + end + if col["format"] then + dat[#dat + 1] = check_format(col["format"]) + dat[#dat + 1] = "val = tempform(val)" + end + if igncol == col["id"] then + dat[#dat + 1] = "checkval = val" + end + dat[#dat + 1] = "line = line .. val .. '\\t'" + end + end + if igncol then + dat[#dat + 1] = "if checkval ~= " .. ignval .. " then output = output .. line .. '\\n' end\nend" + else + dat[#dat + 1] = "output = output .. line .. '\\n'\nend" + end + s[#s + 1] = table.concat(head, "\n") .. "\noutput = output .. '\\n'" + s[#s + 1] = table.concat(dat, "\n") + end + end + end + s[#s + 1] = "return output" + + -- cache script + local script = table.concat(s, "\n") + local scrpath = datpath .. "/" + local scrfile = io.open(scrpath .. set .. ".lua", "w+") + if not scrfile then + lfs.mkdir(scrpath) + scrfile = io.open(scrpath .. set .. ".lua", "w+") + end + if scrfile then + scrfile:write(script) + end + return script + end + + if #env == 0 then + function env.open(file, size) + if file == ".hi" then + local path = "hi" + local ini = emu.file(lfs.env_replace(manager:options().entries.inipath:value()), 1) + local ret = ini:open("hiscore.ini") + if not ret then + local inifile = ini:read(ini:size()) + for line in inifile:gmatch("[^\n\r]") do + token, value = string.match(line, '([^ ]+) ([^ ]+)'); + if token == "hi_path" then + path = value + break + end + end + end + file = path .. "/" .. set .. ".hi" + else + file = lfs.env_replace(manager:options().entries.nvram_directory:value()) .. "/" .. set .. "/" .. file + end + local f = io.open(file, "rb") + local content = f:read("*all") + f:close() + if #content < size then + content = content .. string.rep("\0", size - #content) + end + return content + end + + function env.endianness(bytes, endian) + local newbytes = {} + if endian == "little_endian" then + for i = 1, #bytes do + newbytes[i] = bytes[#bytes - i + 1] + end + else + newbytes = bytes + end + return newbytes + end + + function env.byte_skip(bytes, skip) + local newbytes = {} + if skip == "odd" then + -- lua lists are 1 based so use even indexes + for i = 2, #bytes, 2 do + newbytes[i/2] = bytes[i] + end + elseif skip == "even" then + for i = 1, #bytes, 2 do + newbytes[(i+1)/2] = bytes[i] + end + elseif skip == "1000" then + for i = 1, #bytes, 4 do + newbytes[(i+3)/4] = bytes[i] + end + elseif skip == "0100" then + for i = 2, #bytes, 4 do + newbytes[(i+2)/4] = bytes[i] + end + elseif skip == "0010" then + for i = 3, #bytes, 4 do + newbytes[(i+1)/4] = bytes[i] + end + elseif skip == "0001" then + for i = 4, #bytes, 4 do + newbytes[i/4] = bytes[i] + end + else + skip = tonumber(skip) + for i = 1, #bytes do + if bytes[i] ~= skip then + newbytes[#newbytes + 1] = bytes[i] + end + end + end + return newbytes + end + + function env.byte_trim(bytes, val) + val = tonumber(val) + for i = 1, #bytes do + if bytes[i] ~= val then + return bytes + end + table.remove(bytes, 1) + end + return bytes + end + + function env.byte_swap(bytes, val) + local newbytes = {} + val = tonumber(val) + for i = 1, #bytes do + local off = i + val - 1 - 2 * ((i - 1) % val) + if off > #bytes then -- ?? + break + end + newbytes[i] = bytes[off] + end + return newbytes + end + + function env.nibble_skip(bytes, skip) + local newbytes = {} + if skip == "odd" then + for i = 1, #bytes, 2 do + val = bytes[i]:byte(1) + newbytes[(i+1)/2] = string.char(((val & 0x0f) << 4) | (val & 0x0f)) + end + elseif skip == "even" then + for i = 1, #bytes, 2 do + val = bytes[i]:byte(1) + newbytes[(i+1)/2] = string.char((val & 0xf0) | ((val & 0xf0) >> 4)) + end + end + return newbytes + end + + function env.bit_swap(bytes, swap) + if swap == "yes" then + for i = 1, #bytes do + val = bytes[i]:byte(1) + bytes[i] = string.char(((val & 1) << 7) | ((val & 2) << 5) | ((val & 4) << 3) | ((val & 8) << 1) | ((val & 0x10) >> 1) | ((val & 0x20) >> 3) | ((val & 0x40) >> 5) | ((val & 0x80) >> 7)) + end + end + return bytes + end + + function env.bitmask(bytes, mask) + local newbytes = 0 + bytes = string.unpack(">I" .. #bytes, table.concat(bytes)) + for i = 1, #mask do + newbytes = newbytes | (((bytes >> mask.ishift) & mask.mask) << mask.oshift) + end + bytes = {} + while newbytes ~= 0 do + bytes[#bytes + 1] = newbytes & 0xff + newbytes = newbytes >> 8 + end + newbytes = {} + for i = 1, #bytes do + newbytes[i] = string.char(bytes[#bytes + 1 - i]) + end + return newbytes + end + + function env.frombcd(val) + local result = 0 + local mul = 1 + while val ~= 0 do + result = result + ((val % 16) * mul) + val = val >> 4 + mul = mul * 10 + end + return result + end + + function env.basechar(bytes, base) + if base == "32" then + elseif base == "40" then + end + return bytes + end + + function env.charset_conv(bytes, charset) + if type(charset) == "string" then + local chartype, offset, delta = charset:match("CS_(%w*)%[?(%-?%d?%d?),?(%d?%d?)%]?") + if chartype == "NUMBER" then + + end + return + end + for num, char in ipairs(bytes) do + char = string.byte(char) + if charset[char] then + bytes[num] = charset[char] + elseif charset.default then + bytes[num] = charset.default + end + end + return bytes + end + + function env.ascii_step(bytes, step) + for num, char in ipairs(bytes) do + bytes[num] = string.char(char:byte() / step) + end + return bytes + end + + function env.ascii_offset(bytes, offset) + for num, char in ipairs(bytes) do + bytes[num] = string.char(char:byte() + offset) + end + return bytes + end + + env.tostring = tostring + env.type = type + env.table = { pack = table.pack, concat = table.concat, insert = table.insert, remove = table.remove } + env.string = { unpack = string.unpack, format = string.format, rep = string.rep, gsub = string.gsub, lower = string.lower, upper = string.upper } + env.math = { min = math.min, max = math.max, floor = math.floor } + end + + if curset == set then + if output then + return "High Scores" + else + return nil + end + end + output = nil + curset = set + + local scrfile = emu.file(lfs.env_replace(mame_manager:ui():options().entries.historypath:value():gsub("([^;]+)", "%1/hi2txt")), 1) + local ret = scrfile:open(set .. ".lua") + local script + if ret then + local xml = xml_parse() + if not xml then + return nil + end + local status + status, script = pcall(parse_table, xml) + if not status then + emu.print_verbose("error creating hi score parse script: " .. script) + return nil + end + else + script = scrfile:read(scrfile:size()) + end + local scr, err = load(script, script, "t", env) + if err then + emu.print_verbose("error loading hi score script file: " .. err) + else + status, output = pcall(scr, xml_table) + if not status then + emu.print_verbose("error in hi score parse script: " .. output) + output = nil + end + end + if output then + return "High Scores" + else + return nil + end +end + +function dat.get() + return output +end + +return dat diff --git a/plugins/data/data_history.lua b/plugins/data/data_history.lua new file mode 100644 index 00000000000..329bccd0b1e --- /dev/null +++ b/plugins/data/data_history.lua @@ -0,0 +1,26 @@ +local dat = {} +local ver, info +local datread = require("data/load_dat") +datread, ver = datread.open("history.dat", "## REVISION:") + +function dat.check(set, softlist) + if not datread then + return nil + end + local status + status, info = pcall(datread, "bio", softlist or "info", set) + if not status or not info then + return nil + end + return "History" +end + +function dat.get() + return info +end + +function dat.ver() + return ver +end + +return dat diff --git a/plugins/data/data_mameinfo.lua b/plugins/data/data_mameinfo.lua new file mode 100644 index 00000000000..6daddc57b45 --- /dev/null +++ b/plugins/data/data_mameinfo.lua @@ -0,0 +1,26 @@ +local dat = {} +local ver, info +local datread = require("data/load_dat") +datread, ver = datread.open("mameinfo.dat", "# MAMEINFO.DAT") + +function dat.check(set, softlist) + if softlist or not datread then + return nil + end + local status + status, info = pcall(datread, "mame", "info", set) + if not status or not info then + return nil + end + return "Mameinfo" +end + +function dat.get() + return info +end + +function dat.ver() + return ver +end + +return dat diff --git a/plugins/data/data_messinfo.lua b/plugins/data/data_messinfo.lua new file mode 100644 index 00000000000..5aed9eea8d1 --- /dev/null +++ b/plugins/data/data_messinfo.lua @@ -0,0 +1,27 @@ +local dat = {} +local ver, info + +local datread = require("data/load_dat") +datread, ver = datread.open("messinfo.dat", "# MESSINFO.DAT") + +function dat.check(set, softlist) + if softlist or not datread then + return nil + end + local status + status, info = pcall(datread, "mame", "info", set) + if not status or not info then + return nil + end + return "Messinfo" +end + +function dat.get() + return info +end + +function dat.ver() + return ver +end + +return dat diff --git a/plugins/data/data_story.lua b/plugins/data/data_story.lua new file mode 100644 index 00000000000..1a933f0d74b --- /dev/null +++ b/plugins/data/data_story.lua @@ -0,0 +1,32 @@ +local dat = {} +local ver, info +local datread = require("data/load_dat") +local space_wid = mame_manager:ui():get_char_width(0x200a) +datread, ver = datread.open("story.dat", "# version") + +function dat.check(set, softlist) + if softlist or not datread then + return nil + end + local status + status, info = pcall(datread, "story", "info", set) + if not status or not info then + return nil + end + info = "#jf\n" .. info:gsub("([^%s]-)(%f[_]_+%f[0-9])([0-9.]+)", + function(name, sep, score) + local wid = mame_manager:ui():get_string_width(name .. score, 1.0) + return name .. string.rep(utf8.char(0x200a), math.floor((.4 - wid) / space_wid)) .. score + end) + return "Mamescore" +end + +function dat.get() + return info +end + +function dat.ver() + return ver +end + +return dat diff --git a/plugins/data/data_sysinfo.lua b/plugins/data/data_sysinfo.lua new file mode 100644 index 00000000000..9271f7b0a42 --- /dev/null +++ b/plugins/data/data_sysinfo.lua @@ -0,0 +1,26 @@ +local dat = {} +local ver, info +local datread = require("data/load_dat") +datread, ver = datread.open("sysinfo.dat", "# This file was generated on") + +function dat.check(set, softlist) + if softlist or not datread then + return nil + end + local status + status, info = pcall(datread, "bio", "info", set) + if not status or not info then + return nil + end + return "Sysinfo" +end + +function dat.get() + return info +end + +function dat.ver() + return ver +end + +return dat diff --git a/plugins/data/init.lua b/plugins/data/init.lua new file mode 100644 index 00000000000..83cf194af11 --- /dev/null +++ b/plugins/data/init.lua @@ -0,0 +1,85 @@ +-- license:BSD-3-Clause +-- copyright-holders:Carl +-- A data script should contain two functions check which takes a set name and returns the data +-- heading if it supports the set otherwise nil and get which returns the data +-- the script should be named data_<name>.lua +-- this is set default on in the plugin.json +local exports = {} +exports.name = "data" +exports.version = "0.0.1" +exports.description = "Data plugin" +exports.license = "The BSD 3-Clause License" +exports.author = { name = "Carl" } + +local data = exports + +function data.set_folder(path) + data.path = path +end + +function data.startplugin() + local data_scr = {} + local valid_lst = {} + local cur_set + local cur_list + emu.register_start(function() + data_scr = {} + for file in lfs.dir(data.path) do + local name = string.match(file, "^(data_.*).lua$") + if name then + local script = require("data/" .. name) + if script then + data_scr[#data_scr + 1] = script + end + end + end + end) + emu.register_callback(function(set) + local ret + if set == cur_set then + return cur_list + elseif set == "" then + set = cur_set + else + cur_set = set + end + if not set then + return nil + end + valid_lst = {} + for num, scr in ipairs(data_scr) do + local setname, softname = set:match("^([^,]+),?(.*)$") + if softname == "" then + softname = nil + end + local name = scr.check(setname, softname) + if name then + if not ret then + ret = name + else + ret = ret .. "," .. name + end + valid_lst[#valid_lst + 1] = scr + end + end + cur_list = ret + return ret + end, "data_list") + + emu.register_callback(function(num) + return valid_lst[num + 1].get() + end, "data") + + emu.register_callback(function(num) + local ver + if valid_lst[num + 1].ver then + ver = valid_lst[num + 1].ver() + end + if ver then + return ver + end + return "" + end, "data_version") +end + +return exports diff --git a/plugins/data/load_dat.lua b/plugins/data/load_dat.lua new file mode 100644 index 00000000000..72956a8becb --- /dev/null +++ b/plugins/data/load_dat.lua @@ -0,0 +1,97 @@ +local datfile = {} + +function datfile.open(file, vertag) + local data = {} + local ver + local filepath + local fh + for path in mame_manager:ui():options().entries.historypath:value():gmatch("([^;]+)") do + filepath = lfs.env_replace(path) .. "/" .. file + fh = io.open(filepath, "rb") + if fh then + break + end + end + if not fh then + return nil + end + do + local inblock = false + local buffer = fh:read("a") + if vertag then + local match = buffer:match(vertag .. "%s*([^%s]+)") + if match then + ver = match + end + end + local function gmatchpos() + local pos = 1 + local function iter() + local spos, epos = buffer:find("\n$", pos, true) + if not spos then + return nil + end + spos = spos + 1 + local spos, epos, match = buffer:find("([^\n]+)", spos) + pos = epos + 1 + return match, pos, iter + end + return iter + end + for line, epos, iter in gmatchpos() do + + local flag = line:sub(1, 1) + if flag ~= "#" then + if flag == "$" then + if line:sub(1, 4) == "$end" then + inblock = false + elseif not inblock then + local tag, set = line:match("^%$([^%s=]+)=?([^%s]*)") + if set and set ~= "" then + local tags = {} + local sets = {} + local tag1 = "" + tag:gsub("([^,]+)", function(s) tags[#tags + 1] = s end) + set:gsub("([^,]+)", function(s) sets[#sets + 1] = s end) + repeat + tag1, epos = iter() + until tag1:sub(1, 1) == "$" + tag1 = tag1:match("^$([^%s]*)") + if not data[tag1] then + data[tag1] = {} + end + for num1, tag2 in pairs(tags) do + if not data[tag1][tag2] then + data[tag1][tag2] = {} + end + for num2, set in pairs(sets) do + data[tag1][tag2][set] = epos + end + end + end + inblock = true + end + end + end + end + end + fh:close() + fh = io.open(filepath, "r") + local function read(tag1, tag2, set) + local output = {} + if not data[tag1][tag2][set] then + return nil + end + fh:seek("set", data[tag1][tag2][set]) + for line in fh:lines() do + if line == "$end" then + return table.concat(output, "\n") + end + output[#output + 1] = line + end + end + + return read, ver +end + +return datfile diff --git a/plugins/data/plugin.json b/plugins/data/plugin.json new file mode 100644 index 00000000000..89c36d6bd36 --- /dev/null +++ b/plugins/data/plugin.json @@ -0,0 +1,10 @@ +{ + "plugin": { + "name": "data", + "description": "Data plugin", + "version": "0.0.1", + "author": "Carl", + "type": "plugin", + "start": "true" + } +} diff --git a/scripts/src/mame/frontend.lua b/scripts/src/mame/frontend.lua index d1660dc0f22..41d0598cb15 100644 --- a/scripts/src/mame/frontend.lua +++ b/scripts/src/mame/frontend.lua @@ -130,8 +130,6 @@ files { MAME_DIR .. "src/frontend/mame/ui/custmenu.h", MAME_DIR .. "src/frontend/mame/ui/custui.cpp", MAME_DIR .. "src/frontend/mame/ui/custui.h", - MAME_DIR .. "src/frontend/mame/ui/datfile.cpp", - MAME_DIR .. "src/frontend/mame/ui/datfile.h", MAME_DIR .. "src/frontend/mame/ui/datmenu.cpp", MAME_DIR .. "src/frontend/mame/ui/datmenu.h", MAME_DIR .. "src/frontend/mame/ui/defimg.ipp", diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index a19e80f6e09..88c271f008e 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -2280,6 +2280,17 @@ int lua_engine::l_osd_printf_debug(lua_State *L) return 0; } +int lua_engine::l_driver_find(lua_State *L) +{ + luaL_argcheck(L, lua_isstring(L, 1), 1, "message (string) expected"); + int index = driver_list::find(lua_tostring(L, 1)); + if(index == -1) + lua_pushnil(L); + else + luabridge::Stack<const game_driver &>::push(L, driver_list::driver(index)); + return 1; +} + //------------------------------------------------- // initialize - initialize lua hookup to emu engine //------------------------------------------------- @@ -2316,6 +2327,7 @@ void lua_engine::initialize() .addCFunction ("print_error", l_osd_printf_error ) .addCFunction ("print_info", l_osd_printf_info ) .addCFunction ("print_debug", l_osd_printf_debug ) + .addCFunction ("driver_find", l_driver_find ) .beginClass <machine_manager>("manager") .addFunction("machine", &machine_manager::machine) .addFunction("options", &machine_manager::options) @@ -2577,6 +2589,8 @@ void lua_engine::initialize() .addProperty <bool, bool> ("show_profiler", &mame_ui_manager::show_profiler, &mame_ui_manager::set_show_profiler) .addProperty <bool, bool> ("single_step", &mame_ui_manager::single_step, &mame_ui_manager::set_single_step) .addFunction ("get_line_height", &mame_ui_manager::get_line_height) + .addFunction ("get_string_width", &mame_ui_manager::get_string_width) + .addFunction ("get_char_width", &mame_ui_manager::get_char_width) .endClass() .beginClass <lua_screen> ("lua_screen_dev") .addCFunction ("draw_box", &lua_screen::l_draw_box) diff --git a/src/frontend/mame/luaengine.h b/src/frontend/mame/luaengine.h index 15dfdd2f6ae..c0f9acd491d 100644 --- a/src/frontend/mame/luaengine.h +++ b/src/frontend/mame/luaengine.h @@ -143,6 +143,7 @@ private: static int l_osd_printf_error(lua_State *L); static int l_osd_printf_info(lua_State *L); static int l_osd_printf_debug(lua_State *L); + static int l_driver_find(lua_State *L); static int register_function(lua_State *L, const char *id); // "emu.machine" namespace diff --git a/src/frontend/mame/mame.cpp b/src/frontend/mame/mame.cpp index c6f4824ced4..0a4fc03b3bd 100644 --- a/src/frontend/mame/mame.cpp +++ b/src/frontend/mame/mame.cpp @@ -16,14 +16,12 @@ #include "osdepend.h" #include "validity.h" #include "clifront.h" -#include "drivenum.h" #include "luaengine.h" #include <time.h> #include "ui/ui.h" #include "ui/selgame.h" #include "ui/simpleselgame.h" #include "cheat.h" -#include "ui/datfile.h" #include "ui/inifile.h" #include "xmlfile.h" @@ -297,9 +295,6 @@ void mame_machine_manager::create_custom(running_machine& machine) // allocate autoboot timer m_autoboot_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(mame_machine_manager::autoboot_callback), this)); - // start datfile manager - m_datfile = std::make_unique<ui::datfile_manager>(machine, m_ui->options()); - // start favorite manager m_favorite = std::make_unique<favorite_manager>(machine, m_ui->options()); diff --git a/src/frontend/mame/mame.h b/src/frontend/mame/mame.h index 859c788e2e9..b6061810245 100644 --- a/src/frontend/mame/mame.h +++ b/src/frontend/mame/mame.h @@ -25,7 +25,6 @@ class favorite_manager; class mame_ui_manager; namespace ui { -class datfile_manager; } // namespace ui // ======================> machine_manager @@ -61,7 +60,6 @@ public: void schedule_new_driver(const game_driver &driver); mame_ui_manager& ui() const { assert(m_ui != nullptr); return *m_ui; } cheat_manager &cheat() const { assert(m_cheat != nullptr); return *m_cheat; } - ui::datfile_manager &datfile() const { assert(m_datfile != nullptr); return *m_datfile; } inifile_manager &inifile() const { assert(m_inifile != nullptr); return *m_inifile; } favorite_manager &favorite() const { assert(m_favorite != nullptr); return *m_favorite; } private: @@ -75,7 +73,6 @@ private: emu_timer *m_autoboot_timer; // autoboot timer std::unique_ptr<mame_ui_manager> m_ui; // internal data from ui.cpp std::unique_ptr<cheat_manager> m_cheat; // internal data from cheat.cpp - std::unique_ptr<ui::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 diff --git a/src/frontend/mame/ui/datfile.cpp b/src/frontend/mame/ui/datfile.cpp deleted file mode 100644 index 17552f34d68..00000000000 --- a/src/frontend/mame/ui/datfile.cpp +++ /dev/null @@ -1,581 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Maurizio Petrarota -/*************************************************************************** - - ui/datfile.cpp - - UI DATs manager. - -***************************************************************************/ - -#include "emu.h" -#include "ui/datfile.h" - -#include "drivenum.h" -#include "ui/moptions.h" -#include "ui/utils.h" - -#include <utility> - - -namespace ui { -namespace { -//------------------------------------------------- -// TAGS -//------------------------------------------------- -std::string const DATAFILE_TAG("$"); -std::string const TAG_BIO("$bio"); -std::string const TAG_INFO("$info"); -std::string const TAG_MAME("$mame"); -std::string const TAG_COMMAND("$cmd"); -std::string const TAG_END("$end"); -std::string const TAG_DRIVER("$drv"); -std::string const TAG_STORY("$story"); -std::string const TAG_HISTORY_R("## REVISION:"); -std::string const TAG_MAMEINFO_R("# MAMEINFO.DAT"); -std::string const TAG_MESSINFO_R("# MESSINFO.DAT"); -std::string const TAG_SYSINFO_R("# This file was generated on"); -std::string const TAG_STORY_R("# version"); -std::string const TAG_COMMAND_SEPARATOR("-----------------------------------------------"); -std::string const TAG_GAMEINIT_R("# GAMEINIT.DAT"); - -} // anonymous namespace - -//------------------------------------------------- -// Statics -//------------------------------------------------- -datfile_manager::dataindex datfile_manager::m_histidx; -datfile_manager::dataindex datfile_manager::m_mameidx; -datfile_manager::dataindex datfile_manager::m_messidx; -datfile_manager::dataindex datfile_manager::m_cmdidx; -datfile_manager::dataindex datfile_manager::m_sysidx; -datfile_manager::dataindex datfile_manager::m_storyidx; -datfile_manager::dataindex datfile_manager::m_ginitidx; -datfile_manager::drvindex datfile_manager::m_drvidx; -datfile_manager::drvindex datfile_manager::m_messdrvidx; -datfile_manager::drvindex datfile_manager::m_menuidx; -datfile_manager::swindex datfile_manager::m_swindex; -std::string datfile_manager::m_history_rev; -std::string datfile_manager::m_mame_rev; -std::string datfile_manager::m_mess_rev; -std::string datfile_manager::m_sysinfo_rev; -std::string datfile_manager::m_story_rev; -std::string datfile_manager::m_ginit_rev; -bool datfile_manager::first_run = true; - -#define opendatsfile(f) do { fileptr datfile = parseopen(#f".dat"); if (datfile) init_##f(std::move(datfile)); } while (false) - -//------------------------------------------------- -// ctor -//------------------------------------------------- -datfile_manager::datfile_manager(running_machine &machine, ui_options &moptions) - : m_machine(machine) - , m_options(moptions) -{ - if (m_options.enabled_dats() && first_run) - { - first_run = false; - opendatsfile(mameinfo); - opendatsfile(command); - opendatsfile(story); - opendatsfile(messinfo); - opendatsfile(sysinfo); - opendatsfile(history); - opendatsfile(gameinit); - } -} - -//------------------------------------------------- -// initialize sysinfo.dat index -//------------------------------------------------- -void datfile_manager::init_sysinfo(fileptr &&fp) -{ - int swcount = 0; - auto count = index_datafile(std::move(fp), m_sysidx, swcount, m_sysinfo_rev, TAG_SYSINFO_R, '.'); - osd_printf_verbose("Sysinfo.dat games found = %i\n", count); - osd_printf_verbose("Rev = %s\n", m_sysinfo_rev.c_str()); -} - -//------------------------------------------------- -// initialize story.dat index -//------------------------------------------------- -void datfile_manager::init_story(fileptr &&fp) -{ - int swcount = 0; - auto count = index_datafile(std::move(fp), m_storyidx, swcount, m_story_rev, TAG_STORY_R, 's'); - osd_printf_verbose("Story.dat games found = %i\n", count); -} - -//------------------------------------------------- -// initialize history.dat index -//------------------------------------------------- -void datfile_manager::init_history(fileptr &&fp) -{ - int swcount = 0; - auto count = index_datafile(std::move(fp), m_histidx, swcount, m_history_rev, TAG_HISTORY_R, ' '); - osd_printf_verbose("History.dat systems found = %i\n", count); - osd_printf_verbose("History.dat software packages found = %i\n", swcount); - osd_printf_verbose("Rev = %s\n", m_history_rev.c_str()); -} - -//------------------------------------------------- -// initialize gameinit.dat index -//------------------------------------------------- -void datfile_manager::init_gameinit(fileptr &&fp) -{ - int swcount = 0; - drvindex tmp; - auto count = index_mame_mess_info(std::move(fp), m_ginitidx, tmp, swcount); - osd_printf_verbose("Gameinit.dat games found = %i\n", count); - osd_printf_verbose("Rev = %s\n", m_ginit_rev.c_str()); -} - -//------------------------------------------------- -// initialize mameinfo.dat index -//------------------------------------------------- -void datfile_manager::init_mameinfo(fileptr &&fp) -{ - int drvcount = 0; - auto count = index_mame_mess_info(std::move(fp), m_mameidx, m_drvidx, drvcount); - osd_printf_verbose("Mameinfo.dat games found = %i\n", count); - osd_printf_verbose("Mameinfo.dat drivers found = %d\n", drvcount); - osd_printf_verbose("Rev = %s\n", m_mame_rev.c_str()); -} - -//------------------------------------------------- -// initialize messinfo.dat index -//------------------------------------------------- -void datfile_manager::init_messinfo(fileptr &&fp) -{ - int drvcount = 0; - auto count = index_mame_mess_info(std::move(fp), m_messidx, m_messdrvidx, drvcount); - osd_printf_verbose("Messinfo.dat games found = %i\n", count); - osd_printf_verbose("Messinfo.dat drivers found = %d\n", drvcount); - osd_printf_verbose("Rev = %s\n", m_mess_rev.c_str()); -} - -//------------------------------------------------- -// initialize command.dat index -//------------------------------------------------- -void datfile_manager::init_command(fileptr &&fp) -{ - int swcount = 0; - std::string tmp; - auto count = index_datafile(std::move(fp), m_cmdidx, swcount, tmp, std::string(), 'c'); - osd_printf_verbose("Command.dat games found = %i\n", count); -} - -bool datfile_manager::has_software(std::string const &softlist, std::string const &softname, std::string const &parentname) const -{ - return bool(find_software(softlist, softname, parentname)); -} - -long const *datfile_manager::find_software(std::string const &softlist, std::string const &softname, std::string const &parentname) const -{ - // Find software in software list index - auto const software(m_swindex.find(softlist)); - if (software == m_swindex.end()) - return nullptr; - - auto itemsiter = software->second.find(softname); - if ((itemsiter == software->second.end()) && !parentname.empty()) - itemsiter = software->second.find(parentname); - - return (itemsiter != software->second.end()) ? &itemsiter->second : nullptr; -} - -//------------------------------------------------- -// load software info -//------------------------------------------------- -void datfile_manager::load_software_info(std::string const &softlist, std::string &buffer, std::string const &softname, std::string const &parentname) -{ - if (m_swindex.empty()) - return; - - // Load history text - fileptr const datfile = parseopen("history.dat"); - if (datfile) - { - // Find software in software list index - long const *const s_offset = find_software(softlist, softname, parentname); - if (!s_offset) - return; - - char rbuf[64 * 1024]; - std::fseek(datfile.get(), *s_offset, SEEK_SET); - std::string readbuf; - while (std::fgets(rbuf, 64 * 1024, datfile.get()) != nullptr) - { - readbuf = chartrimcarriage(rbuf); - - // end entry when a end tag is encountered - if (readbuf == TAG_END) - break; - - // add this string to the buffer - buffer.append(readbuf).append("\n"); - } - } -} - -//------------------------------------------------- -// load_data_info -//------------------------------------------------- -void datfile_manager::load_data_info(const game_driver *drv, std::string &buffer, int type) -{ - dataindex const *index_idx = nullptr; - drvindex const *driver_idx = nullptr; - std::string const *tag; - std::string filename; - - switch (type) - { - case UI_HISTORY_LOAD: - filename = "history.dat"; - tag = &TAG_BIO; - index_idx = &m_histidx; - break; - case UI_MAMEINFO_LOAD: - filename = "mameinfo.dat"; - tag = &TAG_MAME; - index_idx = &m_mameidx; - driver_idx = &m_drvidx; - break; - case UI_SYSINFO_LOAD: - filename = "sysinfo.dat"; - tag = &TAG_BIO; - index_idx = &m_sysidx; - break; - case UI_MESSINFO_LOAD: - filename = "messinfo.dat"; - tag = &TAG_MAME; - index_idx = &m_messidx; - driver_idx = &m_messdrvidx; - break; - case UI_STORY_LOAD: - filename = "story.dat"; - tag = &TAG_STORY; - index_idx = &m_storyidx; - break; - case UI_GINIT_LOAD: - filename = "gameinit.dat"; - tag = &TAG_MAME; - index_idx = &m_ginitidx; - break; - default: - assert(false); - return; - } - - fileptr const datfile = parseopen(filename.c_str()); - if (datfile) - { - load_data_text(datfile.get(), drv, buffer, *index_idx, *tag); - - // load driver info - if (driver_idx && !driver_idx->empty()) - load_driver_text(datfile.get(), drv, buffer, *driver_idx, TAG_DRIVER); - - // cleanup mameinfo and sysinfo double line spacing - if (((*tag == TAG_MAME) && (type != UI_GINIT_LOAD)) || (type == UI_SYSINFO_LOAD)) - strreplace(buffer, "\n\n", "\n"); - } -} - -//------------------------------------------------- -// load a game text into the buffer -//------------------------------------------------- -void datfile_manager::load_data_text(FILE *fp, game_driver const *drv, std::string &buffer, dataindex const &idx, std::string const &tag) -{ - auto itemsiter = idx.find(drv); - if (itemsiter == idx.end()) - { - auto cloneof = driver_list::non_bios_clone(*drv); - if (cloneof == -1) - return; - else - { - auto c_drv = &driver_list::driver(cloneof); - itemsiter = idx.find(c_drv); - if (itemsiter == idx.end()) - return; - } - } - - auto s_offset = itemsiter->second; - std::fseek(fp, s_offset, SEEK_SET); - char rbuf[64 * 1024]; - std::string readbuf; - while (std::fgets(rbuf, 64 * 1024, fp) != nullptr) - { - readbuf = chartrimcarriage(rbuf); - - // end entry when a end tag is encountered - if (readbuf == TAG_END) - break; - - // continue if a specific tag is encountered - if (readbuf == tag) - continue; - - // add this string to the buffer - buffer.append(readbuf).append("\n"); - } -} - -//------------------------------------------------- -// load a driver name and offset into an -// indexed array -//------------------------------------------------- -void datfile_manager::load_driver_text(FILE *fp, game_driver const *drv, std::string &buffer, drvindex const &idx, std::string const &tag) -{ - std::string s(core_filename_extract_base(drv->source_file)); - auto index = idx.find(s); - - // if driver not found, return - if (index == idx.end()) - return; - - buffer.append("\n--- DRIVER INFO ---\n").append("Driver: ").append(s).append("\n\n"); - auto s_offset = index->second; - std::fseek(fp, s_offset, SEEK_SET); - char rbuf[64 * 1024]; - std::string readbuf; - while (std::fgets(rbuf, 64 * 1024, fp) != nullptr) - { - readbuf = chartrimcarriage(rbuf); - - // end entry when a end tag is encountered - if (readbuf == TAG_END) - break; - - // continue if a specific tag is encountered - if (readbuf == tag) - continue; - - // add this string to the buffer - buffer.append(readbuf).append("\n"); - } -} - -//------------------------------------------------- -// load a game name and offset into an -// indexed array (mameinfo) -//------------------------------------------------- -int datfile_manager::index_mame_mess_info(fileptr &&fp, dataindex &index, drvindex &index_drv, int &drvcount) -{ - size_t foundtag; - auto t_mame = TAG_MAMEINFO_R.size(); - auto t_mess = TAG_MESSINFO_R.size(); - auto t_ginit = TAG_GAMEINIT_R.size(); - auto t_info = TAG_INFO.size(); - - char rbuf[64 * 1024]; - std::string readbuf, xid, name; - while (std::fgets(rbuf, 64 * 1024, fp.get()) != nullptr) - { - readbuf = chartrimcarriage(rbuf); - if (m_mame_rev.empty() && readbuf.compare(0, t_mame, TAG_MAMEINFO_R) == 0) - { - auto found = readbuf.find(" ", t_mame + 1); - m_mame_rev = readbuf.substr(t_mame + 1, found - t_mame); - } - else if (m_mess_rev.empty() && (foundtag = readbuf.find(TAG_MESSINFO_R)) != std::string::npos) - { - auto found = readbuf.find(" ", foundtag + t_mess + 1); - m_mess_rev = readbuf.substr(foundtag + t_mess + 1, found - t_mess - foundtag); - } - else if (m_ginit_rev.empty() && readbuf.compare(0, t_ginit, TAG_GAMEINIT_R) == 0) - { - auto found = readbuf.find(" ", t_ginit + 1); - m_ginit_rev = readbuf.substr(t_ginit + 1, found - t_ginit); - } - else if (readbuf.compare(0, t_info, TAG_INFO) == 0) - { - // TAG_INFO - std::fgets(rbuf, 64 * 1024, fp.get()); - xid = chartrimcarriage(rbuf); - name = readbuf.substr(t_info + 1); - if (xid == TAG_MAME) - { - // validate driver - auto game_index = driver_list::find(name.c_str()); - if (game_index != -1) - index.emplace(&driver_list::driver(game_index), std::ftell(fp.get())); - } - else if (xid == TAG_DRIVER) - { - index_drv.emplace(name, std::ftell(fp.get())); - drvcount++; - } - } - } - return index.size(); -} - -//------------------------------------------------- -// load a game name and offset into an -// indexed array -//------------------------------------------------- -int datfile_manager::index_datafile(fileptr &&fp, dataindex &index, int &swcount, std::string &rev, std::string const &tag, char sep) -{ - std::string readbuf; - auto const tag_size = tag.size(); - auto const t_info = TAG_INFO.size(); - auto const t_bio = TAG_BIO.size(); - char rbuf[64 * 1024]; - while (std::fgets(rbuf, 64 * 1024, fp.get()) != nullptr) - { - readbuf = chartrimcarriage(rbuf); - - if (!tag.empty()) - { - if (rev.empty() && readbuf.compare(0, tag_size, tag) == 0) - { - if (sep != 's') - rev = readbuf.substr(tag_size + 1, readbuf.find(sep, tag_size + 1) - tag_size); - else - rev = readbuf.substr(tag_size + 1); - } - } - - if (readbuf.compare(0, t_info, TAG_INFO) == 0) - { - // search for game info - auto rd = readbuf.substr(t_info + 1); - std::vector<std::string> gamelist = tokenize(rd, ','); - for (auto & e : gamelist) - { - auto game_index = driver_list::find(e.c_str()); - if (game_index != -1) - index.emplace(&driver_list::driver(game_index), std::ftell(fp.get())); - } - } - else if (!readbuf.empty() && readbuf[0] == DATAFILE_TAG[0]) - { - // search for software info - std::fgets(rbuf, 64 * 1024, fp.get()); - std::string readbuf_2(chartrimcarriage(rbuf)); - if (readbuf_2.compare(0, t_bio, TAG_BIO) == 0) - { - auto eq_sign = readbuf.find('='); - std::string s_list(readbuf.substr(1, eq_sign - 1)); - std::string s_roms(readbuf.substr(eq_sign + 1)); - std::vector<std::string> token_list = tokenize(s_list, ','); - std::vector<std::string> token_roms = tokenize(s_roms, ','); - for (auto & li : token_list) - for (auto & ro : token_roms) - m_swindex[li].emplace(ro, std::ftell(fp.get())); - swcount++; - } - } - } - return index.size(); -} - -//--------------------------------------------------------- -// parseopen - Open up file for reading -//--------------------------------------------------------- -datfile_manager::fileptr datfile_manager::parseopen(const char *filename) -{ - emu_file file(m_options.history_path(), OPEN_FLAG_READ); - if (file.open(filename) != osd_file::error::NONE) - return fileptr(nullptr, &std::fclose); - - std::string const fullpath = file.fullpath(); - file.close(); - fileptr result(std::fopen(fullpath.c_str(), "rb"), &std::fclose); - - fgetc(result.get()); - fseek(result.get(), 0, SEEK_SET); - return result; -} - -//------------------------------------------------- -// create the menu index -//------------------------------------------------- -void datfile_manager::index_menuidx(fileptr &&fp, const game_driver *drv, dataindex const &idx, drvindex &index) -{ - auto itemsiter = idx.find(drv); - if (itemsiter == idx.end()) - { - auto const cloneof = driver_list::non_bios_clone(*drv); - if (cloneof == -1) - return; - - auto const c_drv = &driver_list::driver(cloneof); - if ((itemsiter = idx.find(c_drv)) == idx.end()) - return; - } - - // seek to correct point in datafile - auto const s_offset = itemsiter->second; - std::fseek(fp.get(), s_offset, SEEK_SET); - auto const tinfo = TAG_INFO.size(); - char rbuf[64 * 1024]; - std::string readbuf; - while (std::fgets(rbuf, 64 * 1024, fp.get()) != nullptr) - { - readbuf = chartrimcarriage(rbuf); - - if (!core_strnicmp(TAG_INFO.c_str(), readbuf.c_str(), tinfo)) - break; - - // TAG_COMMAND identifies the driver - if (readbuf == TAG_COMMAND) - { - std::fgets(rbuf, 64 * 1024, fp.get()); - chartrimcarriage(rbuf); - index.emplace(rbuf, std::ftell(fp.get())); - } - } -} - -//------------------------------------------------- -// load command text into the buffer -//------------------------------------------------- -void datfile_manager::load_command_info(std::string &buffer, std::string const &sel) -{ - fileptr const datfile = parseopen("command.dat"); - if (datfile) - { - // open and seek to correct point in datafile - auto const offset = m_menuidx.at(sel); - std::fseek(datfile.get(), offset, SEEK_SET); - char rbuf[64 * 1024]; - std::string readbuf; - while (std::fgets(rbuf, 64 * 1024, datfile.get()) != nullptr) - { - readbuf = chartrimcarriage(rbuf); - - // skip separator lines - if (readbuf == TAG_COMMAND_SEPARATOR) - continue; - - // end entry when a tag is encountered - if (readbuf == TAG_END) - break; - - // add this string to the buffer - buffer.append(readbuf).append("\n");; - } - } -} - -//------------------------------------------------- -// load submenu item for command.dat -//------------------------------------------------- -void datfile_manager::command_sub_menu(const game_driver *drv, std::vector<std::string> &menuitems) -{ - fileptr datfile = parseopen("command.dat"); - if (datfile) - { - m_menuidx.clear(); - index_menuidx(std::move(datfile), drv, m_cmdidx, m_menuidx); - menuitems.reserve(m_menuidx.size()); - for (auto const &elem : m_menuidx) - menuitems.push_back(elem.first); - } -} - -} // namespace ui diff --git a/src/frontend/mame/ui/datfile.h b/src/frontend/mame/ui/datfile.h deleted file mode 100644 index 93d13527cc9..00000000000 --- a/src/frontend/mame/ui/datfile.h +++ /dev/null @@ -1,106 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Maurizio Petrarota -/*************************************************************************** - - ui/datfile.h - - UI DATs manager. - -***************************************************************************/ - -#ifndef MAME_FRONTEND_UI_DATFILE_H -#define MAME_FRONTEND_UI_DATFILE_H - -#pragma once - -#include <cstdio> -#include <memory> -#include <string> -#include <unordered_map> - - -class ui_options; - -namespace ui { -//------------------------------------------------- -// Datafile Manager -//------------------------------------------------- -class datfile_manager -{ -public: - // construction/destruction - datfile_manager(running_machine &machine, ui_options &moptions); - - // getters - running_machine &machine() const { return m_machine; } - - // actions - void load_data_info(const game_driver *drv, std::string &buffer, int type); - void load_command_info(std::string &buffer, std::string const &sel); - void load_software_info(std::string const &softlist, std::string &buffer, std::string const &softname, std::string const &parentname); - void command_sub_menu(const game_driver *drv, std::vector<std::string> &menuitems); - void reset_run() { first_run = true; } - - std::string const &rev_history() const { return m_history_rev; } - std::string const &rev_mameinfo() const { return m_mame_rev; } - std::string const &rev_messinfo() const { return m_mess_rev; } - std::string const &rev_sysinfo() const { return m_sysinfo_rev; } - std::string const &rev_storyinfo() const { return m_story_rev; } - std::string const &rev_ginitinfo() const { return m_ginit_rev; } - - bool has_history(game_driver const *driver) const { return m_histidx.find(driver) != m_histidx.end(); } - bool has_mameinfo(game_driver const *driver) const { return m_mameidx.find(driver) != m_mameidx.end(); } - bool has_messinfo(game_driver const *driver) const { return m_messidx.find(driver) != m_messidx.end(); } - bool has_command(game_driver const *driver) const { return m_cmdidx.find(driver) != m_cmdidx.end(); } - bool has_sysinfo(game_driver const *driver) const { return m_sysidx.find(driver) != m_sysidx.end(); } - bool has_story(game_driver const *driver) const { return m_storyidx.find(driver) != m_storyidx.end(); } - bool has_gameinit(game_driver const *driver) const { return m_ginitidx.find(driver) != m_ginitidx.end(); } - bool has_software(std::string const &softlist, std::string const &softname, std::string const &parentname) const; - - bool has_data(game_driver const *a = nullptr) const - { - game_driver const *const d(a ? a : &machine().system()); - return has_history(d) || has_mameinfo(d) || has_messinfo(d) || has_command(d) || has_sysinfo(d) || has_story(d) || has_gameinit(d); - } - -private: - using drvindex = std::unordered_map<std::string, long>; - using dataindex = std::unordered_map<const game_driver *, long>; - using swindex = std::unordered_map<std::string, drvindex>; - using fileptr = std::unique_ptr<FILE, int (*)(FILE *)>; - - // global index - static dataindex m_histidx, m_mameidx, m_messidx, m_cmdidx, m_sysidx, m_storyidx, m_ginitidx; - static drvindex m_drvidx, m_messdrvidx, m_menuidx; - static swindex m_swindex; - - // internal helpers - void init_history(fileptr &&fp); - void init_mameinfo(fileptr &&fp); - void init_messinfo(fileptr &&fp); - void init_command(fileptr &&fp); - void init_sysinfo(fileptr &&fp); - void init_story(fileptr &&fp); - void init_gameinit(fileptr &&fp); - - fileptr parseopen(char const *filename); - - int index_mame_mess_info(fileptr &&fp, dataindex &index, drvindex &index_drv, int &drvcount); - int index_datafile(fileptr &&fp, dataindex &index, int &swcount, std::string &rev, std::string const &tag, char sep); - void index_menuidx(fileptr &&fp, game_driver const *drv, dataindex const &idx, drvindex &index); - - long const *find_software(std::string const &softlist, std::string const &softname, std::string const &parentname) const; - - void load_data_text(FILE *fp, game_driver const *drv, std::string &buffer, dataindex const &idx, std::string const &tag); - void load_driver_text(FILE *fp, game_driver const *drv, std::string &buffer, drvindex const &idx, std::string const &tag); - - // internal state - running_machine &m_machine; // reference to our machine - ui_options &m_options; - static std::string m_history_rev, m_mame_rev, m_mess_rev, m_sysinfo_rev, m_story_rev, m_ginit_rev; - static bool first_run; -}; - -} // namespace ui - -#endif // MAME_FRONTEND_UI_DATFILE_H diff --git a/src/frontend/mame/ui/datmenu.cpp b/src/frontend/mame/ui/datmenu.cpp index 99ae6b69bb7..71bc7c9bf09 100644 --- a/src/frontend/mame/ui/datmenu.cpp +++ b/src/frontend/mame/ui/datmenu.cpp @@ -11,7 +11,6 @@ #include "emu.h" #include "ui/ui.h" -#include "ui/datfile.h" #include "ui/datmenu.h" #include "ui/utils.h" @@ -19,6 +18,7 @@ #include "rendfont.h" #include "softlist.h" #include "uiinput.h" +#include "luaengine.h" #include <cmath> @@ -45,8 +45,19 @@ menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container m_parent = image.software_entry()->parentname(); } } - - init_items(); + const char *lua_list = mame_machine_manager::instance()->lua()->call_plugin(driver->name, "data_list"); + if(lua_list) + { + std::string list(lua_list); + char *token = strtok((char *)list.c_str(), ","); + int count = 0; + while(token) + { + m_items_list.emplace_back(_(token), count, mame_machine_manager::instance()->lua()->call_plugin(util::string_format("%d", count).c_str(), "data_version")); + count++; + token = strtok(nullptr, ","); + } + } } //------------------------------------------------- @@ -65,10 +76,21 @@ menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container , m_issoft(true) { - if (mame_machine_manager::instance()->datfile().has_software(m_list, m_short, m_parent)) - m_items_list.emplace_back(_("Software History"), UI_HISTORY_LOAD, mame_machine_manager::instance()->datfile().rev_history()); if (swinfo != nullptr && !swinfo->usage.empty()) m_items_list.emplace_back(_("Software Usage"), 0, ""); + const char *lua_list = mame_machine_manager::instance()->lua()->call_plugin(std::string(m_short).append(1, ',').append(m_list).c_str(), "data_list"); + if(lua_list) + { + std::string list(lua_list); + char *token = strtok((char *)list.c_str(), ","); + int count = 1; + while(token) + { + m_items_list.emplace_back(_(token), count, mame_machine_manager::instance()->lua()->call_plugin(util::string_format("%d", count - 1).c_str(), "data_version")); + count++; + token = strtok(nullptr, ","); + } + } } //------------------------------------------------- @@ -368,25 +390,8 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f void menu_dats_view::get_data() { std::vector<int> xstart, xend; - std::string buffer; - if (m_items_list[m_actual].option == UI_COMMAND_LOAD) - { - std::vector<std::string> m_item; - mame_machine_manager::instance()->datfile().command_sub_menu(m_driver, m_item); - if (!m_item.empty()) - { - for (auto & e : m_item) - { - std::string t_buffer; - buffer.append(e).append("\n"); - mame_machine_manager::instance()->datfile().load_command_info(t_buffer, e); - if (!t_buffer.empty()) buffer.append(t_buffer).append("\n"); - } - convert_command_glyph(buffer); - } - } - else - mame_machine_manager::instance()->datfile().load_data_info(m_driver, buffer, m_items_list[m_actual].option); + std::string buffer(mame_machine_manager::instance()->lua()->call_plugin(util::string_format("%d", m_items_list[m_actual].option).c_str(), "data")); + auto lines = ui().wrap_text(container(), buffer.c_str(), 0.0f, 0.0f, 1.0f - (4.0f * UI_BOX_LR_BORDER), xstart, xend); for (int x = 0; x < lines; ++x) @@ -404,12 +409,7 @@ void menu_dats_view::get_data_sw() if (m_items_list[m_actual].option == 0) buffer = m_swinfo->usage; else - { - if (m_swinfo->startempty == 1) - mame_machine_manager::instance()->datfile().load_data_info(m_swinfo->driver, buffer, UI_HISTORY_LOAD); - else - mame_machine_manager::instance()->datfile().load_software_info(m_swinfo->listname, buffer, m_swinfo->shortname, m_swinfo->parentname); - } + buffer = mame_machine_manager::instance()->lua()->call_plugin(util::string_format("%d", m_items_list[m_actual].option - 1).c_str(), "data"); auto lines = ui().wrap_text(container(), buffer.c_str(), 0.0f, 0.0f, 1.0f - (4.0f * UI_BOX_LR_BORDER), xstart, xend); for (int x = 0; x < lines; ++x) @@ -419,23 +419,4 @@ void menu_dats_view::get_data_sw() } } -void menu_dats_view::init_items() -{ - datfile_manager &datfile = mame_machine_manager::instance()->datfile(); - if (datfile.has_history(m_driver)) - m_items_list.emplace_back(_("History"), UI_HISTORY_LOAD, datfile.rev_history()); - if (datfile.has_mameinfo(m_driver)) - m_items_list.emplace_back(_("Mameinfo"), UI_MAMEINFO_LOAD, datfile.rev_mameinfo()); - if (datfile.has_messinfo(m_driver)) - m_items_list.emplace_back(_("Messinfo"), UI_MESSINFO_LOAD, datfile.rev_messinfo()); - if (datfile.has_sysinfo(m_driver)) - m_items_list.emplace_back(_("Sysinfo"), UI_SYSINFO_LOAD, datfile.rev_sysinfo()); - if (datfile.has_story(m_driver)) - m_items_list.emplace_back(_("Mamescore"), UI_STORY_LOAD, datfile.rev_storyinfo()); - if (datfile.has_gameinit(m_driver)) - m_items_list.emplace_back(_("Gameinit"), UI_GINIT_LOAD, datfile.rev_ginitinfo()); - if (datfile.has_command(m_driver)) - m_items_list.emplace_back(_("Command"), UI_COMMAND_LOAD, ""); -} - } // namespace ui diff --git a/src/frontend/mame/ui/datmenu.h b/src/frontend/mame/ui/datmenu.h index 03299187c97..9c76cc7141f 100644 --- a/src/frontend/mame/ui/datmenu.h +++ b/src/frontend/mame/ui/datmenu.h @@ -51,7 +51,6 @@ private: std::string m_list, m_short, m_long, m_parent; void get_data(); void get_data_sw(); - void init_items(); bool m_issoft; struct list_items { diff --git a/src/frontend/mame/ui/dirmenu.cpp b/src/frontend/mame/ui/dirmenu.cpp index 80b036c5277..3be14a80974 100644 --- a/src/frontend/mame/ui/dirmenu.cpp +++ b/src/frontend/mame/ui/dirmenu.cpp @@ -12,7 +12,6 @@ #include "ui/ui.h" #include "ui/dirmenu.h" -#include "ui/datfile.h" #include "ui/utils.h" #include "ui/optsmenu.h" @@ -79,7 +78,6 @@ menu_directory::~menu_directory() { ui().save_ui_options(); ui_globals::reset = true; - mame_machine_manager::instance()->datfile().reset_run(); } //------------------------------------------------- @@ -369,7 +367,6 @@ void menu_add_change_folder::handle() machine().options().set_value(s_folders[m_ref].option, m_current_path.c_str(), OPTION_PRIORITY_CMDLINE, error_string); machine().options().mark_changed(s_folders[m_ref].option); } - mame_machine_manager::instance()->datfile().reset_run(); } else { diff --git a/src/frontend/mame/ui/mainmenu.cpp b/src/frontend/mame/ui/mainmenu.cpp index 92d7db18d4c..a70ae892387 100644 --- a/src/frontend/mame/ui/mainmenu.cpp +++ b/src/frontend/mame/ui/mainmenu.cpp @@ -12,6 +12,7 @@ #include "crsshair.h" #include "emuopts.h" #include "mame.h" +#include "luaengine.h" #include "ui/menu.h" #include "ui/filemngr.h" #include "ui/barcode.h" @@ -29,7 +30,6 @@ #include "ui/videoopt.h" #include "imagedev/cassette.h" #include "machine/bcreader.h" -#include "ui/datfile.h" #include "ui/inifile.h" #include "ui/datmenu.h" #include "ui/pluginopt.h" @@ -129,7 +129,7 @@ void menu_main::populate() item_append(_("Plugin Options"), "", 0, (void *)PLUGINS); // add dats menu - if (ui().options().enabled_dats() && mame_machine_manager::instance()->datfile().has_data()) + if (ui().options().enabled_dats() && mame_machine_manager::instance()->lua()->call_plugin("", "data_list")) item_append(_("External DAT View"), "", 0, (void *)EXTERNAL_DATS); item_append(menu_item_type::SEPARATOR); diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp index 36edddc66b2..c025f75e202 100644 --- a/src/frontend/mame/ui/selgame.cpp +++ b/src/frontend/mame/ui/selgame.cpp @@ -14,7 +14,6 @@ #include "ui/ui.h" #include "ui/miscmenu.h" -#include "ui/datfile.h" #include "ui/inifile.h" #include "ui/datmenu.h" #include "ui/optsmenu.h" @@ -33,23 +32,10 @@ #include "rendutil.h" #include "softlist_dev.h" #include "uiinput.h" - +#include "luaengine.h" extern const char UI_VERSION_TAG[]; namespace ui { -namespace { -char const *const dats_info[] = { - __("General Info"), - __("History"), - __("Mameinfo"), - __("Sysinfo"), - __("Messinfo"), - __("Command"), - __("Gameinit"), - __("Mamescore") -}; - -} // anonymous namespace bool menu_select_game::first_start = true; std::vector<const game_driver *> menu_select_game::m_sortedlist; @@ -61,10 +47,6 @@ int menu_select_game::m_isabios = 0; menu_select_game::menu_select_game(mame_ui_manager &mui, render_container &container, const char *gamename) : menu_select_launch(mui, container, false) - , m_info_buffer() - , m_info_driver(nullptr) - , m_info_software(nullptr) - , m_info_view(-1) { highlight = 0; std::string error_string, last_filter, sub_filter; @@ -139,10 +121,11 @@ menu_select_game::menu_select_game(mame_ui_manager &mui, render_container &conta mui.machine().options().set_value(OPTION_SOFTWARENAME, "", OPTION_PRIORITY_CMDLINE, error_string); ui_globals::curimage_view = FIRST_VIEW; - ui_globals::curdats_view = UI_FIRST_LOAD; + ui_globals::curdats_view = 0; ui_globals::switch_image = false; ui_globals::default_image = true; ui_globals::panels_status = moptions.hide_panels(); + ui_globals::curdats_total = 1; m_searchlist[0] = nullptr; } @@ -270,7 +253,7 @@ void menu_select_game::handle() if (!isfavorite()) { const game_driver *drv = (const game_driver *)menu_event->itemref; - if ((FPTR)drv > skip_main_items && ui_globals::curdats_view > UI_FIRST_LOAD) + if ((FPTR)drv > skip_main_items && ui_globals::curdats_view > 0) { ui_globals::curdats_view--; m_topline_datsview = 0; @@ -279,7 +262,7 @@ void menu_select_game::handle() else { ui_software_info *drv = (ui_software_info *)menu_event->itemref; - if (drv->startempty == 1 && ui_globals::curdats_view > UI_FIRST_LOAD) + if (drv->startempty == 1 && ui_globals::curdats_view > 0) { ui_globals::curdats_view--; m_topline_datsview = 0; @@ -308,7 +291,7 @@ void menu_select_game::handle() if (!isfavorite()) { const game_driver *drv = (const game_driver *)menu_event->itemref; - if ((FPTR)drv > skip_main_items && ui_globals::curdats_view < UI_LAST_LOAD) + if ((FPTR)drv > skip_main_items && ui_globals::curdats_view < ui_globals::curdats_total) { ui_globals::curdats_view++; m_topline_datsview = 0; @@ -317,12 +300,12 @@ void menu_select_game::handle() else { ui_software_info *drv = (ui_software_info *)menu_event->itemref; - if (drv->startempty == 1 && ui_globals::curdats_view < UI_LAST_LOAD) + if (drv->startempty == 1 && ui_globals::curdats_view < ui_globals::curdats_total) { ui_globals::curdats_view++; m_topline_datsview = 0; } - else if ((FPTR)drv > skip_main_items && ui_globals::cur_sw_dats_view < 1) + else if ((FPTR)drv > skip_main_items && ui_globals::cur_sw_dats_view < ui_globals::cur_sw_dats_total) { ui_globals::cur_sw_dats_view++; m_topline_datsview = 0; @@ -362,19 +345,18 @@ void menu_select_game::handle() if (!isfavorite()) { const game_driver *driver = (const game_driver *)menu_event->itemref; - if ((FPTR)driver > skip_main_items && mame_machine_manager::instance()->datfile().has_data(driver)) + if ((FPTR)driver > skip_main_items && mame_machine_manager::instance()->lua()->call_plugin(driver->name, "data_list")) menu::stack_push<menu_dats_view>(ui(), container(), driver); } else { ui_software_info *ui_swinfo = (ui_software_info *)menu_event->itemref; - datfile_manager &mdat = mame_machine_manager::instance()->datfile(); if ((FPTR)ui_swinfo > skip_main_items) { - if (ui_swinfo->startempty == 1 && mdat.has_history(ui_swinfo->driver)) + if (ui_swinfo->startempty == 1 && mame_machine_manager::instance()->lua()->call_plugin(ui_swinfo->driver->name, "data_list")) menu::stack_push<menu_dats_view>(ui(), container(), ui_swinfo->driver); - else if (mdat.has_software(ui_swinfo->listname, ui_swinfo->shortname, ui_swinfo->parentname) || !ui_swinfo->usage.empty()) + else if (mame_machine_manager::instance()->lua()->call_plugin(std::string(ui_swinfo->shortname).append(1, ',').append(ui_swinfo->listname).c_str(), "data_list") || !ui_swinfo->usage.empty()) menu::stack_push<menu_dats_view>(ui(), container(), ui_swinfo); } } @@ -1272,7 +1254,7 @@ void menu_select_game::general_info(const game_driver *driver, std::string &buff if (cloneof != -1) util::stream_format(str, _("Driver is Clone of: %1$-.100s\n"), driver_list::driver(cloneof).description); else - str << _("Driver is Parent\n"); + str << _("Driver is Parent:\n"); if (driver->flags & MACHINE_NOT_WORKING) str << _("Overall: NOT WORKING\n"); @@ -1340,6 +1322,24 @@ void menu_select_game::general_info(const game_driver *driver, std::string &buff else str << _("Roms Audit Pass: Disabled\nSamples Audit Pass: Disabled\n"); + std::istringstream istr(str.str()); + std::string line; + float spacewid = ui().get_char_width(0x200a); + str.clear(); + str.seekp(0); + str << "#jp\n"; + while(std::getline(istr, line)) + { + int nspace = floor((0.35 - ui().get_string_width(line.c_str())) / spacewid); + if(nspace < 5) + nspace = 5; + std::string newstr; + newstr.reserve((nspace * 3) + line.length()); + newstr.append(line.substr(0, line.find(':'))); + for(int i = 0; i < nspace; i++) + newstr.append("\xE2\x80\x8A"); + str << newstr.append(line.substr(line.find(':') + 1, line.npos)).append("\n"); + } buffer = str.str(); } @@ -1660,312 +1660,6 @@ float menu_select_game::draw_left_panel(float x1, float y1, float x2, float y2) } } -//------------------------------------------------- -// draw infos -//------------------------------------------------- - -void menu_select_game::infos_render(float origx1, float origy1, float origx2, float origy2) -{ - float const line_height = ui().get_line_height(); - float text_size = ui().options().infos_size(); - std::vector<int> xstart; - std::vector<int> xend; - - ui_software_info const *software; - game_driver const *driver; - get_selection(software, driver); - - if (software && ((software->startempty != 1) || !driver)) - { - m_info_driver = nullptr; - - float gutter_width = 0.4f * line_height * machine().render().ui_aspect() * 1.3f; - float ud_arrow_width = line_height * machine().render().ui_aspect(); - float oy1 = origy1 + line_height; - - // apply title to right panel - if (software->usage.empty()) - { - ui().draw_text_full(container(), _("History"), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, ui::text_layout::TRUNCATE, - mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); - ui_globals::cur_sw_dats_view = 0; - } - else - { - float title_size = 0.0f; - float txt_length = 0.0f; - std::string t_text[2]; - t_text[0] = _("History"); - t_text[1] = _("Usage"); - - for (auto & elem: t_text) - { - ui().draw_text_full(container(), elem.c_str(), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, ui::text_layout::TRUNCATE, - mame_ui_manager::NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_length, nullptr); - txt_length += 0.01f; - title_size = (std::max)(txt_length, title_size); - } - - rgb_t fgcolor = UI_TEXT_COLOR; - rgb_t bgcolor = UI_TEXT_BG_COLOR; - if (get_focus() == focused_menu::rightbottom) - { - fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00); - bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff); - } - - float middle = origx2 - origx1; - - if (bgcolor != UI_TEXT_BG_COLOR) - { - ui().draw_textured_box(container(), origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f), - origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); - } - - ui().draw_text_full(container(), t_text[ui_globals::cur_sw_dats_view].c_str(), origx1, origy1, origx2 - origx1, - ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr); - - draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::cur_sw_dats_view, 0, 1, title_size); - } - - if (m_info_software != software || m_info_view != ui_globals::cur_sw_dats_view) - { - m_info_buffer.clear(); - m_info_view = ui_globals::cur_sw_dats_view; - m_info_software = software; - if (ui_globals::cur_sw_dats_view == 0) - { - if (software->startempty == 1) - mame_machine_manager::instance()->datfile().load_data_info(software->driver, m_info_buffer, UI_HISTORY_LOAD); - else - mame_machine_manager::instance()->datfile().load_software_info(software->listname, m_info_buffer, software->shortname, software->parentname); - } - else - m_info_buffer = software->usage; - } - - if (m_info_buffer.empty()) - { - ui().draw_text_full(container(), _("No Infos Available"), origx1, (origy2 + origy1) * 0.5f, origx2 - origx1, ui::text_layout::CENTER, - ui::text_layout::WORD, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); - return; - } - else - { - m_total_lines = ui().wrap_text(container(), m_info_buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size); - } - - int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size)); - if (m_total_lines < r_visible_lines) - r_visible_lines = m_total_lines; - if (m_topline_datsview < 0) - m_topline_datsview = 0; - if (m_topline_datsview + r_visible_lines >= m_total_lines) - m_topline_datsview = m_total_lines - r_visible_lines; - - for (int r = 0; r < r_visible_lines; ++r) - { - int itemline = r + m_topline_datsview; - std::string tempbuf(m_info_buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline])); - - // up arrow - if (r == 0 && m_topline_datsview != 0) - draw_info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width); - // bottom arrow - else if (r == r_visible_lines - 1 && itemline != m_total_lines - 1) - draw_info_arrow(1, origx1, origx2, oy1, line_height, text_size, ud_arrow_width); - else - ui().draw_text_full(container(), tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1, ui::text_layout::LEFT, - ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size); - oy1 += (line_height * text_size); - } - - // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow - right_visible_lines = r_visible_lines - (m_topline_datsview != 0) - (m_topline_datsview + r_visible_lines != m_total_lines); - } - else if (driver) - { - m_info_software = nullptr; - - float gutter_width = 0.4f * line_height * machine().render().ui_aspect() * 1.3f; - float ud_arrow_width = line_height * machine().render().ui_aspect(); - float oy1 = origy1 + line_height; - - // MAMESCORE? Full size text - if (ui_globals::curdats_view == UI_STORY_LOAD) - text_size = 1.0f; - - std::string snaptext(_(dats_info[ui_globals::curdats_view])); - - // apply title to right panel - float title_size = 0.0f; - float txt_length = 0.0f; - - for (int x = UI_FIRST_LOAD; x < UI_LAST_LOAD; ++x) - { - ui().draw_text_full(container(), _(dats_info[x]), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, - ui::text_layout::NEVER, mame_ui_manager::NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_length, nullptr); - txt_length += 0.01f; - title_size = (std::max)(txt_length, title_size); - } - - rgb_t fgcolor = UI_TEXT_COLOR; - rgb_t bgcolor = UI_TEXT_BG_COLOR; - if (get_focus() == focused_menu::rightbottom) - { - fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00); - bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff); - } - - float middle = origx2 - origx1; - - // check size - float sc = title_size + 2.0f * gutter_width; - float tmp_size = (sc > middle) ? ((middle - 2.0f * gutter_width) / sc) : 1.0f; - title_size *= tmp_size; - - if (bgcolor != UI_TEXT_BG_COLOR) - { - ui().draw_textured_box(container(), origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f), - origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); - } - - ui().draw_text_full(container(), snaptext.c_str(), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, - ui::text_layout::NEVER, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr, tmp_size); - - draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::curdats_view, UI_FIRST_LOAD, UI_LAST_LOAD, title_size); - - if (driver != m_info_driver || ui_globals::curdats_view != m_info_view) - { - m_info_buffer.clear(); - m_info_driver = driver; - m_info_view = ui_globals::curdats_view; - m_topline_datsview = 0; - m_total_lines = 0; - std::vector<std::string> m_item; - - if (ui_globals::curdats_view == UI_GENERAL_LOAD) - general_info(driver, m_info_buffer); - else if (ui_globals::curdats_view != UI_COMMAND_LOAD) - mame_machine_manager::instance()->datfile().load_data_info(driver, m_info_buffer, ui_globals::curdats_view); - else - mame_machine_manager::instance()->datfile().command_sub_menu(driver, m_item); - - if (!m_item.empty() && ui_globals::curdats_view == UI_COMMAND_LOAD) - { - for (size_t x = 0; x < m_item.size(); ++x) - { - std::string t_buffer; - m_info_buffer.append(m_item[x]).append("\n"); - mame_machine_manager::instance()->datfile().load_command_info(t_buffer, m_item[x]); - if (!t_buffer.empty()) - m_info_buffer.append(t_buffer).append("\n"); - } - convert_command_glyph(m_info_buffer); - } - } - - if (m_info_buffer.empty()) - { - ui().draw_text_full(container(), _("No Infos Available"), origx1, (origy2 + origy1) * 0.5f, origx2 - origx1, ui::text_layout::CENTER, - ui::text_layout::WORD, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); - return; - } - else if (ui_globals::curdats_view != UI_STORY_LOAD && ui_globals::curdats_view != UI_COMMAND_LOAD) - m_total_lines = ui().wrap_text(container(), m_info_buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size); - else - m_total_lines = ui().wrap_text(container(), m_info_buffer.c_str(), 0.0f, 0.0f, 1.0f - (2.0f * gutter_width), xstart, xend, text_size); - - int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size)); - if (m_total_lines < r_visible_lines) - r_visible_lines = m_total_lines; - if (m_topline_datsview < 0) - m_topline_datsview = 0; - if (m_topline_datsview + r_visible_lines >= m_total_lines) - m_topline_datsview = m_total_lines - r_visible_lines; - - sc = origx2 - origx1 - (2.0f * UI_BOX_LR_BORDER); - for (int r = 0; r < r_visible_lines; ++r) - { - int itemline = r + m_topline_datsview; - std::string tempbuf(m_info_buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline])); - - // up arrow - if (r == 0 && m_topline_datsview != 0) - draw_info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width); - // bottom arrow - else if (r == r_visible_lines - 1 && itemline != m_total_lines - 1) - draw_info_arrow(1, origx1, origx2, oy1, line_height, text_size, ud_arrow_width); - // special case for mamescore - else if (ui_globals::curdats_view == UI_STORY_LOAD) - { - // check size - float textlen = ui().get_string_width(tempbuf.c_str(), text_size); - float tmp_size2 = (textlen > sc) ? text_size * (sc / textlen) : text_size; - - size_t last_underscore = tempbuf.find_last_of("_"); - if (last_underscore == std::string::npos) - { - ui().draw_text_full(container(), tempbuf.c_str(), origx1, oy1, origx2 - origx1, ui::text_layout::CENTER, - ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, tmp_size2); - } - else - { - float effective_width = origx2 - origx1 - gutter_width; - float effective_left = origx1 + gutter_width; - std::string last_part(tempbuf.substr(last_underscore + 1)); - std::string first_part(tempbuf.substr(0, tempbuf.find("___"))); - float item_width; - - ui().draw_text_full(container(), first_part.c_str(), effective_left, oy1, effective_width, - ui::text_layout::LEFT, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &item_width, nullptr, tmp_size2); - - ui().draw_text_full(container(), last_part.c_str(), effective_left + item_width, oy1, - origx2 - origx1 - 2.0f * gutter_width - item_width, ui::text_layout::RIGHT, ui::text_layout::TRUNCATE, - mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, tmp_size2); - } - } - - // special case for command - else if (ui_globals::curdats_view == UI_COMMAND_LOAD || ui_globals::curdats_view == UI_GENERAL_LOAD) - { - // check size - float textlen = ui().get_string_width(tempbuf.c_str(), text_size); - float tmp_size3 = (textlen > sc) ? text_size * (sc / textlen) : text_size; - - int first_dspace = (ui_globals::curdats_view == UI_COMMAND_LOAD) ? tempbuf.find(" ") : tempbuf.find(":"); - if (first_dspace > 0) - { - float effective_width = origx2 - origx1 - gutter_width; - float effective_left = origx1 + gutter_width; - std::string first_part(tempbuf.substr(0, first_dspace)); - std::string last_part(tempbuf.substr(first_dspace + 1)); - strtrimspace(last_part); - ui().draw_text_full(container(), first_part.c_str(), effective_left, oy1, effective_width, ui::text_layout::LEFT, - ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, tmp_size3); - - ui().draw_text_full(container(), last_part.c_str(), effective_left, oy1, origx2 - origx1 - 2.0f * gutter_width, - ui::text_layout::RIGHT, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, tmp_size3); - } - else - { - ui().draw_text_full(container(), tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1, ui::text_layout::LEFT, - ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, tmp_size3); - } - } - else - { - ui().draw_text_full(container(), tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1, ui::text_layout::LEFT, - ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size); - } - - oy1 += (line_height * text_size); - } - - // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow - right_visible_lines = r_visible_lines - (m_topline_datsview != 0) - (m_topline_datsview + r_visible_lines != m_total_lines); - } -} //------------------------------------------------- @@ -1986,7 +1680,6 @@ void menu_select_game::get_selection(ui_software_info const *&software, game_dri } } - void menu_select_game::make_topbox_text(std::string &line0, std::string &line1, std::string &line2) const { inifile_manager &inifile = mame_machine_manager::instance()->inifile(); diff --git a/src/frontend/mame/ui/selgame.h b/src/frontend/mame/ui/selgame.h index 699d9222f1b..097db9ddbb6 100644 --- a/src/frontend/mame/ui/selgame.h +++ b/src/frontend/mame/ui/selgame.h @@ -43,11 +43,6 @@ private: static int m_isabios; int highlight; - std::string m_info_buffer; - game_driver const *m_info_driver; - ui_software_info const *m_info_software; - int m_info_view; - static std::vector<const game_driver *> m_sortedlist; std::vector<const game_driver *> m_availsortedlist; std::vector<const game_driver *> m_unavailsortedlist; @@ -88,9 +83,7 @@ private: } // General info - void general_info(const game_driver *driver, std::string &buffer); - - virtual void infos_render(float x1, float y1, float x2, float y2) override; + virtual void general_info(const game_driver *driver, std::string &buffer) override; // handlers void inkey_select(const event *menu_event); diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp index 6894603b990..20f80651307 100644 --- a/src/frontend/mame/ui/selmenu.cpp +++ b/src/frontend/mame/ui/selmenu.cpp @@ -29,6 +29,7 @@ #include "rendutil.h" #include "softlist.h" #include "uiinput.h" +#include "luaengine.h" #include <algorithm> #include <cmath> @@ -153,6 +154,10 @@ menu_select_launch::menu_select_launch(mame_ui_manager &mui, render_container &c , m_total_lines(0) , m_topline_datsview(0) , m_ui_error(false) + , m_info_driver(nullptr) + , m_info_software(nullptr) + , m_info_view(-1) + , m_info_buffer() , m_cache() , m_is_swlist(is_swlist) , m_focus(focused_menu::main) @@ -493,7 +498,9 @@ void menu_select_launch::draw_common_arrow(float origx1, float origy1, float ori } // apply arrow - if (current == dmin) + if (dmax == dmin) + return; + else if (current == dmin) draw_arrow(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor_right, ROT90); else if (current == dmax) draw_arrow(al_x0, al_y0, al_x1, al_y1, fgcolor_left, ROT90 ^ ORIENTATION_FLIP_X); @@ -1871,4 +1878,211 @@ void menu_select_launch::exit(running_machine &machine) s_caches.erase(&machine); } +//------------------------------------------------- +// draw infos +//------------------------------------------------- + +void menu_select_launch::infos_render(float origx1, float origy1, float origx2, float origy2) +{ + float const line_height = ui().get_line_height(); + float text_size = ui().options().infos_size(); + std::vector<int> xstart; + std::vector<int> xend; + const char *first = ""; + ui_software_info const *software; + game_driver const *driver; + int total; + get_selection(software, driver); + + if (software && ((software->startempty != 1) || !driver)) + { + m_info_driver = nullptr; + first = "Usage"; + + if (m_info_software != software || m_info_view != ui_globals::cur_sw_dats_view) + { + m_info_buffer.clear(); + if (software == m_info_software) + { + m_info_view = ui_globals::cur_sw_dats_view; + } + else + { + m_info_view = 0; + m_info_software = software; + ui_globals::cur_sw_dats_view = 0; + ui_globals::cur_sw_dats_total = 1; + + const char *lua_list = mame_machine_manager::instance()->lua()->call_plugin(std::string(software->shortname).append(1, ',').append(software->listname).c_str(), "data_list"); + m_items_list.clear(); + if(lua_list) + { + std::string list(lua_list); + char *token = strtok((char *)list.c_str(), ","); + while(token) + { + ui_globals::cur_sw_dats_total++; + m_items_list.emplace_back(token); + token = strtok(nullptr, ","); + } + } + } + + if (m_info_view == 0) + m_info_buffer = software->usage; + else + m_info_buffer = mame_machine_manager::instance()->lua()->call_plugin(util::string_format("%d", m_info_view - 1).c_str(), "data"); + } + total = ui_globals::cur_sw_dats_total; + } + else if (driver) + { + m_info_software = nullptr; + first = "General Info"; + + if (driver != m_info_driver || ui_globals::curdats_view != m_info_view) + { + m_info_buffer.clear(); + if (driver == m_info_driver) + { + m_info_view = ui_globals::curdats_view; + } + else + { + m_info_driver = driver; + m_info_view = 0; + ui_globals::curdats_view = 0; + ui_globals::curdats_total = 1; + + const char *lua_list = mame_machine_manager::instance()->lua()->call_plugin(driver->name, "data_list"); + m_items_list.clear(); + if(lua_list) + { + std::string list(lua_list); + char *token = strtok((char *)list.c_str(), ","); + while(token) + { + ui_globals::curdats_total++; + m_items_list.emplace_back(token); + token = strtok(nullptr, ","); + } + } + } + + if (m_info_view == 0) + general_info(driver, m_info_buffer); + else + m_info_buffer = mame_machine_manager::instance()->lua()->call_plugin(util::string_format("%d", m_info_view - 1).c_str(), "data"); + } + total = ui_globals::curdats_total; + } + else + return; + + float gutter_width = 0.4f * line_height * machine().render().ui_aspect() * 1.3f; + float ud_arrow_width = line_height * machine().render().ui_aspect(); + float oy1 = origy1 + line_height; + + std::string snaptext; + if (m_info_view) + snaptext = _(m_items_list[m_info_view - 1].c_str()); + else + snaptext = _(first); + + // apply title to right panel + float title_size = 0.0f; + float txt_length = 0.0f; + + for (int x = 0; x < ui_globals::curdats_total; ++x) + { + const char *name; + if(!x) + name = first; + else + name = m_items_list[x - 1].c_str(); + ui().draw_text_full(container(), _(name), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, + ui::text_layout::NEVER, mame_ui_manager::NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_length, nullptr); + txt_length += 0.01f; + title_size = (std::max)(txt_length, title_size); + } + + rgb_t fgcolor = UI_TEXT_COLOR; + rgb_t bgcolor = UI_TEXT_BG_COLOR; + if (get_focus() == focused_menu::rightbottom) + { + fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00); + bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff); + } + + float middle = origx2 - origx1; + + // check size + float sc = title_size + 2.0f * gutter_width; + float tmp_size = (sc > middle) ? ((middle - 2.0f * gutter_width) / sc) : 1.0f; + title_size *= tmp_size; + + if (bgcolor != UI_TEXT_BG_COLOR) + { + ui().draw_textured_box(container(), origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f), + origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); + } + + ui().draw_text_full(container(), snaptext.c_str(), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, + ui::text_layout::NEVER, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr, tmp_size); + + char justify = 'l'; // left justify + if ((m_info_buffer.length() >= 3) && (m_info_buffer[0] == '#')) + { + if (m_info_buffer[1] == 'j') + justify = m_info_buffer[2]; + } + + draw_common_arrow(origx1, origy1, origx2, origy2, m_info_view, 0, total - 1, title_size); + if (justify == 'f') + m_total_lines = ui().wrap_text(container(), m_info_buffer.c_str(), 0.0f, 0.0f, 1.0f - (2.0f * gutter_width), xstart, xend, text_size); + else + m_total_lines = ui().wrap_text(container(), m_info_buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size); + + int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size)); + if (m_total_lines < r_visible_lines) + r_visible_lines = m_total_lines; + if (m_topline_datsview < 0) + m_topline_datsview = 0; + if (m_topline_datsview + r_visible_lines >= m_total_lines) + m_topline_datsview = m_total_lines - r_visible_lines; + + sc = origx2 - origx1 - (2.0f * UI_BOX_LR_BORDER); + for (int r = 0; r < r_visible_lines; ++r) + { + int itemline = r + m_topline_datsview; + std::string tempbuf(m_info_buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline])); + if (tempbuf[0] == '#') + continue; + + // up arrow + if (r == 0 && m_topline_datsview != 0) + draw_info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width); + // bottom arrow + else if (r == r_visible_lines - 1 && itemline != m_total_lines - 1) + draw_info_arrow(1, origx1, origx2, oy1, line_height, text_size, ud_arrow_width); + else if (justify == 'f' || justify == 'p') // full or partial justify + { + // check size + float textlen = ui().get_string_width(tempbuf.c_str(), text_size); + float tmp_size3 = (textlen > sc) ? text_size * (sc / textlen) : text_size; + ui().draw_text_full(container(), tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1, ui::text_layout::LEFT, + ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, tmp_size3); + } + else + { + ui().draw_text_full(container(), tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1, ui::text_layout::LEFT, + ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size); + } + + oy1 += (line_height * text_size); + } + // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow + right_visible_lines = r_visible_lines - (m_topline_datsview != 0) - (m_topline_datsview + r_visible_lines != m_total_lines); +} + } // namespace ui diff --git a/src/frontend/mame/ui/selmenu.h b/src/frontend/mame/ui/selmenu.h index 99838673e36..9b1e4c41d62 100644 --- a/src/frontend/mame/ui/selmenu.h +++ b/src/frontend/mame/ui/selmenu.h @@ -115,8 +115,15 @@ private: // draw left panel virtual float draw_left_panel(float x1, float y1, float x2, float y2) = 0; + game_driver const *m_info_driver; + ui_software_info const *m_info_software; + int m_info_view; + std::vector<std::string> m_items_list; + std::string m_info_buffer; + // draw infos - virtual void infos_render(float x1, float y1, float x2, float y2) = 0; + void infos_render(float x1, float y1, float x2, float y2); + virtual void general_info(const game_driver *driver, std::string &buffer) = 0; // get selected software and/or driver virtual void get_selection(ui_software_info const *&software, game_driver const *&driver) const = 0; diff --git a/src/frontend/mame/ui/selsoft.cpp b/src/frontend/mame/ui/selsoft.cpp index 858a29e36fe..127b6c0ce54 100644 --- a/src/frontend/mame/ui/selsoft.cpp +++ b/src/frontend/mame/ui/selsoft.cpp @@ -14,7 +14,6 @@ #include "ui/ui.h" #include "ui/datmenu.h" -#include "ui/datfile.h" #include "ui/inifile.h" #include "ui/selector.h" @@ -26,6 +25,7 @@ #include "rendutil.h" #include "softlist_dev.h" #include "uiinput.h" +#include "luaengine.h" namespace ui { @@ -142,7 +142,8 @@ menu_select_software::menu_select_software(mame_ui_manager &mui, render_containe ui_globals::curimage_view = SNAPSHOT_VIEW; ui_globals::switch_image = true; - ui_globals::cur_sw_dats_view = UI_FIRST_LOAD; + ui_globals::cur_sw_dats_view = 0; + ui_globals::cur_sw_dats_total = 1; std::string error_string; mui.machine().options().set_value(OPTION_SOFTWARENAME, "", OPTION_PRIORITY_CMDLINE, error_string); @@ -224,7 +225,7 @@ void menu_select_software::handle() ui_globals::switch_image = true; ui_globals::default_image = false; } - else if (ui_globals::rpanel == RP_INFOS && ui_globals::cur_sw_dats_view < 1) + else if (ui_globals::rpanel == RP_INFOS && ui_globals::cur_sw_dats_view < ui_globals::cur_sw_dats_total) { // Infos ui_globals::cur_sw_dats_view++; @@ -245,11 +246,10 @@ void menu_select_software::handle() { // handle UI_DATS ui_software_info *ui_swinfo = (ui_software_info *)menu_event->itemref; - datfile_manager &mdat = mame_machine_manager::instance()->datfile(); - if (ui_swinfo->startempty == 1 && mdat.has_history(ui_swinfo->driver)) + if (ui_swinfo->startempty == 1 && mame_machine_manager::instance()->lua()->call_plugin(ui_swinfo->driver->name, "data_list")) menu::stack_push<menu_dats_view>(ui(), container(), ui_swinfo->driver); - else if (mdat.has_software(ui_swinfo->listname, ui_swinfo->shortname, ui_swinfo->parentname) || !ui_swinfo->usage.empty()) + else if (mame_machine_manager::instance()->lua()->call_plugin(std::string(ui_swinfo->shortname).append(1, ',').append(ui_swinfo->listname).c_str(), "data_list") || !ui_swinfo->usage.empty()) menu::stack_push<menu_dats_view>(ui(), container(), ui_swinfo); } else if (menu_event->iptkey == IPT_UI_LEFT_PANEL) @@ -339,7 +339,7 @@ void menu_select_software::handle() ui_globals::switch_image = true; ui_globals::default_image = false; } - else if (ui_globals::rpanel == RP_INFOS && ui_globals::cur_sw_dats_view < 1) + else if (ui_globals::rpanel == RP_INFOS && ui_globals::cur_sw_dats_view < ui_globals::cur_sw_dats_total) { // Infos ui_globals::cur_sw_dats_view++; @@ -1259,151 +1259,6 @@ float menu_select_software::draw_left_panel(float x1, float y1, float x2, float } //------------------------------------------------- -// draw infos -//------------------------------------------------- - -void menu_select_software::infos_render(float origx1, float origy1, float origx2, float origy2) -{ - float line_height = ui().get_line_height(); - static std::string buffer; - std::vector<int> xstart; - std::vector<int> xend; - float text_size = ui().options().infos_size(); - ui_software_info *soft = (get_selection_ref() != nullptr) ? (ui_software_info *)get_selection_ref() : ((m_prev_selected != nullptr) ? (ui_software_info *)m_prev_selected : nullptr); - static ui_software_info *oldsoft = nullptr; - static int old_sw_view = -1; - - float gutter_width = 0.4f * line_height * machine().render().ui_aspect() * 1.3f; - float ud_arrow_width = line_height * machine().render().ui_aspect(); - float oy1 = origy1 + line_height; - - // apply title to right panel - if (soft != nullptr && soft->usage.empty()) - { - float title_size = 0.0f; - - ui().draw_text_full(container(), _("History"), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, ui::text_layout::TRUNCATE, - mame_ui_manager::NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &title_size, nullptr); - title_size += 0.01f; - - rgb_t fgcolor = UI_TEXT_COLOR; - rgb_t bgcolor = UI_TEXT_BG_COLOR; - if (get_focus() == focused_menu::rightbottom) - { - fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00); - bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff); - } - - float middle = origx2 - origx1; - - if (bgcolor != UI_TEXT_BG_COLOR) - ui().draw_textured_box(container(), origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f), - origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); - - ui().draw_text_full(container(), _("History"), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, ui::text_layout::NEVER, - mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr); - ui_globals::cur_sw_dats_view = 0; - } - else - { - float title_size = 0.0f; - float txt_lenght = 0.0f; - std::string t_text[2]; - t_text[0] = _("History"); - t_text[1] = _("Usage"); - - for (auto & elem : t_text) - { - ui().draw_text_full(container(), elem.c_str(), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, ui::text_layout::NEVER, - mame_ui_manager::NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_lenght, nullptr); - txt_lenght += 0.01f; - title_size = std::max(txt_lenght, title_size); - } - - rgb_t fgcolor = UI_TEXT_COLOR; - rgb_t bgcolor = UI_TEXT_BG_COLOR; - if (get_focus() == focused_menu::rightbottom) - { - fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00); - bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff); - } - - float middle = origx2 - origx1; - - // check size - float sc = title_size + 2.0f * gutter_width; - float tmp_size = (sc > middle) ? ((middle - 2.0f * gutter_width) / sc) : 1.0f; - title_size *= tmp_size; - - if (bgcolor != UI_TEXT_BG_COLOR) - ui().draw_textured_box(container(), origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f), - origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); - - ui().draw_text_full(container(), t_text[ui_globals::cur_sw_dats_view].c_str(), origx1, origy1, origx2 - origx1, - ui::text_layout::CENTER, ui::text_layout::NEVER, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr, tmp_size); - - draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::cur_sw_dats_view, 0, 1, title_size); - } - - if (oldsoft != soft || old_sw_view != ui_globals::cur_sw_dats_view) - { - buffer.clear(); - old_sw_view = ui_globals::cur_sw_dats_view; - oldsoft = soft; - if (ui_globals::cur_sw_dats_view == 0) - { - if (soft->startempty == 1) - mame_machine_manager::instance()->datfile().load_data_info(soft->driver, buffer, UI_HISTORY_LOAD); - else - mame_machine_manager::instance()->datfile().load_software_info(soft->listname, buffer, soft->shortname, soft->parentname); - } - else - buffer = soft->usage; - } - - if (buffer.empty()) - { - ui().draw_text_full(container(), _("No Infos Available"), origx1, (origy2 + origy1) * 0.5f, origx2 - origx1, ui::text_layout::CENTER, - ui::text_layout::WORD, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); - return; - } - else - m_total_lines = ui().wrap_text(container(), buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size); - - int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size)); - if (m_total_lines < r_visible_lines) - r_visible_lines = m_total_lines; - if (m_topline_datsview < 0) - m_topline_datsview = 0; - if (m_topline_datsview + r_visible_lines >= m_total_lines) - m_topline_datsview = m_total_lines - r_visible_lines; - - for (int r = 0; r < r_visible_lines; ++r) - { - int itemline = r + m_topline_datsview; - std::string tempbuf; - tempbuf.assign(buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline])); - - // up arrow - if (r == 0 && m_topline_datsview != 0) - draw_info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width); - // bottom arrow - else if (r == r_visible_lines - 1 && itemline != m_total_lines - 1) - draw_info_arrow(1, origx1, origx2, oy1, line_height, text_size, ud_arrow_width); - else - ui().draw_text_full(container(), tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1, - ui::text_layout::LEFT, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, - nullptr, nullptr, text_size); - oy1 += (line_height * text_size); - } - - // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow - right_visible_lines = r_visible_lines - (m_topline_datsview != 0) - (m_topline_datsview + r_visible_lines != m_total_lines); -} - - - -//------------------------------------------------- // ctor //------------------------------------------------- diff --git a/src/frontend/mame/ui/selsoft.h b/src/frontend/mame/ui/selsoft.h index 1f18671f9d8..54186969de7 100644 --- a/src/frontend/mame/ui/selsoft.h +++ b/src/frontend/mame/ui/selsoft.h @@ -61,11 +61,11 @@ private: void find_matches(const char *str, int count); void load_sw_custom_filters(); - virtual void infos_render(float x1, float y1, float x2, float y2) override; - // handlers void inkey_select(const event *menu_event); void inkey_special(const event *menu_event); + + virtual void general_info(const game_driver *driver, std::string &buffer) override {} }; class software_parts : public menu diff --git a/src/frontend/mame/ui/utils.cpp b/src/frontend/mame/ui/utils.cpp index a2b9fd95e32..0f80d20be6e 100644 --- a/src/frontend/mame/ui/utils.cpp +++ b/src/frontend/mame/ui/utils.cpp @@ -40,6 +40,8 @@ size_t sw_filters::length = ARRAY_LENGTH(sw_filters::text); UINT8 ui_globals::rpanel = 0; UINT8 ui_globals::curimage_view = 0; UINT8 ui_globals::curdats_view = 0; +UINT8 ui_globals::cur_sw_dats_total = 0; +UINT8 ui_globals::curdats_total = 0; UINT8 ui_globals::cur_sw_dats_view = 0; bool ui_globals::switch_image = false; bool ui_globals::default_image = true; diff --git a/src/frontend/mame/ui/utils.h b/src/frontend/mame/ui/utils.h index 0c63d3961fe..b61c230f618 100644 --- a/src/frontend/mame/ui/utils.h +++ b/src/frontend/mame/ui/utils.h @@ -84,20 +84,6 @@ enum HIDE_BOTH }; -enum -{ - UI_FIRST_LOAD = 0, - UI_GENERAL_LOAD = UI_FIRST_LOAD, - UI_HISTORY_LOAD, - UI_MAMEINFO_LOAD, - UI_SYSINFO_LOAD, - UI_MESSINFO_LOAD, - UI_COMMAND_LOAD, - UI_GINIT_LOAD, - UI_STORY_LOAD, - UI_LAST_LOAD = UI_STORY_LOAD -}; - enum : UINT16 { UI_SW_FIRST = 0, @@ -202,7 +188,7 @@ struct c_year // GLOBAL CLASS struct ui_globals { - static UINT8 curimage_view, curdats_view, cur_sw_dats_view, rpanel; + static UINT8 curimage_view, curdats_view, curdats_total, cur_sw_dats_view, cur_sw_dats_total, rpanel; static bool switch_image, redraw_icon, default_image, reset; static int visible_main_lines, visible_sw_lines; static UINT16 panels_status; |
