Skip to content

Commit

Permalink
EmulatorJS - First Version (#23)
Browse files Browse the repository at this point in the history
* feat: added EmulatorJS support for Mega Drive, NES, and N64 (see: #15)

* doc: updated attribution in README.MD to include EmulatorJS

* ci: updated action to include submodules
  • Loading branch information
michael-j-green authored Jul 13, 2023
1 parent b010f97 commit 7a8e445
Show file tree
Hide file tree
Showing 17 changed files with 140 additions and 6 deletions.
Binary file modified .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .github/workflows/BuildDockerOnTag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ jobs:
-
name: Checkout
uses: actions/checkout@v3
with:
submodules: 'true'
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "gaseous-server/wwwroot/EmulatorJS"]
path = gaseous-server/wwwroot/EmulatorJS
url = https://github.com/EmulatorJS/EmulatorJS.git
3 changes: 2 additions & 1 deletion README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The following projects are used by Gaseous
* https://github.com/JamesNK/Newtonsoft.Json
* https://www.nuget.org/packages/MySql.Data/8.0.32.1
* https://github.com/kamranayub/igdb-dotnet
* https://github.com/EmulatorJS/EmulatorJS

## Configuration File
When Gaseous-Server is started for the first time, it creates a configuration file at ~/.gaseous-server/config.json if it doesn't exist. Some values can be filled in using environment variables (such as in the case of using docker).
Expand Down Expand Up @@ -105,4 +106,4 @@ Loop through each of the search candidates searching using:
2. "wherefuzzy" - partial match using wildcards
3. "search" - uses a more flexible search method

Note: that if more than one result is found, the image will be set as "Unknown" as there is no way for Gaseous to know which title is the correct one.
Note: that if more than one result is found, the image will be set as "Unknown" as there is no way for Gaseous to know which title is the correct one.
Binary file modified gaseous-server/.DS_Store
Binary file not shown.
14 changes: 14 additions & 0 deletions gaseous-server/Classes/Roms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,19 @@ private static GameRomItem BuildRom(DataRow romDR)
Path = (string)romDR["path"],
Source = (GameRomItem.SourceType)(Int32)romDR["metadatasource"]
};

// check for a web emulator and update the romItem
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in Models.PlatformMapping.PlatformMap)
{
if (platformMapping.IGDBId == romItem.PlatformId)
{
if (platformMapping.WebEmulator != null)
{
romItem.Emulator = platformMapping.WebEmulator;
}
}
}

return romItem;
}

Expand All @@ -115,6 +128,7 @@ public class GameRomItem
public long Id { get; set; }
public long PlatformId { get; set; }
public IGDB.Models.Platform Platform { get; set; }
public Dictionary<string, string>? Emulator { get; set; }
public long GameId { get; set; }
public string? Name { get; set; }
public long Size { get; set; }
Expand Down
1 change: 1 addition & 0 deletions gaseous-server/Controllers/GamesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,7 @@ public ActionResult GameRomDelete(long GameId, long RomId)
}

[HttpGet]
[HttpHead]
[Route("{GameId}/roms/{RomId}/file")]
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
Expand Down
2 changes: 2 additions & 0 deletions gaseous-server/Models/PlatformMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public class PlatformMapItem
public string IGDBName { get; set; }
public List<string> AlternateNames { get; set; } = new List<string>();
public List<string> KnownFileExtensions { get; set; } = new List<string>();
public Dictionary<string, string>? WebEmulator { get; set; }

}
}
}
Expand Down
6 changes: 5 additions & 1 deletion gaseous-server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@
app.UseAuthorization();

app.UseDefaultFiles();
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true, //allow unkown file types also to be served
DefaultContentType = "plain/text" //content type to returned if fileType is not known.
});

app.MapControllers();

Expand Down
18 changes: 15 additions & 3 deletions gaseous-server/Support/PlatformMap.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@
".MD",
".SG",
".SMD"
]
],
"WebEmulator": {
"Type": "EmulatorJS",
"Core": "segaMD"
}
},
{
"IGDBId": 4,
Expand All @@ -71,7 +75,11 @@
],
"KnownFileExtensions": [
".Z64"
]
],
"WebEmulator": {
"Type": "EmulatorJS",
"Core": "n64"
}
},
{
"IGDBId": 18,
Expand All @@ -88,6 +96,10 @@
".SFC",
".SMC",
".SWC"
]
],
"WebEmulator": {
"Type": "EmulatorJS",
"Core": "nes"
}
}
]
9 changes: 9 additions & 0 deletions gaseous-server/gaseous-server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@
</ItemGroup>
<ItemGroup>
<Content Remove="Support\PlatformMap.json" />
<Content Remove="wwwroot\styles\select2.min.css" />
<Content Remove="wwwroot\scripts\select2.min.js" />
<Content Remove="wwwroot\scripts\moment.js" />
<Content Remove="wwwroot\scripts\jquery-3.6.0.min.js" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Support\PlatformMap.json" Condition="'$(ExcludeConfigFilesFromBuildOutput)'!='true'">
Expand Down Expand Up @@ -165,4 +169,9 @@
<EmbeddedResource Include="Assets\Ratings\CLASS_IND\CLASS_IND_Ten.svg" />
<EmbeddedResource Include="Assets\Ratings\CLASS_IND\CLASS_IND_Twelve.svg" />
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\EmulatorJS\data\old\sega-old-wasm.data">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
Binary file modified gaseous-server/wwwroot/.DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions gaseous-server/wwwroot/EmulatorJS
Submodule EmulatorJS added at f7fa5d
25 changes: 25 additions & 0 deletions gaseous-server/wwwroot/pages/EmulatorJS.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<div style='width:640px;height:480px;max-width:100%'>
<div id='game'></div>
</div>

