New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please include the RocketLauncher Plugin in Windows Builds #348

Closed
progets opened this Issue Apr 28, 2017 · 4 comments

Comments

Projects
None yet
2 participants
@progets
Contributor

progets commented Apr 28, 2017

RocketLauncher has put the Attract-Mode plugin in their default build code more than 6 months ago. I think that Attract-Mode should do the same. It's only 2 files for a total of 12k so it's not like it's a big strain for people that aren't using it.

The Attract-Mode/RocketLauncher integration has fallen into the depths of old threads in the forum and it really brings a lot to the table for those that want the best of emulation. I think this really should be a part of the default Windows build since it's already built into RocketLauncher.

File 1 /attractmode/plugins/RocketLauncher/file_util.nut
`
///////////////////////////////////////////////////
//
// Attract-Mode Frontend - History.dat plugin
//
// File utilities
//
///////////////////////////////////////////////////
const READ_BLOCK_SIZE=80960;
local next_ln_overflow=""; // used by the get_next_ln() function
local idx_path = FeConfigDirectory + "history.idx/";
local loaded_idx = {};

//
// Write a single line of output to f
//
function write_ln( f, line )
{
local b = blob( line.len() );

for (local i=0; i<line.len(); i++)
	b.writen( line[i], 'b' );

f.writeblob( b );

}

//
// Get a single line of input from f
//
function get_next_ln( f )
{
local ln = next_ln_overflow;
next_ln_overflow="";
while ( !f.eos() )
{
local char = f.readn( 'b' );
if ( char == '\n' )
return strip( ln );

	ln += char.tochar();
}

next_ln_overflow=ln;
return "";

}

//
// Scan through f and return the next line starting with a "$"
//
function scan_for_ctrl_ln( f )
{
local char;
while ( !f.eos() )
{
char = f.readn( 'b' );
if (( char == '\n' ) && ( !f.eos() ))
{
char = f.readn( 'b' );
if ( char == '$' )
{
next_ln_overflow="$";
return get_next_ln( f );
}
}
}
return "";
}

//
// Generate our history.dat index files
//
function generate_index( config )
{
local histf_name = fe.path_expand( config[ "dat_path" ] );
local histf;

try
{
	histf = file( histf_name, "rb" );
}
catch ( e )
{
	return "Error opening file: " + histf_name;
}

local indices = {};

local last_per=0;

//
// Get an index for all the entries in history.dat
//
while ( !histf.eos() )
{
	local base_pos = histf.tell();
	local blb = histf.readblob( READ_BLOCK_SIZE );

	// Update the user with the percentage complete
	local percent = 100.0 * ( histf.tell().tofloat() / histf.len().tofloat() );
	if ( percent.tointeger() > last_per )
	{
		last_per = percent.tointeger();
		if ( fe.overlay.splash_message(
				"Generating index ("
				+ last_per + "%)" ) )
			break; // break loop if user cancels
	}
	
	while ( !blb.eos() )
	{
		local line = scan_for_ctrl_ln( blb );

		if ( line.len() < 5 ) // skips $bio, $end
			continue;

		local eq = line.find( "=", 1 );
		if ( eq != null )
		{
			local systems = split( line.slice(1,eq), "," );
			local roms = split( line.slice(eq+1), "," );

			foreach ( s in systems )
			{
				if ( !indices.rawin( s ) )
					indices[ s ] <- {};

				if ( config[ "index_clones" ] == "Yes" )
				{
					foreach ( r in roms )
						(indices[ s ])[ r ]
							<- ( base_pos + blb.tell() );
				}
				else if ( roms.len() > 0 )
				{
					(indices[ s ])[ roms[0] ]
						<- ( base_pos + blb.tell() );
				}
			}
		}
	}
}

//
// Make sure the directory we are writing to exists...
//
system( "mkdir \"" + idx_path + "\"" );

fe.overlay.splash_message( "Writing index file." );

//
// Now write an index file for each system encountered
//
foreach ( n,l in indices )
{
	local idx = file( idx_path + n + ".idx", "w" );
	foreach ( rn,ri in l )
		write_ln( idx, rn + ";" + ri + "\n" );

	idx.close();
}

histf.close();

return "Created index for " + indices.len()
	+ " systems in " + idx_path;

}

//
// Return the text for the history.dat entry after the given offset
//
function get_history_entry( offset, config )
{
local histf = file( fe.path_expand( config[ "dat_path" ] ), "rb" );
histf.seek( offset );

local entry = "\n\n"; // a bit of space to start
local open_entry = false;

while ( !histf.eos() )
{
	local blb = histf.readblob( READ_BLOCK_SIZE );
	while ( !blb.eos() )
	{
		local line = get_next_ln( blb );

		if ( !open_entry )
		{
			//
			// forward to the $bio tag
			//
			if (( line.len() < 1 )
					|| (  line != "$bio" ))
				continue;

			open_entry = true;
		}
		else
		{
			if ( line == "$end" )
			{
				entry += "\n\n";
				return entry;
			}
			else if (!(blb.eos() && ( line == "" )))
				entry += line + "\n";
		}
	}
}

return entry;

}

//
// Load the index for the given system if it is not already loaded
//
function load_index( sys )
{
// check if system index already loaded
//
if ( loaded_idx.rawin( sys ) )
return true;

local idx;
try
{
	idx = file( idx_path + sys + ".idx", "r" );
}
catch( e )
{
	loaded_idx[sys] <- null;
	return false;
}

loaded_idx[sys] <- {};

while ( !idx.eos() )
{
	local blb = idx.readblob( READ_BLOCK_SIZE );
	while ( !blb.eos() )
	{
		local line = get_next_ln( blb );
		local bits = split( line, ";" );
		if ( bits.len() > 0 )
			(loaded_idx[sys])[bits[0]] <- bits[1].tointeger();
	}
}

return true;

}

//
// Return the index the history.dat entry for the specified system and rom
//
function get_history_offset( sys, rom, alt, cloneof )
{
foreach ( s in sys )
{
if (( load_index( s ) )
&& ( loaded_idx[s] != null ))
{
if ( loaded_idx[s].rawin( rom ) )
return (loaded_idx[s])[rom];
else if ((alt.len() > 0 )
&& ( loaded_idx[s].rawin( alt ) ))
return (loaded_idx[s])[alt];
else if ((cloneof.len() > 0 )
&& ( loaded_idx[s].rawin( cloneof ) ))
return (loaded_idx[s])[cloneof];
}

}

if (( sys.len() != 1 ) || ( sys[0] != "info" ))
	return get_history_offset( ["info"], rom, alt, cloneof );

return -1;

}

`

