Posts for Ilari


Post subject: Another VFR NHML fixup program
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
This is not well-tested so beware (I only tested with one encode)... This code alters Video NHMLs (used by MP4Box) to be timed like MKV timecode file specifies, and also at the same time fixes the corresponding audio NHML to make it sync with the new video timecodes. It is written in Lua and should run on all platforms (with enough memory) that have Lua reference interpretter (lua) available. Download NHMLFixup.lua
Language: lua

#!/usr/bin/env lua ---------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------- -- NHMLFixup v1 by Ilari (2010-09-16). -- Update timecodes in NHML Audio/Video track timing to conform to given MKV v2 timecodes file. -- Syntax: NHMLFixup <video-nhml-file> <audio-nhml-file> <mkv-timecodes-file> [<delay>] -- <delay> is number of milliseconds to delay the video (in order to compensate for audio codec delay, reportedly -- does not work right with some demuxers). ---------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------- -- Function load_timecode_file(FILE file, number timescale) -- Loads timecode data from file @file, using timescale of @timescale frames per second. Returns array of scaled -- timecodes. ---------------------------------------------------------------------------------------------------------------------- load_timecode_file = function(file, timescale) local line, ret; line = file:read("*l"); if line ~= "# timecode format v2" then error("Timecode file is not in MKV timecodes v2 format"); end ret = {}; while true do line = file:read("*l"); if not line then break; end local timecode = tonumber(line); if not timecode then error("Can't parse timecode '" .. line .. "'."); end table.insert(ret, math.floor(0.5 + timecode / 1000 * timescale)); end return ret; end ---------------------------------------------------------------------------------------------------------------------- -- Function make_reverse_index_table(Array array) -- Returns table, that has entry for each entry in given array @array with value being rank of value, 1 being smallest -- and #array the largest. If @lookup is non-nil, values are looked up from that array. ---------------------------------------------------------------------------------------------------------------------- make_reverse_index_table = function(array, lookup) local sorted, ret; local i; sorted = {}; for i = 1,#array do sorted[i] = array[i]; end table.sort(sorted); ret = {}; for i = 1,#sorted do ret[sorted[i]] = (lookup and lookup[i]) or i; end return ret; end ---------------------------------------------------------------------------------------------------------------------- -- Function max_causality_violaton(Array CTS, Array DTS) -- Return the maximum number of time units CTS and DTS values violate causality. #CTS must equal #DTS. ---------------------------------------------------------------------------------------------------------------------- max_causality_violation = function(CTS, DTS) local max_cv = 0; local i; for i = 1,#CTS do max_cv = math.max(max_cv, DTS[i] - CTS[i]); end return max_cv; end ---------------------------------------------------------------------------------------------------------------------- -- Function fixup_video_times(Array sampledata, Array timecodes, Number spec_delay) -- Fixes video timing of @sampledata (fields CTS and DTS) to be consistent with timecodes in @timecodes. Returns the -- CTS offset of first sample (for fixing audio). @spec_delay is special delay to add (to fix A/V sync). ---------------------------------------------------------------------------------------------------------------------- fixup_video_times = function(sampledata, timecodes, spec_delay) local cts_tab = {}; local dts_tab = {}; local k, v, i; if #sampledata ~= #timecodes then error("Number of samples (" .. #sampledata .. ") does not match number of timecodes (" .. #timecodes .. ")."); end for i = 1,#sampledata do cts_tab[i] = sampledata[i].CTS; dts_tab[i] = sampledata[i].DTS; end cts_lookup = make_reverse_index_table(cts_tab, timecodes); dts_lookup = make_reverse_index_table(dts_tab, timecodes); -- Perform time translation and find max causality violation. local max_cv = 0; for i = 1,#sampledata do sampledata[i].CTS = cts_lookup[sampledata[i].CTS]; sampledata[i].DTS = dts_lookup[sampledata[i].DTS]; max_cv = math.max(max_cv, sampledata[i].DTS - sampledata[i].CTS); end -- Add maximum causality violation to CTS to eliminate the causality violations. -- Also find the minimum CTS. local min_cts = 999999999999999999999; for i = 1,#sampledata do sampledata[i].CTS = sampledata[i].CTS + max_cv + spec_delay; --Spec_delay should not apply to audio. min_cts = math.min(min_cts, sampledata[i].CTS - spec_delay); end return min_cts; end ---------------------------------------------------------------------------------------------------------------------- -- Function fixup_video_times(Array sampledata, Number min_video_cts, Number video_timescale, Number audio_timescale) -- Fixes video timing of @sampledata (field CTS) to be consistent with video minimum CTS of @cts. Video timescale -- is assumed to be @video_timescale and audio timescale @audio_timescale. ---------------------------------------------------------------------------------------------------------------------- fixup_audio_times = function(sampledata, min_video_cts, video_timescale, audio_timescale) local fixup = math.floor(0.5 + min_video_cts * audio_timescale / video_timescale); for i = 1,#sampledata do sampledata[i].CTS = sampledata[i].CTS + fixup; end end ---------------------------------------------------------------------------------------------------------------------- -- Function translate_NHML_TS_in(Array sampledata); -- Translate NHML CTSOffset fields in @sampledata into CTS fields. ---------------------------------------------------------------------------------------------------------------------- translate_NHML_TS_in = function(sampledata, default_dDTS) local i; local dts = 0; for i = 1,#sampledata do if not sampledata[i].DTS then sampledata[i].DTS = dts + default_dDTS; end dts = sampledata[i].DTS; if sampledata[i].CTSOffset then sampledata[i].CTS = sampledata[i].CTSOffset + sampledata[i].DTS; else sampledata[i].CTS = sampledata[i].DTS; end end end ---------------------------------------------------------------------------------------------------------------------- -- Function translate_NHML_TS_out(Array sampledata); -- Translate CTS fields in @sampledata into NHML CTSOffset fields. ---------------------------------------------------------------------------------------------------------------------- translate_NHML_TS_out = function(sampledata) local i; for i = 1,#sampledata do sampledata[i].CTSOffset = sampledata[i].CTS - sampledata[i].DTS; if sampledata[i].CTSOffset < 0 then error("INTERNAL ERROR: translate_NHML_TS_out: Causality violation: CTS=" .. tostring( sampledata[i].CTS) .. " DTS=" .. tostring(sampledata[i].DTS) .. "."); end sampledata[i].CTS = nil; end end ---------------------------------------------------------------------------------------------------------------------- -- Function map_table_to_number(Table tab); -- Translate all numeric fields in table @tab into numbers. ---------------------------------------------------------------------------------------------------------------------- map_table_to_number = function(tab) local k, v; for k, v in pairs(tab) do local n = tonumber(v); if n then tab[k] = n; end end end ---------------------------------------------------------------------------------------------------------------------- -- Function map_fields_to_number(Array sampledata); -- Translate all numeric fields in array @sampledata into numbers. ---------------------------------------------------------------------------------------------------------------------- map_fields_to_number = function(sampledata) local i; for i = 1,#sampledata do map_table_to_number(sampledata[i]); end end ---------------------------------------------------------------------------------------------------------------------- -- Function escape_xml_text(String str) -- Return XML escaping of text str. ---------------------------------------------------------------------------------------------------------------------- escape_xml_text = function(str) str = string.gsub(str, "&", "&amp;"); str = string.gsub(str, "<", "&lt;"); str = string.gsub(str, ">", "&gt;"); str = string.gsub(str, "\"", "&quot;"); str = string.gsub(str, "\'", "&apos;"); return str; end ---------------------------------------------------------------------------------------------------------------------- -- Function escape_xml_text(String str) -- Return XML unescaping of text str. ---------------------------------------------------------------------------------------------------------------------- unescape_xml_text = function(str) str = string.gsub(str, "&apos;", "\'"); str = string.gsub(str, "&quot;", "\""); str = string.gsub(str, "&gt;", ">"); str = string.gsub(str, "&lt;", "<"); str = string.gsub(str, "&amp;", "&"); return str; end ---------------------------------------------------------------------------------------------------------------------- -- Function serialize_table_to_xml_entity(File file, String tag, Table data, bool noclose); -- Write @data as XML start tag of type @tag into @file. If noclose is true, then tag will not be closed. ---------------------------------------------------------------------------------------------------------------------- serialize_table_to_xml_entity = function(file, tag, data, noclose) local k, v; file:write("<" .. tag .. " "); for k, v in pairs(data) do file:write(k .. "=\"" .. escape_xml_text(tostring(v)) .. "\" "); end if noclose then file:write(">\n"); else file:write("/>\n"); end end ---------------------------------------------------------------------------------------------------------------------- -- Function serialize_array_to_xml_entity(File file, String tag, Array data); -- Write each element of @data as empty XML tag of type @tag into @file. ---------------------------------------------------------------------------------------------------------------------- serialize_array_to_xml_entity = function(file, tag, data) local i; for i = 1,#data do serialize_table_to_xml_entity(file, tag, data[i]); end end ---------------------------------------------------------------------------------------------------------------------- -- Function write_NHML_data(File file, Table header, Table sampledata) -- Write entiere NHML file. ---------------------------------------------------------------------------------------------------------------------- write_NHML_data = function(file, header, sampledata) file:write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); serialize_table_to_xml_entity(file, "NHNTStream", header, true); serialize_array_to_xml_entity(file, "NHNTSample", sampledata); file:write("</NHNTStream>\n"); end ---------------------------------------------------------------------------------------------------------------------- -- Function open_file_checked(String file, String mode, bool for_write) -- Return file handle to file (checking that open succeeds). ---------------------------------------------------------------------------------------------------------------------- open_file_checked = function(file, mode, for_write) local a, b; a, b = io.open(file, mode); if not a then error("Can't open '" .. file .. "': " .. b); end return a; end ---------------------------------------------------------------------------------------------------------------------- -- Function call_with_file(fun, string file, String mode, ...); -- Call fun with opened file handle to @file (in mode @mode) as first parameter. ---------------------------------------------------------------------------------------------------------------------- call_with_file = function(fun, file, mode, ...) -- FIXME: Handle nils returned from function. local handle = open_file_checked(file, mode); local ret = {fun(handle, ...)}; handle:close(); return unpack(ret); end ---------------------------------------------------------------------------------------------------------------------- -- Function xml_parse_tag(String line); -- Returns the xml tag type for @line plus table of attributes. ---------------------------------------------------------------------------------------------------------------------- xml_parse_tag = function(line) -- More regexping... local tagname; local attr = {}; tagname = string.match(line, "<(%S+).*>"); if not tagname then error("'" .. line .. "': Parse error."); end local k, v; for k, v in string.gmatch(line, "([^ =]+)=\"([^\"]*)\"") do attr[k] = unescape_xml_text(v); end return tagname, attr; end ---------------------------------------------------------------------------------------------------------------------- -- Function load_NHML(File file) -- Loads NHML file @file. Returns header table and samples array. ---------------------------------------------------------------------------------------------------------------------- load_NHML = function(file) -- Let's regexp this shit... local header = {}; local samples = {}; while true do local line = file:read(); if not line then error("Unexpected end of NHML file."); end local xtag, attributes; xtag, attributes = xml_parse_tag(line); if xtag == "NHNTStream" then header = attributes; elseif xtag == "NHNTSample" then table.insert(samples, attributes); elseif xtag == "/NHNTStream" then break; elseif xtag == "?xml" then else print("WARNING: Unrecognized tag '" .. xtag .. "'."); end end return header, samples; end ---------------------------------------------------------------------------------------------------------------------- -- Function reame_errcheck(String old, String new) -- Rename old to new. With error checking. ---------------------------------------------------------------------------------------------------------------------- rename_errcheck = function(old, new) local a, b; a, b = os.rename(old, new); if not a then error("Can't rename '" .. old .. "' -> '" .. new .. "': " .. b); end end if #arg < 3 or #arg > 4 then error("Syntax: NHMLFixup.lua <video.nhml> <audio.nhml> <timecodes.txt> [<delaycompensation>]"); end -- Load the NHML files. io.stdout:write("Loading '" .. arg[1] .. "'..."); io.stdout:flush(); video_header, video_samples = call_with_file(load_NHML, arg[1], "r"); io.stdout:write("Done.\n"); io.stdout:write("Loading '" .. arg[2] .. "'..."); io.stdout:flush(); audio_header, audio_samples = call_with_file(load_NHML, arg[2], "r"); io.stdout:write("Done.\n"); io.stdout:write("String to number conversion on video header..."); io.stdout:flush(); map_table_to_number(video_header); io.stdout:write("Done.\n"); io.stdout:write("String to number conversion on video samples..."); io.stdout:flush(); map_fields_to_number(video_samples); io.stdout:write("Done.\n"); io.stdout:write("String to number conversion on audio header..."); io.stdout:flush(); map_table_to_number(audio_header); io.stdout:write("Done.\n"); io.stdout:write("String to number conversion on audio samples..."); io.stdout:flush(); map_fields_to_number(audio_samples); io.stdout:write("Done.\n"); io.stdout:write("Computing CTS for video samples..."); io.stdout:flush(); translate_NHML_TS_in(video_samples, video_header.DTS_increment or 0); io.stdout:write("Done.\n"); io.stdout:write("Computing CTS for audio samples..."); io.stdout:flush(); translate_NHML_TS_in(audio_samples, audio_header.DTS_increment or 0); io.stdout:write("Done.\n"); -- Alter timescale if needed and load the timecode data. delay = 0; rdelay = 0; if arg[4] then local n = tonumber(arg[4]); if not n then error("Bad delay."); end rdelay = n; delay = math.floor(0.5 + rdelay / 1000 * video_header.timeScale); end timecode_data = call_with_file(load_timecode_file, arg[3], "r", video_header.timeScale); MAX_MP4BOX_TIMECODE = 0x7FFFFFF; if timecode_data[#timecode_data] > MAX_MP4BOX_TIMECODE then -- Workaround MP4Box bug. divider = math.ceil(timecode_data[#timecode_data] / MAX_MP4BOX_TIMECODE); print("Notice: Dividing timecodes by " .. divider .. " to workaround MP4Box timecode bug."); io.stdout:write("Performing division..."); io.stdout:flush(); video_header.timeScale = video_header.timeScale / divider; for i = 1,#timecode_data do timecode_data[i] = timecode_data[i] / divider; end --Recompute delay. delay = math.floor(0.5 + rdelay / 1000 * video_header.timeScale); io.stdout:write("Done.\n"); end -- Do the actual fixup. io.stdout:write("Fixing up video timecodes..."); io.stdout:flush(); audio_fixup = fixup_video_times(video_samples, timecode_data, delay); io.stdout:write("Done.\n"); io.stdout:write("Fixing up audio timecodes..."); io.stdout:flush(); fixup_audio_times(audio_samples, audio_fixup, video_header.timeScale, audio_header.timeScale); io.stdout:write("Done.\n"); -- Save the NHML files. io.stdout:write("Computing CTSOffset for video samples..."); io.stdout:flush(); translate_NHML_TS_out(video_samples); io.stdout:write("Done.\n"); io.stdout:write("Computing CTSOffset for audio samples..."); io.stdout:flush(); translate_NHML_TS_out(audio_samples); io.stdout:write("Done.\n"); io.stdout:write("Saving '" .. arg[1] .. ".tmp'..."); io.stdout:flush(); call_with_file(write_NHML_data, arg[1] .. ".tmp", "w", video_header, video_samples); io.stdout:write("Done.\n"); io.stdout:write("Saving '" .. arg[2] .. ".tmp'..."); io.stdout:flush(); call_with_file(write_NHML_data, arg[2] .. ".tmp", "w", audio_header, audio_samples); io.stdout:write("Done.\n"); io.stdout:write("Renaming '" .. arg[1] .. ".tmp' -> '" .. arg[1] .. "'..."); io.stdout:flush(); rename_errcheck(arg[1] .. ".tmp", arg[1]); io.stdout:write("Done.\n"); io.stdout:write("Renaming '" .. arg[2] .. ".tmp' -> '" .. arg[2] .. "'..."); io.stdout:flush(); rename_errcheck(arg[2] .. ".tmp", arg[2]); io.stdout:write("Done.\n"); io.stdout:write("All done.\n");
Post subject: Re: Video converter for JPC-RR r10.x video dumps
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
creaothceann wrote:
- framerate is currently fixed at 60 fps (which is just a dummy value) - the timestamps are not used in this version, so the frames will have the wrong timing; this needs more code or a container format like MKV
For R10 dumps, this is mostly OK, as r10.x versions have framerate fixed to 60fps (assuming single-segment source). Won't work for the R11 stuff (since that can even have runtime-variable framerate for single-segment source). And one could write timecodes file (matroska v2 timecodes seem to be most useful)... Format has header line "# timecode format v2" followed by timestamps (just a base-10 number; in milliseconds), one per line.
creaothceann wrote:
Afaik JPC-RR r11 will have a different dump file format and different tools, so this one won't work with it then.
s/will have/has/
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
Here are some (more significant) changes from r10.7 to r10.16 (as can be seen, they are mostly small bug fixes): - Don't lose stack trace data on some errors. - Fix bug in handling "OPTION ABSOLUTE" in movie files. - Allow printing image info from command line. - Lua can query movie length, rerecord count and main headers. - New author headers editor, supporting both full names and nicknames. - Allow binding multiple action sequence to same key. - Implement INT3_O16 and INTO_O16 in pmode (fixes some game). - Allow Lua to update display on stop/loadstate. - Allow Lua scripts to prompt for file to load/save to. - Support self-modifying code properly (DJGPP stuff no longer categorially instacrashes). - Fix "off-by-one" graphical glitching in mode13h. - Fix emulator wedging itself after enough savestates are made. - Loadstates should have less chance of hanging the whole emulator. - Fix some savestate/loadstate/ramdump operations from Lua. - Allow access to command-line imagemaker in .JAR builds.
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
The actual game itself actually runs as 320x240 which then gets upscaled to 640x480 due to clock halving and doublescanning being enabled (VGA BIOS sets those options and upscaling is done by VGA card). I just checked what is the actual size of frame 10.015s into the movie (this is about the time ball has left the plunger lane) using actual raw emulator dump output. It is 640x480. Note: Some games use different resolution in menus and in actual game. One should look what the resolution is in actual game.
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
Benchmarking the BIOS (time when "booting from 0000:7c00" message appears, rouned up to nearest millisecond): <Enter> the boot prompt, HDD only: 661ms <Enter> the boot prompt (subframe-optimized), HDD only: 661ms <F12><1> the boot prompt, HDD only: 667ms <Enter> the boot prompt, all HDx: 661ms <F12><1> the boot prompt, all HDx: 667ms The HD image is 16(cyliners)x63(sectors)x16(sides). FPU and SB present. I didn't subframe-optimize the inputs (unless otherwise noted). So it appears that: - putting the game as HDD is as good as putting it to all slots - <Enter> in boot prompt is sightly faster than <F12><1> - subframe-optimizing the clearing of boot prompt doesn't matter (usually).
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
Yes, there is Gamecube (and Wii) emulator (Dolphin). It even has TAS tools. Unfortunately they are currently not useful for real TASing (AFAIK those videos are edited from multiple segments) because Dolphin (GC/Wii emulator) is not sync-stable. AFAIK, someone is working on it... I agree that there are many good games to TAS on GC/Wii, so I am looking forward to see what pops up once GC/Wii is submittable.
Post subject: Re: RSS feed is being wonky
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
Clefaria wrote:
For a week or two now, the new movies RSS feed has been acting very strangely, giving links to obsoleted versions of movies. What in the world is going on? Can you guys fix it?
Making torrents for those movies that lack them. Due to the fact that first pass through all movies has finished, the rate of entries from updating movies will drop a lot (from tens of movies per day to update or few now and then).
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
OmnipotentEntity wrote:
yeah, 20 nice is the nicest possible. -19 nice is the meanest possible.
According to nice(1) manpage I have, 19 is the lowest of normal priorities and -20 is the highest of normal priorities. And indeed, trying to give nice of +20 to process results nice +19 process (Linux). Below normal priorities is idle priority, and above normal priorities are realtime priorities.
Post subject: Re: encoding on linux server
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
UploadBot wrote:
is there a way to encode using "idle" cpu? ie, priority = idle if so, which program should i use?
Install schedtool (its in package repostiories), and then to encode, run 'schedtool -D -e <rest of encode command>'. -D means run at idle priority, -e means execute given command.
UploadBot wrote:
also, what are good settings to host videos on my own server? i only have 100mbit, so i need a small filesize
Take a look at various encoding scripts posted in forums and wiki, since small filesize at high quality is important here. Also, CRF value is the most important for filesize-quality tradeoff. 20 is the usual high-quality value (sometimes bit larger numbers like 23 are used). Higher values result worse quality but smaller files. Then there are parameters that control CPU-time vs. filesize tradeoff. Increasing the CPU time used usually results smaller files (but one pretty quickly runs into decreasing returns).
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
The torrents do not expire. The torrents in question were manually deleted years ago (they were all obsolete movies at that time). The reason ones recently uploaded to archive seem to be "expiring" is that updated message comes from torrent being recreated, and that requires mirror to download the file to make torrent of. These torrents were not available before! Furthermore there is bug that causes caches to become stale if torrent has been deleted and then reuploaded. This requires manual intervention to flush the caches to make the torrent show up correctly.
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
Brushy wrote:
If I understood you correctly, you're pointing out that making emulator cores work on several different platforms is difficult, right? I think what scrimpeh was after is that there's a single GUI front-end that calls for different emulator cores when asked, so there won't be just a single core that has to manage with all of the emulation.
Well, what I'm talking about is single GUI (and perhaps some other common parts, possibly Lua VM, possibly movie code, etc..) calling number of emulator cores (one for each system or system group) for different systems (like NES core, SNES core, GBx core, Genesis core, etc...) The almost impossible part refers to systems that are pretty much totally different from common consoles, like PC(DOS) and MSX. These things also have really diverse configurations, where console configurations are quite limited.
Brushy wrote:
I actually think this is a great idea, but I'm a little pessimistic about it becoming reality in near future.
I'm pessimistic too. It is loads of work after all...
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
For console emulators, making one emulator capable of running them all could be feasible. But then there are computer emulators, which tend to be really different from console emulators, making merging almost impossible. But still, merging console emulators could be possible. The emulator core would have to export lots of functional parameters to generic part (the controller axis and button maps, how many controllers are possible, memory sizes, byte orders, etc...) the generic part would then offer UI based on these parameters (restricting input ranges and disabling options where needed). Ideally, Lua support would be part of generic part. Some Lua functions probably won't make sense on all systems but many do. Then there's the problem that 2D consoles (the generations of NES and SNES) should use 2D rendering to screen and 3D consoles (later generations) should use 3D rendering to screen. There's still fair amount of machines that can't properly handle 3D rendering.
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
rhebus wrote:
Kerio wrote:
How about we just measure CPU time? Consistant, fits nicely to a turn-based game like NetHack, wouldn't penalize multiletter commands too much.
It measures something which isn't the main goal. Also, you have to decide if you're measuring I/O (reading/writing level files to disk, redrawing the screen) or just pure CPU time.
All those operations themselves occur in zero time. Unless you mean completely ignoring I/O system call durations, which would be quite difficult to calculate.
rhebus wrote:
Another question: I have heard from the Duke Nukem thread that JPC-RR doesn't like playing movies if your hdd contents are different. As a result, do we need to agree on a standard defaults.nh file, or even a whole standard NH distribution? Would not matching byte-for-byte cause desyncs or would it just be awkward? A standard defaults.nh file could also prevent players using the ugly and difficult-to-follow extmenu to save keypresses on a minimal-keypress run.
Some extra files are needed anyway, because Nethack doesn't ship with any working DPMI extender (the one known to work is HXDPMI). That file could be put into separate floppy and run from there, but it can also be put together with game image. As for byte-to-byte identical disk images, Nethack might be special case that syncs even with quite different ROMs. One can edit the image name in movie if one wants to try if it syncs. No guarantees that such editing will give movie that syncs.
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
Derakon wrote:
However, regardless of how fast your computer is, you cannot possibly input more than one character per frame. Thus, measuring characters gives consistency for this game.
You can type faster than one key per frame. The limit for most main block keys is ~750 keys per second (20 cycles of ~15kHz clock) whereas VGA frame rate is far slower than that (limit comes from keyboard clocking emulation). The typing rate also depends on key. There are keys (mainly arrows and those keys above arrows) that take double time (and pause takes triple time).
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
List of days that are both Friday 13th and new moon (hope they are correct), 1980-2099. Numbers in parenthesis are number of days since JPC-RR epoch day: 1980-06-13 (3816) [before 3.4.3 release] 1983-05-13 (4880) [before 3.4.3 release] 1985-12-13 (5825) [before 3.4.3 release] 1994-05-13 (8898) [before 3.4.3 release] 1996-09-13 (9752) [before 3.4.3 release] 1999-08-13 (10816) [before 3.4.3 release] 2015-11-13 (16752) 2018-07-13 (17725) 2023-10-13 (19643) 2029-04-13 (21652) 2029-07-13 (21743) 2032-02-13 (22688) 2034-10-13 (23661) 2040-01-13 (25579) 2040-04-13 (25670) 2043-03-13 (26734) 2045-10-13 (27679) 2051-01-13 (29597) 2062-01-13 (33615) 2064-06-13 (34497) 2067-05-13 (35561) 2069-12-13 (36506) 2078-05-13 (39579) 2080-09-13 (40433) 2080-12-13 (40524) 2083-08-13 (41497) 2089-05-13 (43597) 2094-08-13 (45515) 2099-11-13 (47433)
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
moozooh wrote:
Oh… you mean things like opening/closing menus, entering inapplicable commands, etc.?
I don't know the specifics, but one example is trying to walk into wall (which is kind of "inapplicable command").
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
moozooh wrote:
rhebus wrote:
Is it possible to shuffle the RNG without advancing the in-game clock? How?
Oh wait, I guess I misunderstood what ais523 had said earlier. I was under the impression that you could shuffle the RNG by waiting for a certain amount of real-time frames between turns. If it's not the case and all the manipulation takes turns, I see no problems at all with minimum-turns any% runs.
ais523 wrote:
Minimum gametime has been suggested, but unfortunately, as it's possible to manipulate luck without spending any gametime
I guess "gametime" means turns. And no, its not real time waiting that's used to manipulate the RNG. There are some actions that do not consume turns but use randomness (manipulating the RNG). In fact, the only way real time affects anything is when game initializes its RNG on startup. Actually, Ais523 planned to do the run by using special hacked Linux version (modified to behave like DOS version would) recording the needed keyboard input and then just spamming that input (together with the boot sequence input) to emulator using Lua (which will cause final movie file (unless edited) to have RERECORDS 0).
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
Avoid The Noid: Runs, but with graphical corruption.
Looks like I broke something in r11-WIP (edit: fixed the CGA modes). The corruption looks similar to Moments of Mars and r10.12 (version I tested with, because I didn't have r10.13 .jar handy) didn't have that graphical glitch. And besides, run should be made using v1.1 barring v1.0. having serious glitches not present in v1.1 since v1.1 has FM music and EGA graphics (v1.0 had CGA).
Blake Stone: Runs, but with minor graphical glitches
NO_FPU hack fixes those graphical issues for me (by preventing game from using FPU).
Jetpack: Does not load (no error, just hangs after running) (I used the freeware version, not shareware)
I tried Freeware version and was able to enter first level and move there (IODELAY/HRETRACE/SB16/FPU)
Monuments of Mars: Runs, but with graphics issues
r10.x doesn't seem to have those issues (edit: neither do later r11-WIP versions). Unfortunately, text looks like mojibake (edit: I think it is caused by VGA BIOS not honoring user-defined characters and is still present in newest Qemu VGABIOS, so I can't do much about it).
Ninja: Runs, but with the same graphics issues
r10.x should not have the graphics corruption (edit: Also later r11-WIP versions should fix it).
Wolfenstein 3D: Does not load (no error, just hangs after running, with or without FPU)
That one runs for me. NO_FPU is needed to prevent graphical glitching. I tested both with shareware version and Blake Revolution, which is hack made using registered version.
Zone 66: I wasn't able to get it to run using the freedos boot disk, but it may be possible with a real DOS bootdisk
I get that game to start (edit: Strange, I can't get it to even load anymore). Unfortunately it does not work as it crashes instantly if you start the actual game.
Post subject: Re: Some thoughts
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
Critical five wrote:
Anyway, having filled myself the list a bit, I agree with Ilari's choice of categories (we'll see next April if there is a need to add an "April fool" categorie or something ;) )
BTW: 2530S isn't April Fools submission (2610S is). 2530S was requested test submission (actually second of them, the first was so broken it had to be deleted (it broke the site)).
Critical five wrote:
This also raises a question : should we list (some of the) cancelled submissions too ? Indeed, not a few cancelled submissions were in fact submissions that were to-be-rejected ; and the reasons they've been cancelled may be interesting too.
There's canceled submissions list already. And usually the reason for canceling run is either "will improve this", "already obsoleted" or "this would be rejected". Usually there's not that much information about reasons.
Critical five wrote:
This boils down to think about how the list should be organized (when it will be more mature of course). In alphabetical order ? Or should we arrange the list by categories ? This would help to put in place Randil's idea, but a problem appears when two categories (like Game/Optimization) apply to one submission.
If it was module, it would be easy to have it sorted in various orders. But as long as its manually kept, I think its better to keep it in submission order (so its easier to see missing submissions).
Post subject: RejectedSubmissions
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
I started Rejected Submissions page. The idea is to have every rejected submission plus short categorization (like 'bad game choice', 'bad optimization', 'wrong mode', etc...) of reason for its rejection. Adelikat had idea of making database table of it plus module, so that new rejections automatically appear in it (either to be filled or with cause given with rejection). Making this module would mean deciding the categories beforehand. Also, this should be done well, as recategorization would be quite a pain. Also, deciding on proper categorization would help even if there won't be module for it. Here's a list of few proposed categories:
    Bad game Bad goal choice Bad version (bad dump, using E instead of U, use another console) Bad mode (like using GB mode in SGB game, should be combined with bad settings?) Bad game settings (like playing on easy, should be combined with bad mode?) Incomplete (fails to complete the game) Breaks self-imposed restrictions Bad optimization (fails to beat records, visibly sloppy timewise or obsoleted while in queue) Entertainment (fails to entertain even with oppurtunities to do so) Plagiarized / Unathorized submission (submitting someone else's run as your own or without that person's aproval) Other