<script type='text/javascript'>
EJS_player = '#game';

// Can also be fceumm or nestopia
EJS_core = urlParams.get('core');

// Lightgun
EJS_lightgun = false; // can be true or false

// URL to BIOS file
EJS_biosUrl = ''; // example: https://dl.dropboxusercontent.com/s/[random-code]/bios.bin

// URL to Game rom
EJS_gameUrl = decodeURIComponent(urlParams.get('rompath'));

// Path to the data directory
EJS_pathtodata = '/EmulatorJS/data/';

EJS_DEBUG_XX = false;
</script>
<script src='/EmulatorJS/data/loader.js'></script>
48 changes: 48 additions & 0 deletions gaseous-server/wwwroot/pages/emulator.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<div id="bgImage">
<div id="bgImage_Opacity"></div>
</div>

<div id="emulator"></div>

<script type="text/javascript">
const urlParams = new URLSearchParams(window.location.search);

var gameId = urlParams.get('gameid');
var gameData;
var artworks = null;
var artworksPosition = 0;

ajaxCall('/api/v1/Games/' + gameId, 'GET', function (result) {
gameData = result;

// load artwork
if (result.artworks) {
artworks = result.artworks.ids;
var startPos = randomIntFromInterval(0, result.artworks.ids.length);
artworksPosition = startPos;
rotateBackground();
} else {
if (result.cover) {
var bg = document.getElementById('bgImage');
bg.setAttribute('style', 'background-image: url("/api/v1/Games/' + gameId + '/cover/image"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);');
}
}
});

function rotateBackground() {
if (artworks) {
artworksPosition += 1;
if (artworks[artworksPosition] == null) {
artworksPosition = 0;
}
var bg = document.getElementById('bgImage');
bg.setAttribute('style', 'background-image: url("/api/v1/Games/' + gameId + '/artwork/' + artworks[artworksPosition] + '/image"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);');
}
}

switch (urlParams.get('engine')) {
case 'EmulatorJS':
$('#emulator').load('/pages/EmulatorJS.html');
break;
}
</script>
8 changes: 7 additions & 1 deletion gaseous-server/wwwroot/pages/game.html
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ <h3>ROM's/Images</h3>
var newTable = document.createElement('table');
newTable.className = 'romtable';
newTable.setAttribute('cellspacing', 0);
newTable.appendChild(createTableRow(true, ['Name', 'Size', 'Media', '', '']));
newTable.appendChild(createTableRow(true, ['Name', 'Size', 'Media', '', '', '']));

var lastPlatform = '';
for (var i = 0; i < result.length; i++) {
Expand All @@ -318,11 +318,17 @@ <h3>ROM's/Images</h3>
newTable.appendChild(platformRow);
}

var launchButton = '';
if (result[i].emulator) {
launchButton = '<a href="/index.html?page=emulator&engine=' + result[i].emulator.Type + '&core=' + result[i].emulator.Core + '&gameid=' + gameId + '&rompath=' + encodeURIComponent('/api/v1/Games/' + gameId + '/roms/' + result[i].id + '/file') + '" class="romlink">Start</a>';
}

var newRow = [
'<a href="/api/v1/Games/' + gameId + '/roms/' + result[i].id + '/file" class="romlink">' + result[i].name + '</a>',
formatBytes(result[i].size, 2),
result[i].romTypeMedia,
result[i].mediaLabel,
launchButton,
'<span class="romlink" onclick="showDialog(\'rominfo\', ' + result[i].id + ');">...</span>'
];
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
Expand Down
6 changes: 6 additions & 0 deletions gaseous-server/wwwroot/styles/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -578,4 +578,10 @@ button:disabled {

.redbutton:disabled {
background-color: #555;
}

#emulator {
margin: 0 auto;
width: 640px;
padding-top: 100px;
}

0 comments on commit 7a8e445

Please sign in to comment.