File 2 /attractmode/plugins/RocketLauncher/plugin.nut
`
///////////////////////////////////////////////////
//
// Attract-Mode Frontend - UltraStik360 plugin
//
// A plugin that allows the intergration with RocketLauncher
// to be seamless
//
///////////////////////////////////////////////////

//
// The UserConfig class identifies plugin settings that can be configured
// from Attract-Mode's configuration menu
//

//To Do
// create a copy routine to save the files to Rocket Launcher
// create a routine to configure the emulators to have their settings changed
// see how both points above can be achieved without it running each time the plugin is used --> ask RayGun

class UserConfig </ help="Configure the RocketLauncher integration with AttractMode" /> {

</ label="Path to Rocketlauncher", help="Path Rocketlaucher e.g. D:\\Rocketlauncher\\", order=1 />
rlpath = "D:\\Rocketlauncher\\";

</ label="Path to Emulator Pics", help="Path to picture files representing every emulator", order=2 />
emulatorpic = "D:\\AttractMode\\media\\systemlogos\\";

</ label="screenshot(RL Background)", help="Determine which AttractMode Artwork should be used to show Rocketlauncher game backgrounds in the fade screen", options="none, snap,wheel, fanart,marquee,flyer", order=3 />
screenshot = "snap";

</ label="wheel art(RL Logo)", help="Determine which AttractMode Artwork should be used to show Rocketlauncher wheels/box art in the fade screen", options="none, snap,wheel, fanart,marquee,flyer", order=4 />
wheel = "wheel";

</ label="game_video(RL Video)", help="Determine which AttractMode Artwork should be used to show Rocketlauncher videos in the fade screen", options="none, snap,wheel, fanart,marquee,flyer", order=5 />
video = "snap";

</ label="game_marquee(RL Artwork)", help="Determine which AttractMode Artwork should be used to show Rocketlauncher game artwork in the fade screen ", options="none, snap,wheel, fanart,marquee,flyer", order=6 />
marquee = "marquee";

</ label="game_fanart(RL Artwork)", help="Determine which AttractMode Artwork should be used to show Rocketlauncher game artwork in the fade screen", options="none, snap,wheel, fanart,marquee,flyer", order=7 />
fanart = "fanart";

</ label="game_flyer(RL Artwork)", help="Determine which AttractMode Artwork should be used to show Rocketlauncher game artwork in the fade screen", options="none, snap,wheel, fanart,marquee,flyer", order=8 />
flyer = "flyer";	

};

// setup plugin
local config = fe.get_config();
local my_dir = fe.script_dir;
dofile( my_dir + "file_util.nut" );

// write the information to a file when a game is started
fe.add_transition_callback( "rocketlauncher_integration_transition" );

function rocketlauncher_integration_transition( ttype, var, ttime )
{

switch ( ttype )
{
	case Transition.ToGame:

	local rlfile = file("rl_integration.txt","wb+")
	local gameInfo = [];
	local gamestring = "#Name|Title|Emulator|CloneOf|Year|Manufacturer|Category|Players|Rotation|Control|Status|DisplayCount|DisplayType|AltRomname|AltTitle|Extra|Buttons|Rating\n";
	gameInfo.push(fe.game_info( Info.Name ));
	gameInfo.push(fe.game_info( Info.Title ));
	gameInfo.push(fe.game_info( Info.Emulator )); // current emulator
	gameInfo.push(fe.game_info( Info.CloneOf )); 
	gameInfo.push(fe.game_info( Info.Year ));
	gameInfo.push(fe.game_info( Info.Manufacturer ));
	gameInfo.push(fe.game_info( Info.Category ));
	gameInfo.push(fe.game_info( Info.Players ));
	gameInfo.push(fe.game_info( Info.Rotation ));
	gameInfo.push(fe.game_info( Info.Control ));
	gameInfo.push(fe.game_info( Info.Status ));
	gameInfo.push(fe.game_info( Info.DisplayCount ));
	gameInfo.push(fe.game_info( Info.DisplayType ));
	gameInfo.push(fe.game_info( Info.AltRomname ));
	gameInfo.push(fe.game_info( Info.AltTitle ));
	gameInfo.push(fe.game_info( Info.Extra ));
	gameInfo.push(fe.game_info( Info.Buttons ));
	gameInfo.push(fe.game_info( Info.Tags));

	foreach (value in gameInfo)
	{
		gamestring = gamestring + value + "|";
	}
	
	local screenshot = (config["screenshot"] == "none") ? "" : config["screenshot"];
	local wheel = (config["wheel"] == "none") ? "" : config["wheel"];
	local emulatorpic = config["emulatorpic"] + gameInfo[2] + ".png"
	local video = (config["video"] == "none") ? "" : config["video"];
	local marquee = (config["marquee"] == "none") ? "" : config["marquee"];
	local fanart = (config["fanart"] == "none") ? "" : config["fanart"];
	local flyer = (config["flyer"] == "none") ? "" : config["flyer"];
	
	screenshot = fe.get_art( screenshot,0,0, Art.ImagesOnly) + "|screenshot(RL Background)"
	wheel = fe.get_art( wheel ) + "|wheel art(RL Logo)"; 	
	emulatorpic = emulatorpic + "|emulator art(RL Logo)"; 
	video = fe.get_art( video ) + "|game_video(RL Video)"; 	
	marquee = fe.get_art( marquee ) + "|game_marquee(RL Artwork)";
	fanart = fe.get_art( fanart ) + "|game_fanart(RL Artwork)";
	flyer = fe.get_art( flyer ) + "|game_flyer(RL Artwork)"; 
	
	local artwork = [];
	local artworkstring = "";
	artwork.push(screenshot); // screenshot (RL Background)
	artwork.push(wheel); // current game wheel (RL Logo)
	artwork.push(emulatorpic); //  current system wheel (RL Logo)
	artwork.push(video); // videos (RL Video)
	artwork.push(marquee); // marquee (RL Artwork)
	artwork.push(fanart); // fanart (RL Artwork)
	artwork.push(flyer); // flyer (RL Artwork)

	// artwork.push("|screenshot(RL Background)");	// screenshot (RL Background)
	// artwork.push("|wheel art(RL Logo)"); 		// current game wheel (RL Logo)
	// artwork.push("|emulator art(RL Logo)"); 		// current system wheel (RL Logo)
	// artwork.push("|game_video(RL Video)"); 		// videos (RL Video)
	// artwork.push("|game_marquee(RL Artwork)"); 	// marquee (RL Artwork)
	// artwork.push("|game_fanart(RL Artwork)"); 	// fanart (RL Artwork)
	// artwork.push("|game_flyer(RL Artwork)"); 	// flyer (RL Artwork)
	
	foreach (value in artwork)
	{
		artworkstring = artworkstring + "\n" + value
	}
		
	write_ln( rlfile, gamestring + artworkstring );
	rlfile.close;
	break;

}

return false; // must return false

}

`