Also, maybe ones like:
    Sync (doesn't sync for others) Unapproved hack (pre-mid-2009 hack quickrejections, hacks obsoleted by other hacks (I don't think there are any examples of actual rejections due the latter)) Troll (extremely bad game choices (repeatedly), extremely bad optimization (repeatedly), using multiple accounts, etc...)
Comments?
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
C0DE RED wrote:
Flygon: That command prompt you posted works best on Linux, right?! If so, what's the best distro to use for encoding? I thought Mandriva and Ubuntu isn't so bad.
If you refer to script in first post, then its definitely for Windows. --deldup and --versioninfo are Direct264-only options (and Direct264 only is for Windows, but it seems to run fine in Wine, even on x64). Also the 'start /wait' part is dead giveaway. The linux version would be 'wine /path/to/x264.exe <rest of arguments here>'. Or if you don't need deldup (bit larger encodes, but you can use "native" x264), 'x264 <rest of arguments removing deldup and versioninfo>'. Also note that x264 may or may not support input from AVI and other containers (direct264 does) depending on what external libraries it is configured to use. If it doesn't support container input, you have to feed the data as raw YUV420p (ffmpeg or mplayer can generate it, I use mplayer for that becuase piping the data directly to x264 works, whereas I couldn't get that working with ffmpeg). On Linux, mplayer can be used for encoding too (don't ask me how, I have never gotten result that even passes basic sanity checks, such as A/V sync; others that use mplayer for encoding should know). Linux distro doesn't matter much apart from wheither there's prebuilt x264 for it (if not, you need to download direct264 and install wine or build x264 from source). But yeah, as said, there's much more to encoding than just the video compression, like: * Dumping the video (some emulators are easy in this regard, others are not-so-easy) * Fixing A/V desyncs in source material (if any, but dumping methods that produce severe desyncing should not be used) * Inserting subtitles * Inserting logo * encoding audio * final muxing If you want to try encoding stuff, I think it is good idea to first develop methods so that you can get encodes that have logo, good video (at least no blatant errors in colors or picture jumping all over the place), good subtitles, good audio (no staticy mess) and A/V sync. Use very fast encoding settings on this stage so you can test faster... Then work on encode sizes. Also As said, Windows encoding guides are mostly better than for Linux. Those guides usually can be fairly easily be (mostly) adopted to work on Linux (e.g. mencoder is available for both).
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
Should be fixed now.
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
FreezerBurns wrote:
Well, answer the simple question: Do episodes 2 and 3 run from the same .exe as episode 1? If yes, then put them all in a contiguous run. If no, then separate runs.
AFAIK, no they don't. I would argue to split the episodes if game does not let you continue after finishing an episode or have unlockable episodes (most PC games don't let you do that since finishing last level of episode is automatic "game over" with no continue option and all episodes are immediatlely selectable), since this effectively makes episodes independent play-wise. Seperate .exes is stronger condition, but I think that "no continue" condition is sufficient. So submit Duke Nukem 1 (episode 1) as its own run.
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
Arjin wrote:
Object in invalid state for operation (Unknown uCode V224)
Fixed in f06067996aa0946ea2c (no idea if the fix is correct, I only looked at architecture reference manuals on what these do (answer: throw GP fault)).
Post subject: Re: PC - Recordings
Emulator Coder, Experienced Forum User, Published Author, Skilled player (1142)
Joined: 5/1/2010
Posts: 1217
gunnargumpertTAS wrote:
Is there a kind of emulator, that emulates games form PC? i don't mean, the emulator is something like XP ore vista, it more just allow you to TAS any 3D games.
You mean DOS or Windows? If DOS, there's JPC-RR (allowed to be used in submissions, but a lot of games don't currently emulate correctly). For Windows, there was some project to implement rerecording (forum topic http://tasvideos.org/forum/viewtopic.php?t=8750 ). I don't know much about that project... It isn't approved for submissions.