@progets

This comment has been minimized.

Show comment
Hide comment
@progets

progets Apr 28, 2017

Contributor

I pasted the contents of the files as code. I'm not sure why it came out like it did. This is the thread that has the post and download of the zip file but only the two files above need to be included http://forum.attractmode.org/index.php?topic=858.0.

Contributor

progets commented Apr 28, 2017

I pasted the contents of the files as code. I'm not sure why it came out like it did. This is the thread that has the post and download of the zip file but only the two files above need to be included http://forum.attractmode.org/index.php?topic=858.0.

@mickelson

This comment has been minimized.

Show comment
Hide comment
@mickelson

mickelson Oct 15, 2017

Owner

HI progets, sorry this is pretty old, could you create a pull request on git to add the files that you want added? I'd be happy to add them to the project here

Owner

mickelson commented Oct 15, 2017

HI progets, sorry this is pretty old, could you create a pull request on git to add the files that you want added? I'd be happy to add them to the project here

@mickelson

This comment has been minimized.

Show comment
Hide comment
@mickelson

mickelson Aug 14, 2018

Owner

@progets I know this request is old, but can you create a pull request on git to add the files that you want added? I'd be happy to add them to the project here

Owner

mickelson commented Aug 14, 2018

@progets I know this request is old, but can you create a pull request on git to add the files that you want added? I'd be happy to add them to the project here

@progets

This comment has been minimized.

Show comment
Hide comment
@progets

progets Aug 15, 2018

Contributor

I have created the pull request.

Contributor

progets commented Aug 15, 2018

I have created the pull request.

@mickelson mickelson closed this Aug 17, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment