Various improvements

This commit is contained in:
Matt Borgerson 2020-04-04 19:26:14 -07:00
parent 193bc777b6
commit facd569901
1873 changed files with 22520 additions and 5752 deletions

6
.gitignore vendored
View File

@ -1,2 +1,8 @@
__pycache__/ __pycache__/
dist/ dist/
env/
.sass-cache/
dart-sass/
bootstrap-4.4.1/
*.log
*.pid

26
build.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash -ex
if [[ ! -d dart-sass ]]; then
echo "Downloading sass";
SASS_URL=https://github.com/sass/dart-sass/releases/download/1.26.3/dart-sass-1.26.3-linux-x64.tar.gz
wget $SASS_URL
tar xf `basename $SASS_URL`
fi
if [[ ! -d bootstrap-4.4.1 ]]; then
echo "Downloading bootstrap"
BS_URL=https://github.com/twbs/bootstrap/archive/v4.4.1.zip
wget $BS_URL
unzip `basename $BS_URL`
fi
echo "Compiling stylesheets"
./dart-sass/sass theme.scss dist/theme.css
echo "Generating HTML pages"
./generate.py
cp resources/cover_front_default.png \
resources/xbox_logo.png \
resources/xbox_duke.png \
dist
rm dist/theme.css.map

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 208 KiB

2551
db.csv

File diff suppressed because it is too large Load Diff

12
gen_thumbnails.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash -ex
INPUT=$1
OUTPUT_RESIZED=`dirname $1`/cover_front_thumbnail_tmp.png
OUTPUT_COMPRESSED=`dirname $1`/cover_front_thumbnail.jpg
if [[ -e "$OUTPUT_COMPRESSED" ]]; then
echo "$OUTPUT_COMPRESSED already exists"
exit 0
fi
echo "CONVERTING $INPUT"
convert $INPUT -quality 100 -resize 256 -density 72x72 $OUTPUT_RESIZED
./guetzli/bin/Release/guetzli $OUTPUT_RESIZED $OUTPUT_COMPRESSED
rm $OUTPUT_RESIZED

View File

@ -1,18 +1,17 @@
#!/usr/bin/env python3 #!/usr/bin/env python
import codecs import codecs
import csv
import json import json
import os import os
import re import re
from tqdm import tqdm
from collections import defaultdict
from datetime import datetime from datetime import datetime
from github import Github
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
from tqdm import tqdm
cover_path_url_base = 'https://raw.githubusercontent.com/mborgerson/xemu-website/master/' repo_url_base = 'https://raw.githubusercontent.com/mborgerson/xemu-website/master/'
web_root = '/'
titles = {}
bad_titles = []
title_status_descriptions = { title_status_descriptions = {
'Unknown' : 'A compatibility test has not been recorded for this title.', 'Unknown' : 'A compatibility test has not been recorded for this title.',
'Broken' : 'This title crashes very soon after launching, or displays nothing at all.', 'Broken' : 'This title crashes very soon after launching, or displays nothing at all.',
@ -21,56 +20,65 @@ title_status_descriptions = {
'Playable' : 'This title is playable from start to finish, with only minor issues.', 'Playable' : 'This title is playable from start to finish, with only minor issues.',
'Perfect' : 'This title is playable from start to finish with no noticable issues.' 'Perfect' : 'This title is playable from start to finish with no noticable issues.'
} }
title_status_names = [
'Unknown',
'Broken',
'Intro',
'Starts',
'Playable',
'Perfect',
]
title_status_colors = {
'Unknown' : '#2A2A2A',
'Broken' : '#D7263D',
'Intro' : '#F86624',
'Starts' : '#FF9800',
'Playable' : '#1B998B',
'Perfect' : '#4CAF50',
}
class TitleRelease:
def __init__(self, title,region,edition,xboxid,pubid,titleid,discid,regionid):
self.title = title
self.region = region
self.edition = edition
self.xboxid = xboxid
self.pubid = pubid
self.titleid = titleid
self.discid = discid
self.regionid = regionid
def load_title_db():
global titles
with open('db.csv') as f:
for row in csv.reader(f):
title,region,edition,xboxid,pubid,titleid,discid,regionid = row
# Don't catalog rows with invalid publisher, title, or title info
is_bad = True
try:
int(titleid)
is_bad = False
except:
pass
if title == '' or pubid == '' or titleid == '' or is_bad:
continue
full_titleid = (pubid,titleid)
if full_titleid not in titles:
titles[full_titleid] = []
titles[full_titleid].append(TitleRelease(*row))
def get_field(s,x): def get_field(s,x):
return s[x] if x in s else '' return s[x] if x in s else ''
class Issue:
issues_by_title = None
def __init__(self, number, url, title, affected_titles, created_at, updated_at):
self.number = number
self.url = url
self.title = title
self.affected_titles = affected_titles
self.created_at = created_at
self.updated_at = updated_at
def __repr__(self):
return self.title
@classmethod
def get_all_issues(cls):
"""
Search through all GitHub issues for any title tags to construct a list of
titles and their associated issues
"""
issues = []
titles_re = re.compile(r'Titles?:\s*(\w+)(\s*,\s*\w+)*')
for issue in Github().get_user('mborgerson').get_repo('xemu').get_issues():
if issue.state != 'open': continue
# Matches returns list of tuples, just concatenate everything, strip
# out the comments and chop up by whitespace
matches = titles_re.findall(issue.body)
joiner = lambda x: ' '.join(x)
matches = map(joiner, matches)
affected_titles = []
for t in joiner(matches).replace(',', ' ').split():
affected_titles.append(t.lstrip('0x'))
issues.append(cls(
issue.number,
issue.html_url,
issue.title,
affected_titles,
issue.created_at,
issue.updated_at))
return issues
@classmethod
def get_issues_by_title(cls):
if cls.issues_by_title is not None:
return cls.issues_by_title
# Organize issues by title
issues_by_title = defaultdict(list)
for issue in cls.get_all_issues():
for title in issue.affected_titles:
issues_by_title[title].append(issue)
cls.issues_by_title = issues_by_title
return issues_by_title
class CompatibilityTest: class CompatibilityTest:
def __init__(self, d): def __init__(self, d):
timef = '%Y-%m-%d %H:%M:%S %Z' timef = '%Y-%m-%d %H:%M:%S %Z'
@ -90,68 +98,64 @@ class CompatibilityTest:
self.rating = get_field(d, "rating") self.rating = get_field(d, "rating")
class Title: class Title:
def __init__(self, pubid, tid): def __init__(self, info_path):
self.pubid = pubid with open(info_path) as f:
self.tid = tid self.info = json.load(f)
pub_hex = codecs.encode(pubid.encode('ascii'), 'hex').decode('ascii') self.pubid = codecs.decode(self.info['title_id'][0:4], 'hex').decode('ascii')
self.tid = '%03d' % (int(self.info['title_id'][4:], 16))
self.title_url = f"/titles/{self.info['title_id']}"
self.title_path = os.path.dirname(info_path)
self.title_name = self.info['name']
self.full_title_id_text = '%s-%s' % (self.pubid, self.tid)
self.full_title_id_hex = self.info['title_id']
# Determine cover paths # Determine cover paths
self.title_path = os.path.join('titles', pubid, tid)
self.cover_path = os.path.join(self.title_path, 'cover_front.jpg')
self.have_cover = True self.have_cover = True
if not os.path.exists(self.cover_path): self.cover_path = f'cover_front.jpg'
self.cover_path = os.path.join(self.title_path, 'cover_front.png') if not os.path.exists(os.path.join(self.title_path, self.cover_path)):
if not os.path.exists(self.cover_path): # Try .png extension
self.cover_path = f'cover_front.png'
if not os.path.exists(os.path.join(self.title_path, self.cover_path)):
self.have_cover = False self.have_cover = False
self.cover_path = 'cover_front_default.png'
self.cover_thumbnail_path = os.path.join(self.title_path, 'cover_front_thumbnail.jpg') self.have_thumbnail = True
if not os.path.exists(self.cover_thumbnail_path): self.cover_thumbnail_path = 'cover_front_thumbnail.jpg'
self.cover_thumbnail_path = 'cover_front_default.png' if not os.path.exists(os.path.join(self.title_path, self.cover_thumbnail_path)):
assert not self.have_cover, "Please create thumbnail for %s" % self.title_name
self.have_thumbnail = False
self.cover_url = cover_path_url_base + self.cover_path if self.have_cover:
self.cover_thumbnail_url = cover_path_url_base + self.cover_thumbnail_path self.cover_url = repo_url_base + self.title_path + '/' + self.cover_path
else:
print('Note: Missing artwork for %s' % self.title_name)
self.cover_url = repo_url_base + '/cover_front_default.png'
self.title_url = f'./{self.pubid}/{self.tid}.html' if self.have_thumbnail:
self.cover_thumbnail_url = repo_url_base + self.title_path + '/' + self.cover_thumbnail_path
# Get title info else:
info_path = os.path.join(self.title_path, 'info.json') if self.have_cover:
self.title_report = {} print('Note: Missing thumbnail for %s' % self.title_name)
if os.path.exists(info_path): self.cover_thumbnail_url = self.cover_url
with open(info_path) as f:
# Strip comments from lines
lines = '\n'.join(['' if re.match(r'^\s*//.+', l) else l for l in f])
self.title_report = json.loads(lines)
# Get all known releases of the game
self.releases = titles[(pubid, tid)]
# Determine which title name should be displayed
self.title_name = get_field(self.title_report, 'display_title') or self.releases[0].title
self.full_title_id_text = '%s-%s' % (pubid, tid)
self.full_title_id_hex = '%s%04x' % (pub_hex, int(tid))
# Parse out compatibility tests # Parse out compatibility tests
self.compatibility_tests = [] self.compatibility_tests = []
self.most_recent_test = None self.most_recent_test = None
if 'compatibility_tests' in self.title_report: if 'compatibility_tests' in self.info:
self.compatibility_tests = [CompatibilityTest(x) for x in self.title_report['compatibility_tests']] self.compatibility_tests = [CompatibilityTest(x) for x in self.info['compatibility_tests']]
if len(self.compatibility_tests) > 0: if len(self.compatibility_tests) > 0:
self.most_recent_test = compatibility_tests[-1] self.most_recent_test = compatibility_tests[-1]
if self.most_recent_test:
self.status = self.most_recent_test.rating self.status = self.most_recent_test.rating
else: else:
self.status = 'Unknown' self.status = 'Unknown'
assert(self.status in title_status_descriptions) assert(self.status in title_status_descriptions)
def main(): @property
load_title_db() def issues(self):
output_dir_path = 'dist' return Issue.get_issues_by_title()[self.info['title_id']]
os.makedirs(output_dir_path, exist_ok=True)
print('Generating webpages...') def main():
index_titles = [] output_dir = 'dist'
env = Environment(loader=FileSystemLoader(searchpath='templates'))
game_status_counts = { game_status_counts = {
'Unknown' : 0, 'Unknown' : 0,
'Broken' : 0, 'Broken' : 0,
@ -161,25 +165,64 @@ def main():
'Perfect' : 0, 'Perfect' : 0,
} }
env = Environment(loader=FileSystemLoader(searchpath='templates')) # Gather all info.json files
print('Gathering info.json files...')
for pubid, tid in tqdm(titles): titles = []
title = Title(pubid, tid) title_alias_map = {}
index_titles.append(title) title_lookup = {}
for root, dirs, files in os.walk('titles', topdown=True):
# Update global stats for name in files:
if name != 'info.json': continue
title = Title(os.path.join(root,name))
titles.append(title)
assert(title.full_title_id_hex not in title_lookup, "Title %s defined in multiple places" % title.full_title_id_hex)
title_lookup[title.full_title_id_hex] = title
game_status_counts[title.status] += 1 game_status_counts[title.status] += 1
for release in title.info['releases']:
title_alias_map[release['title_id']] = title.info['title_id']
print(' - Found %d' % (len(titles)))
# Generate page print('Getting GitHub Issues List...')
os.makedirs(os.path.join(output_dir_path, pubid), exist_ok=True) Issue.get_all_issues()
output_page_path = os.path.join(output_dir_path, pubid, tid + ".html") print(' - Ok')
print('Rebuilding pages...')
template = env.get_template('template_title.html') template = env.get_template('template_title.html')
open(output_page_path, 'w').write(template.render(**locals(), **globals())) count = 0
for title_id in tqdm(title_lookup):
title_dir = os.path.join(output_dir, 'titles', title_id)
os.makedirs(title_dir, exist_ok=True)
title = title_lookup[title_id]
with open(os.path.join(title_dir, 'index.html'), 'w') as f:
f.write(template.render(
title=title,
title_status_descriptions=title_status_descriptions
))
count += 1
print(' - Created %d title pages' % count)
# Generate index print('Generating alias redirects...')
output_page_path = os.path.join(output_dir_path, 'index.html') count = 0
for title_id in title_alias_map:
if title_alias_map[title_id] != title_id:
# This is an alias, create a redirect
title_dir = os.path.join(output_dir, 'titles', title_id)
os.makedirs(title_dir, exist_ok=True)
with open(os.path.join(title_dir, 'index.html'), 'w') as f:
url=f"/titles/{title_alias_map[title_id]}"
f.write(f'<html><head><meta http-equiv="refresh" content="0; URL={url!s}" /></head></html>')
count += 1
print(' - Created %d redirect pages' % count)
print('Rebuilding index...')
template = env.get_template('template_index.html') template = env.get_template('template_index.html')
open(output_page_path, 'w').write(template.render(**locals(), **globals())) with open(os.path.join(output_dir, 'index.html'), 'w') as f:
f.write(template.render(
titles=sorted(titles,key=lambda title:title.title_name),
title_status_descriptions=title_status_descriptions,
game_status_counts=game_status_counts
))
print(' - Ok')
if __name__ == '__main__': if __name__ == '__main__':
main() main()

13
publish.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/bash -ex
# exit 0
cd dist
cssmin > theme.css.min < theme.css
mv theme.css.min theme.css
rm -rf .git
git init .
git remote add origin git@github.com:mborgerson/xemu-website.git
echo "xemu.app" > CNAME
git add .
git commit -m "Update site"
git branch -m gh-pages
git push -f origin gh-pages

View File

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
resources/xbox_duke.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
resources/xbox_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -3,16 +3,27 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <link rel="stylesheet" href="{{ main_url_base }}/theme.css">
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.13.0/css/all.css"> <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.13.0/css/all.css">
<link href="https://fonts.googleapis.com/css2?family=Ubuntu+Mono&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Ubuntu+Mono&display=swap" rel="stylesheet">
<title>{%block title %}{% endblock %}{% if self.title() %} | {% endif %}xemu: Original Xbox Emulator</title> <title>{%block title %}{% endblock %}{% if self.title() %} | {% endif %}xemu: Original Xbox Emulator</title>
{% block header_extension %}{% endblock %} {% block append_head %}{% endblock %}
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-163809672-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-163809672-1');
</script>
</head> </head>
<body> <body>
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark"> <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
<a class="navbar-brand" href="/" style="font-family: 'Ubuntu Mono'">xemu</a> <a class="navbar-brand" href="{{ main_url_base }}/" style="font-family: 'Ubuntu Mono'">xemu</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExample04" aria-controls="navbarsExample04" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExample04" aria-controls="navbarsExample04" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
@ -20,7 +31,7 @@
<div class="collapse navbar-collapse" id="navbarsExample04"> <div class="collapse navbar-collapse" id="navbarsExample04">
<ul class="navbar-nav mr-auto"> <ul class="navbar-nav mr-auto">
<li class="nav-item active"> <li class="nav-item active">
<a class="nav-link" href="/#compatibility">Compatibility</a> <a class="nav-link" href="{{ main_url_base }}/#compatibility">Compatibility</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -50,6 +61,6 @@
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
{% block footer_extension %}{% endblock %} {% block append_foot %}{% endblock %}
</body> </body>
</html> </html>

View File

@ -0,0 +1,38 @@
{% extends "template_base.html" %}
{% block title %}User Token{% endblock %}
{% block content %}
<div class="py-2 pt-5">
<h4>Request User Token</h4>
</div>
{% if token %}
<div class="py-2 pt-5">
<h4>Thanks!</h4>
</div>
<div class="list-group">
<p>Paste this token into the compatibility report window in xemu to submit it with your feedback reports.</p>
<div class="list-group-item text-center text-muted text-small">
<code>{{ token }}</code>
</div>
</div>
{% else %}
<div class="list-group">
<p>
User tokens are an easy way to establish your identity. If you would like to
expedite your compatibility reports and get credit for testing, please file
with a user token!
</p>
<p>
The xemu community operates on Discord. By authenticating with Discord, you
can help verify your identity. Only your Discord username, Discord user id number,
and the IP address which you connect from are collected; no other private information
is stored.
</p>
<p><center>
<a class="btn btn-outline-secondary btn-lg" href="{{ authorize_url }}" role="button">
<i class="fab fa-discord btn-icon"></i>Verify with Discord</a>
</center></p>
</div>
{% endif %}
{% endblock %}

View File

@ -1,5 +1,7 @@
{% set title_status_colors = {'Unknown' : '#2A2A2A', 'Broken' : '#D7263D', 'Intro' : '#F86624', 'Starts' : '#FF9800', 'Playable' : '#1B998B', 'Perfect' : '#4CAF50'} %}
{% extends "template_base.html" %} {% extends "template_base.html" %}
{% block header_extension %} {% block append_head %}
<style type="text/css"> <style type="text/css">
/* https://www.gungorbudak.com/blog/2018/12/12/bootstrap-4-search-box-with-search-icon/ */ /* https://www.gungorbudak.com/blog/2018/12/12/bootstrap-4-search-box-with-search-icon/ */
.has-search .form-control { .has-search .form-control {
@ -38,7 +40,7 @@
background-color: #373737; background-color: #373737;
} }
.title-card-image-container { .title-card-image-container {
background-image:url('{{ cover_path_url_base }}/cover_front_default.png'); background-image:url('cover_front_default.png');
background-size: 8rem 11rem; background-size: 8rem 11rem;
background-repeat: no-repeat; background-repeat: no-repeat;
width: 100%; width: 100%;
@ -70,6 +72,12 @@
height: 60px; /* fixed header height*/ height: 60px; /* fixed header height*/
margin: -60px 0 0; /* negative fixed header height */ margin: -60px 0 0; /* negative fixed header height */
} }
.feature-icon {
font-size: 0.7em;
padding-right: 0.25em;
vertical-align: 10%;
}
</style> </style>
{% endblock %} {% endblock %}
@ -80,10 +88,10 @@
<div class="container"> <div class="container">
<div class="row mt-5"> <div class="row mt-5">
<div class="col-md-6 mt-4 text-center"> <div class="col-md-6 mt-4 text-center">
<img src="{{ cover_path_url_base }}/xbox_logo.png" class="img-fluid" /> <img src="xbox_logo.png" class="img-fluid" width=450 />
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<h1 class="display-3" style="font-family: 'Ubuntu Mono'">xemu</h1> <h1 class="display-3" style="font-family: 'Ubuntu Mono'; color: #42e335">xemu</h1>
<h4 class="card-subtitle mb-2 text-muted">Original Xbox Emulator</h4> <h4 class="card-subtitle mb-2 text-muted">Original Xbox Emulator</h4>
<p> <p>
An open-source, cross-platform application that emulates the hardware of An open-source, cross-platform application that emulates the hardware of
@ -94,6 +102,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="scroll"></div>
</div> </div>
{% endblock %} {% endblock %}
@ -101,24 +110,24 @@
<h2 class="mb-4 text-center">Features</h2> <h2 class="mb-4 text-center">Features</h2>
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<h4><i class="fab fa-github"></i> Open Source</h4> <h4><i class="fab fa-github feature-icon"></i> Open Source</h4>
<p>The source code for xemu is publicly available. Users are invited to help improve the project!</p> <p>The source code for xemu is publicly available. Users are invited to help improve the project!</p>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<h4><i class="fas fa-users"></i> Cross Platform</h4> <h4><i class="fas fa-users feature-icon"></i> Cross Platform</h4>
<p>xemu runs natively on Windows, macOS, and Linux platforms. Pre-compiled binaries are available for Windows, and soon for all three platforms.</p> <p>xemu runs natively on Windows, macOS, and Linux platforms. Pre-compiled binaries are available for Windows, and soon for all three platforms.</p>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<h4><i class="fas fa-project-diagram"></i> System Link</h4> <h4><i class="fas fa-people-arrows feature-icon"></i> System Link</h4>
<p>Networking is supported out of the box. Connect to other instances of xemu and even real Xboxes, locally or over the Internet.</p> <p>Networking is supported out of the box. Connect to other instances of xemu and even real Xboxes, locally or over the Internet.</p>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<h4><i class="fas fa-gamepad"></i> Gamepad Support</h4> <h4><i class="fas fa-gamepad feature-icon"></i> Gamepad Support</h4>
<p>Built on SDL2, xemu supports virtually all gamepads. Connect up to 4 controllers at any time, just like a real Xbox.</p> <p>Built on SDL2, xemu supports virtually all gamepads. Connect up to 4 controllers at any time, just like a real Xbox.</p>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<div class="coming-soon-contents"> <div class="coming-soon-contents">
<h4><i class="fas fa-save"></i> Snapshots</h4> <h4><i class="fas fa-download feature-icon"></i> Snapshots</h4>
<p>Don't wait for checkpoints. xemu supports saving the current machine state and loading it back up at a later time.</p> <p>Don't wait for checkpoints. xemu supports saving the current machine state and loading it back up at a later time.</p>
</div> </div>
<div class="coming-soon-overlay"> <div class="coming-soon-overlay">
@ -127,7 +136,7 @@
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<div class="coming-soon-contents"> <div class="coming-soon-contents">
<h4><i class="fas fa-expand-alt"></i> Surface Scaling</h4> <h4><i class="fas fa-expand-alt feature-icon"></i> Surface Scaling</h4>
<p>Breathe new life into your old games by scaling up the resolution which the games render at.</p> <p>Breathe new life into your old games by scaling up the resolution which the games render at.</p>
</div> </div>
<div class="coming-soon-overlay"> <div class="coming-soon-overlay">
@ -148,7 +157,7 @@
</div> </div>
<div class="container mt-2"> <div class="container mt-2">
<div class="row" id="results"> <div class="row" id="results">
{% for title in index_titles %} {% for title in titles %}
<div class="col mb-4 title-card" data-title-name="{{ title.title_name }}"> <div class="col mb-4 title-card" data-title-name="{{ title.title_name }}">
<a href="{{ title.title_url }}"> <a href="{{ title.title_url }}">
<div class="mx-auto title-card-container"> <div class="mx-auto title-card-container">
@ -170,7 +179,7 @@
</div> </div>
{% endblock %} {% endblock %}
{% block footer_extension %} {% block append_foot %}
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazy/1.7.10/jquery.lazy.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazy/1.7.10/jquery.lazy.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazy/1.7.10/jquery.lazy.plugins.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazy/1.7.10/jquery.lazy.plugins.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/apexcharts"></script> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
@ -221,9 +230,10 @@ var options = {
{% endfor %} {% endfor %}
], ],
chart: { chart: {
foreColor: '#a7a7a7', // text color
background: '#444',
type: 'bar', type: 'bar',
height: 100, height: 100,
offsetY: 0,
stacked: true, stacked: true,
stackType: '100%', stackType: '100%',
toolbar: { toolbar: {
@ -236,8 +246,12 @@ var options = {
}, },
}, },
stroke: { stroke: {
width: 1, show: false,
colors: ['#fff'] width: 0,
colors: ['#999']
},
grid: {
show: false
}, },
xaxis: { xaxis: {
categories: [ categories: [
@ -245,14 +259,30 @@ var options = {
], ],
labels: { labels: {
show: false show: false
},
axisBorder: {
show: false,
color: '#ffff00'
},
axisTicks: {
show: false,
} }
}, },
yaxis: { yaxis: {
labels: { labels: {
show: false show: true,
maxWidth: 0
},
axisBorder: {
show: false,
color: '#ff00ff'
},
axisTicks: {
show: false,
} }
}, },
tooltip: { tooltip: {
enabled: false,
y: { y: {
formatter: function (val) { formatter: function (val) {
return val return val
@ -267,6 +297,7 @@ var options = {
legend: { legend: {
position: 'top', position: 'top',
horizontalAlign: 'center', horizontalAlign: 'center',
offsetY: 20
} }
}; };
var chart = new ApexCharts(document.querySelector("#title_stats"), options); var chart = new ApexCharts(document.querySelector("#title_stats"), options);

View File

@ -25,10 +25,10 @@
<li class="list-group-item d-flex justify-content-between lh-condensed"> <li class="list-group-item d-flex justify-content-between lh-condensed">
<div class="list-group w-100"> <div class="list-group w-100">
<div class="d-flex w-100 justify-content-between"> <div class="d-flex w-100 justify-content-between">
<h6 class="">Status</h6> <h5 class="">Status</h5>
<span class="text-color-{{ title.status }}"><strong>{{ title.status }}</strong></span> <span><strong>{{ title.status }}</strong></span>
</div> </div>
<p class="text-muted mb-1"><small>{{ title_status_descriptions[title.status] }}</small></p> <p class="text-muted mb-1">{{ title_status_descriptions[title.status] }}</p>
</div> </div>
</li> </li>
@ -74,15 +74,16 @@
<h4>Known Issues</h4> <h4>Known Issues</h4>
</div> </div>
<div class="list-group"> <div class="list-group">
{% if False %} {% if title.issues|length > 0 %}
<a href="#" class="list-group-item list-group-item-action flex-column align-items-start"> {% for issue in title.issues %}
<a href="{{ issue.url }}" class="list-group-item list-group-item-action flex-column align-items-start">
<div class="d-flex w-100 justify-content-between"> <div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">List group item heading</h5> <h5 class="mb-1">{{ issue.title }}</h5>
<small>3 days ago</small> <small>#{{ issue.number }}</small>
</div> </div>
<p class="mb-1">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> <p class="mb-1 text-small text-muted">Issue last updated {{ issue.updated_at.strftime('%b %-m, %Y') }}.</p>
<small>Donec id elit non mi porta.</small>
</a> </a>
{% endfor %}
{% else %} {% else %}
<div class="list-group-item text-center text-muted text-small"> <div class="list-group-item text-center text-muted text-small">
No issues have been reported for this title. No issues have been reported for this title.

443
theme.scss Normal file
View File

@ -0,0 +1,443 @@
// Your variable overrides
/*$body-bg: #303030;*/
$body-color: #A7A7A7;
////////////////////////////////////////////////////////////////////////////////
// Darkly 4.3.1
// Bootswatch
//
// Color system
//
$white: #fff !default;
$gray-100: #f8f9fa !default;
$gray-200: #ebebeb !default;
$gray-300: #dee2e6 !default;
$gray-400: #ced4da !default;
$gray-500: #adb5bd !default;
$gray-600: #888 !default;
$gray-700: #444 !default;
$gray-800: #303030 !default;
$gray-900: #222 !default;
$black: #000 !default;
$blue: #375a7f !default;
$indigo: #6610f2 !default;
$purple: #6f42c1 !default;
$pink: #e83e8c !default;
$red: #E74C3C !default;
$orange: #fd7e14 !default;
$yellow: #F39C12 !default;
$green: #00bc8c !default;
$teal: #20c997 !default;
$cyan: #3498DB !default;
$primary: $blue !default;
$secondary: $gray-600 !default;
$success: $green !default;
$info: $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-500 !default;
$dark: $gray-800 !default;
$yiq-contrasted-threshold: 175 !default;
// Body
$body-bg: $gray-900 !default;
$body-color: $white !default;
// Links
$link-color: $success !default;
// Fonts
$font-family-sans-serif: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default;
$font-size-base: 0.9375rem !default;
$h1-font-size: 3rem !default;
$h2-font-size: 2.5rem !default;
$h3-font-size: 2rem !default;
$text-muted: $gray-600 !default;
// Tables
$table-accent-bg: $gray-800 !default;
$table-border-color: $gray-700 !default;
// Forms
$input-bg: $gray-900 !default;
$input-color: $body-color;
$input-placeholder-color: darken($input-color, 25%);
$input-focus-border-color: #42e335;
$input-border-color: $input-color !default;
$input-focus-color: $input-color;
$input-group-addon-color: $gray-500 !default;
$input-group-addon-bg: $gray-700 !default;
$custom-file-color: $gray-500 !default;
$custom-file-border-color: $body-bg !default;
// Dropdowns
$dropdown-bg: $gray-900 !default;
$dropdown-border-color: $gray-700 !default;
$dropdown-divider-bg: $gray-700 !default;
$dropdown-link-color: $white !default;
$dropdown-link-hover-color: $white !default;
$dropdown-link-hover-bg: $primary !default;
// Navs
$nav-link-padding-x: 2rem !default;
$nav-link-disabled-color: $gray-500 !default;
$nav-tabs-border-color: $gray-700 !default;
$nav-tabs-link-hover-border-color: $nav-tabs-border-color $nav-tabs-border-color transparent !default;
$nav-tabs-link-active-color: $white !default;
$nav-tabs-link-active-border-color: $nav-tabs-border-color $nav-tabs-border-color transparent !default;
// Navbar
/*$navbar-padding-y: 1rem !default;*/
$navbar-dark-color: rgba($white,.6) !default;
$navbar-dark-hover-color: $white !default;
$navbar-light-color: rgba($gray-900, .7) !default;
$navbar-light-hover-color: $gray-900 !default;
$navbar-light-active-color: $gray-900 !default;
$navbar-light-toggler-border-color: rgba($gray-900, .1) !default;
// Pagination
$pagination-color: $white !default;
$pagination-bg: $success !default;
$pagination-border-width: 0 !default;
$pagination-border-color: transparent !default;
$pagination-hover-color: $white !default;
$pagination-hover-bg: lighten($success, 10%) !default;
$pagination-hover-border-color: transparent !default;
$pagination-active-bg: $pagination-hover-bg !default;
$pagination-active-border-color: transparent !default;
$pagination-disabled-color: $white !default;
$pagination-disabled-bg: darken($success, 15%) !default;
$pagination-disabled-border-color: transparent !default;
// Jumbotron
$jumbotron-bg: $gray-800 !default;
// Cards
$card-cap-bg: $gray-700 !default;
$card-bg: $gray-800 !default;
// Popovers
$popover-bg: $gray-800 !default;
$popover-header-bg: $gray-700 !default;
// Toasts
$toast-background-color: $gray-700 !default;
$toast-header-background-color: $gray-800 !default;
// Modals
$modal-content-bg: $gray-800 !default;
$modal-content-border-color: $gray-700 !default;
$modal-header-border-color: $gray-700 !default;
// Progress bars
$progress-bg: $gray-700 !default;
// List group
$list-group-bg: $gray-800 !default;
$list-group-border-color: $gray-700 !default;
$list-group-hover-bg: $gray-700 !default;
// Breadcrumbs
$breadcrumb-bg: $gray-700 !default;
// Close
$close-color: $white !default;
$close-text-shadow: none !default;
// Code
$pre-color: inherit !default;
////////////////////////////////////////////////////////////////////////////////
@import "bootstrap-4.4.1/scss/bootstrap.scss";
////////////////////////////////////////////////////////////////////////////////
// Darkly 4.3.1
// Bootswatch
// Variables ===================================================================
$web-font-path: "https://fonts.googleapis.com/css?family=Lato:400,700,400italic&display=swap" !default;
@import url($web-font-path);
// Navbar ======================================================================
// Buttons =====================================================================
// Typography ==================================================================
.blockquote {
&-footer {
color: $gray-600;
}
}
// Tables ======================================================================
.table {
&-primary {
&, > th, > td {
background-color: $primary;
}
}
&-secondary {
&, > th, > td {
background-color: $secondary;
}
}
&-light {
&, > th, > td {
background-color: $light;
}
}
&-dark {
&, > th, > td {
background-color: $dark;
}
}
&-success {
&, > th, > td {
background-color: $success;
}
}
&-info {
&, > th, > td {
background-color: $info;
}
}
&-danger {
&, > th, > td {
background-color: $danger;
}
}
&-warning {
&, > th, > td {
background-color: $warning;
}
}
&-active {
&, > th, > td {
background-color: $table-active-bg;
}
}
&-hover {
.table-primary:hover {
&, > th, > td {
background-color: darken($primary, 5%);
}
}
.table-secondary:hover {
&, > th, > td {
background-color: darken($secondary, 5%);
}
}
.table-light:hover {
&, > th, > td {
background-color: darken($light, 5%);
}
}
.table-dark:hover {
&, > th, > td {
background-color: darken($dark, 5%);
}
}
.table-success:hover {
&, > th, > td {
background-color: darken($success, 5%);
}
}
.table-info:hover {
&, > th, > td {
background-color: darken($info, 5%);
}
}
.table-danger:hover {
&, > th, > td {
background-color: darken($danger, 5%);
}
}
.table-warning:hover {
&, > th, > td {
background-color: darken($warning, 5%);
}
}
.table-active:hover {
&, > th, > td {
background-color: $table-active-bg;
}
}
}
}
// Forms =======================================================================
.input-group-addon {
color: #fff;
}
// Navs ========================================================================
.nav-tabs,
.nav-pills {
.nav-link,
.nav-link.active,
.nav-link.active:focus,
.nav-link.active:hover,
.nav-item.open .nav-link,
.nav-item.open .nav-link:focus,
.nav-item.open .nav-link:hover {
color: #fff;
}
}
.breadcrumb a {
color: #fff;
}
.pagination {
a:hover {
text-decoration: none;
}
}
// Indicators ==================================================================
.close {
opacity: 0.4;
&:hover,
&:focus {
opacity: 1;
}
}
.alert {
border: none;
color: $white;
a,
.alert-link {
color: #fff;
text-decoration: underline;
}
@each $color, $value in $theme-colors {
&-#{$color} {
@if $enable-gradients {
background: $value linear-gradient(180deg, mix($white, $value, 15%), $value) repeat-x;
} @else {
background-color: $value;
}
}
}
}
// Progress bars ===============================================================
// Containers ==================================================================
.list-group-item-action {
color: #fff;
&:hover,
&:focus {
background-color: $gray-700;
color: #fff;
}
.list-group-item-heading {
color: #fff;
}
}
body {
background-image: url(xbox_duke.png);
background-position: -200px 40em;
background-size: 400px 311px;
background-repeat: no-repeat;
}
.btn-icon {
padding-right: 0.5em;
}

18
titles/AC/001/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Dave Mirra Freestyle BMX 2",
"title_id": "41430001",
"releases": [
{
"title_id": "41430001",
"region": "USA",
"edition": "Platinum Hits",
"disc_id": 1
},
{
"title_id": "41430001",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

24
titles/AC/002/info.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "All-Star Baseball 2003 featuring Derek Jeter",
"title_id": "41430002",
"releases": [
{
"title_id": "41430002",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41430002",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41430002",
"region": "Japan",
"edition": "Original",
"disc_id": 3
}
]
}

18
titles/AC/003/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Legends of Wrestling",
"title_id": "41430003",
"releases": [
{
"title_id": "41430003",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41430003",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

29
titles/AC/004/info.json Normal file
View File

@ -0,0 +1,29 @@
{
"name": "Turok: Evolution",
"title_id": "41430004",
"releases": [
{
"title_id": "41430004",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41430004",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41430004",
"region": "Germany",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "5a420300",
"region": "USA",
"edition": "Beta"
}
]
}

18
titles/AC/005/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Vexx",
"title_id": "41430005",
"releases": [
{
"title_id": "41430005",
"region": "USA",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "41430005",
"region": "Europe",
"edition": "Original",
"disc_id": 4
}
]
}

18
titles/AC/006/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Burnout",
"title_id": "41430006",
"releases": [
{
"title_id": "41430006",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41430006",
"region": "Europe",
"edition": "Classics, ESC Escape 03 Xbox Charity Pack",
"disc_id": 2
}
]
}

18
titles/AC/007/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Aggressive Inline",
"title_id": "41430007",
"releases": [
{
"title_id": "41430007",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41430007",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

18
titles/AC/010/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "ATV: Quad Power Racing 2",
"title_id": "4143000a",
"releases": [
{
"title_id": "4143000a",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4143000a",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

18
titles/AC/011/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Speed Kings",
"title_id": "4143000b",
"releases": [
{
"title_id": "4143000b",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4143000b",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

18
titles/AC/012/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Urban Freestyle Soccer",
"title_id": "4143000c",
"releases": [
{
"title_id": "4143000c",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "4143000c",
"region": "USA",
"edition": "Original",
"disc_id": 3
}
]
}

12
titles/AC/013/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "AFL Live 2003",
"title_id": "4143000d",
"releases": [
{
"title_id": "4143000d",
"region": "Australia",
"edition": "Original",
"disc_id": 1
}
]
}

18
titles/AC/014/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "BMX XXX",
"title_id": "4143000e",
"releases": [
{
"title_id": "4143000e",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4143000e",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

18
titles/AC/015/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Legends of Wrestling II",
"title_id": "4143000f",
"releases": [
{
"title_id": "4143000f",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4143000f",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

18
titles/AC/016/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "SX Superstar",
"title_id": "41430010",
"releases": [
{
"title_id": "41430010",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41430010",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

18
titles/AC/019/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "NBA Jam",
"title_id": "41430013",
"releases": [
{
"title_id": "41430013",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41430013",
"region": "Europe",
"edition": "Original",
"disc_id": 3
}
]
}

18
titles/AC/020/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "XGRA: Extreme G Racing Association",
"title_id": "41430014",
"releases": [
{
"title_id": "41430014",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41430014",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

18
titles/AC/022/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Alias",
"title_id": "41430016",
"releases": [
{
"title_id": "41430016",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41430016",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

18
titles/AC/023/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Dakar 2",
"title_id": "41430017",
"releases": [
{
"title_id": "41430017",
"region": "Europe",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41430017",
"region": "USA",
"edition": "Original",
"disc_id": 2
}
]
}

12
titles/AC/024/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "All-Star Baseball 2004 featuring Derek Jeter",
"title_id": "41430018",
"releases": [
{
"title_id": "41430018",
"region": "USA",
"edition": "Original",
"disc_id": 1
}
]
}

18
titles/AC/025/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Burnout 2: Point of Impact",
"title_id": "41430019",
"releases": [
{
"title_id": "41430019",
"region": "USA",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "41430019",
"region": "Europe",
"edition": "Original",
"disc_id": 4
}
]
}

24
titles/AC/026/info.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "Gladiator: Sword of Vengeance",
"title_id": "4143001a",
"releases": [
{
"title_id": "4143001a",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4143001a",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "4143001a",
"region": "Germany",
"edition": "Original",
"disc_id": 3
}
]
}

12
titles/AC/027/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "AFL Live 2004",
"title_id": "4143001b",
"releases": [
{
"title_id": "4143001b",
"region": "Australia",
"edition": "Original",
"disc_id": 2
}
]
}

12
titles/AC/028/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "All-Star Baseball 2005 featuring Derek Jeter",
"title_id": "4143001c",
"releases": [
{
"title_id": "4143001c",
"region": "USA",
"edition": "Original",
"disc_id": 1
}
]
}

18
titles/AC/029/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Showdown: Legends of Wrestling",
"title_id": "4143001d",
"releases": [
{
"title_id": "4143001d",
"region": "USA",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "4143001d",
"region": "Europe",
"edition": "Original",
"disc_id": 4
}
]
}

12
titles/AC/031/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "WCR: World Championship Rugby",
"title_id": "4143001f",
"releases": [
{
"title_id": "4143001f",
"region": "Europe",
"edition": "Original",
"disc_id": 1
}
]
}

12
titles/AC/035/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "AFL Live Premiership Edition",
"title_id": "41430023",
"releases": [
{
"title_id": "41430023",
"region": "Australia",
"edition": "Original",
"disc_id": 1
}
]
}

12
titles/AC/126/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "The Red Star",
"title_id": "4143007e",
"releases": [
{
"title_id": "4143007e",
"region": "World",
"edition": "Proto",
"disc_id": 50
}
]
}

12
titles/AD/002/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Pump It Up: Exceed",
"title_id": "41440002",
"releases": [
{
"title_id": "41440002",
"region": "USA",
"edition": "Original",
"disc_id": 1
}
]
}

11
titles/AH/001/info.json Normal file
View File

@ -0,0 +1,11 @@
{
"name": "Fear Factor: Unleashed",
"title_id": "41480001",
"releases": [
{
"title_id": "41480001",
"edition": "UNRELEASED GAME, SERIAL GUESSED",
"disc_id": 1
}
]
}

18
titles/AH/002/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Playboy: The Mansion",
"title_id": "41480002",
"releases": [
{
"title_id": "41480002",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41480002",
"region": "USA",
"edition": "Original",
"disc_id": 3
}
]
}

12
titles/AP/001/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Tenerezza",
"title_id": "41500001",
"releases": [
{
"title_id": "41500001",
"region": "Japan",
"edition": "Original",
"disc_id": 1
}
]
}

12
titles/AQ/001/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Petit Copter",
"title_id": "41510001",
"releases": [
{
"title_id": "41510001",
"region": "Japan",
"edition": "Original",
"disc_id": 1
}
]
}

12
titles/AQ/002/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Flight Academy",
"title_id": "41510002",
"releases": [
{
"title_id": "41510002",
"region": "Japan",
"edition": "Original",
"disc_id": 1
}
]
}

12
titles/AQ/003/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Sentou Yousei Yukikaze: Yousei no Mau Sora",
"title_id": "41510003",
"releases": [
{
"title_id": "41510003",
"region": "Japan",
"edition": "Original",
"disc_id": 1
}
]
}

12
titles/AS/001/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Break Nine: World Billiards Tournament",
"title_id": "41530001",
"releases": [
{
"title_id": "41530001",
"region": "Japan",
"edition": "Original",
"disc_id": 1
}
]
}

12
titles/AT/001/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Touge R",
"title_id": "41540001",
"releases": [
{
"title_id": "41540001",
"region": "Japan",
"edition": "Original",
"disc_id": 1
}
]
}

12
titles/AT/002/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Shin Megami Tensei: Nine",
"title_id": "41540002",
"releases": [
{
"title_id": "41540002",
"region": "Japan",
"edition": "Original",
"disc_id": 1
}
]
}

12
titles/AT/003/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Pro Fishing Challenge",
"title_id": "41540003",
"releases": [
{
"title_id": "41540003",
"region": "USA",
"edition": "Original",
"disc_id": 1
}
]
}

18
titles/AT/004/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Galleon",
"title_id": "41540004",
"releases": [
{
"title_id": "41540004",
"region": "USA",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "5343000b",
"region": "Europe",
"edition": "Original",
"disc_id": 1
}
]
}

12
titles/AV/001/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Tony Hawk's Pro Skater 2x",
"title_id": "41560001",
"releases": [
{
"title_id": "41560001",
"region": "USA",
"edition": "Original",
"disc_id": 2
}
]
}

22
titles/AV/002/info.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "Kelly Slater's Pro Surfer",
"title_id": "41560002",
"releases": [
{
"title_id": "41560002",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560002",
"disc_id": 2
},
{
"title_id": "41560002",
"region": "Europe",
"edition": "Original",
"disc_id": 3
}
]
}

18
titles/AV/003/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Street Hoops",
"title_id": "41560003",
"releases": [
{
"title_id": "41560003",
"region": "Europe",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560003",
"region": "USA",
"edition": "Original",
"disc_id": 2
}
]
}

18
titles/AV/004/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Tony Hawk's Pro Skater 3",
"title_id": "41560004",
"releases": [
{
"title_id": "41560004",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560004",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

18
titles/AV/005/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Blade II",
"title_id": "41560005",
"releases": [
{
"title_id": "41560005",
"region": "Europe",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560005",
"region": "USA",
"edition": "Original",
"disc_id": 2
}
]
}

42
titles/AV/006/info.json Normal file
View File

@ -0,0 +1,42 @@
{
"name": "Spider-Man",
"title_id": "41560006",
"releases": [
{
"title_id": "41560006",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560006",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41560006",
"region": "France",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "41560006",
"region": "Germany",
"edition": "Original",
"disc_id": 4
},
{
"title_id": "41560006",
"region": "Korea",
"edition": "Original",
"disc_id": 5
},
{
"title_id": "4343000a",
"region": "Japan",
"edition": "Original",
"disc_id": 1
}
]
}

30
titles/AV/007/info.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "X-Men: Next Dimension",
"title_id": "41560007",
"releases": [
{
"title_id": "41560007",
"disc_id": 1
},
{
"title_id": "41560007",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41560007",
"disc_id": 3
},
{
"title_id": "41560007",
"disc_id": 4
},
{
"title_id": "41560007",
"region": "USA",
"edition": "Original",
"disc_id": 5
}
]
}

34
titles/AV/008/info.json Normal file
View File

@ -0,0 +1,34 @@
{
"name": "X-Men 2: Wolverine's Revenge",
"title_id": "41560008",
"releases": [
{
"title_id": "41560008",
"region": "Europe",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560008",
"region": "USA",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41560008",
"region": "Europe",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "41560008",
"disc_id": 4
},
{
"title_id": "41560008",
"region": "Japan",
"edition": "World Collection",
"disc_id": 5
}
]
}

30
titles/AV/009/info.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "Rally Fusion: Race of Champions",
"title_id": "41560009",
"releases": [
{
"title_id": "41560009",
"region": "Europe",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560009",
"region": "USA",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41560009",
"region": "Europe",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "41560009",
"region": "Korea",
"edition": "Original",
"disc_id": 4
}
]
}

30
titles/AV/010/info.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "Wreckless: The Yakuza Missions",
"title_id": "4156000a",
"releases": [
{
"title_id": "4156000a",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4156000c",
"region": "Europe",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4156000c",
"region": "Germany",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "4156000c",
"region": "France",
"edition": "Original",
"disc_id": 3
}
]
}

24
titles/AV/011/info.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "Mat Hoffman's Pro BMX 2",
"title_id": "4156000b",
"releases": [
{
"title_id": "4156000b",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4156000b",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "4156000b",
"region": "France",
"edition": "Original",
"disc_id": 3
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

View File

@ -1 +0,0 @@
https://www.mobygames.com/game/xbox/wreckless-the-yakuza-missions

28
titles/AV/013/info.json Normal file
View File

@ -0,0 +1,28 @@
{
"name": "Wakeboarding Unleashed featuring Shaun Murray",
"title_id": "4156000d",
"releases": [
{
"title_id": "4156000d",
"region": "Europe",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4156000d",
"region": "USA",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "4156000d",
"disc_id": 3
},
{
"title_id": "4156000d",
"region": "Japan",
"edition": "World Collection",
"disc_id": 4
}
]
}

30
titles/AV/014/info.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "True Crime: Streets of LA",
"title_id": "4156000e",
"releases": [
{
"title_id": "4156000e",
"region": "USA, Asia",
"edition": "Original",
"disc_id": 6
},
{
"title_id": "4156000e",
"region": "Europe",
"edition": "Original",
"disc_id": 7
},
{
"title_id": "4156000e",
"region": "Europe",
"edition": "Original",
"disc_id": 8
},
{
"title_id": "4156000e",
"region": "Japan",
"edition": "Original",
"disc_id": 9
}
]
}

48
titles/AV/015/info.json Normal file
View File

@ -0,0 +1,48 @@
{
"name": "Star Wars: Obi-Wan",
"title_id": "4156000f",
"releases": [
{
"title_id": "4156000f",
"region": "Europe",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "43540001",
"region": "Italy",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "45410022",
"region": "Germany",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "45410022",
"region": "Spain",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "4c410001",
"region": "USA",
"edition": "Original, Platinum Hits",
"disc_id": 1
},
{
"title_id": "4c410001",
"region": "Asia",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "5553000f",
"region": "France",
"edition": "Original",
"disc_id": 1
}
]
}

16
titles/AV/016/info.json Normal file
View File

@ -0,0 +1,16 @@
{
"name": "Return to Castle Wolfenstein: Tides of War",
"title_id": "41560010",
"releases": [
{
"title_id": "41560010",
"disc_id": 1
},
{
"title_id": "41560010",
"region": "USA, Europe",
"edition": "Original, Classics, Platinum Hits",
"disc_id": 2
}
]
}

48
titles/AV/020/info.json Normal file
View File

@ -0,0 +1,48 @@
{
"name": "Minority Report: Everybody Runs",
"title_id": "41560014",
"releases": [
{
"title_id": "41560014",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560014",
"disc_id": 2
},
{
"title_id": "41560014",
"region": "France",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "41560014",
"region": "Asia",
"edition": "Original",
"disc_id": 4
},
{
"title_id": "41560014",
"disc_id": 5
},
{
"title_id": "41560014",
"region": "Europe",
"edition": "Original",
"disc_id": 6
},
{
"title_id": "41560014",
"disc_id": 7
},
{
"title_id": "41560014",
"region": "Germany",
"edition": "Original",
"disc_id": 8
}
]
}

24
titles/AV/021/info.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "Star Wars: Jedi Knight II: Jedi Outcast",
"title_id": "41560015",
"releases": [
{
"title_id": "41560015",
"region": "Europe",
"edition": "Original",
"disc_id": 4
},
{
"title_id": "41560015",
"region": "Germany",
"edition": "Original",
"disc_id": 5
},
{
"title_id": "4c410009",
"region": "USA",
"edition": "Original",
"disc_id": 2
}
]
}

34
titles/AV/023/info.json Normal file
View File

@ -0,0 +1,34 @@
{
"name": "Tony Hawk's Pro Skater 4",
"title_id": "41560017",
"releases": [
{
"title_id": "41560017",
"region": "USA",
"edition": "Platinum Hits",
"disc_id": 1
},
{
"title_id": "41560017",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41560017",
"region": "France",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "41560017",
"disc_id": 4
},
{
"title_id": "41560017",
"region": "Germany",
"edition": "Original",
"disc_id": 5
}
]
}

30
titles/AV/024/info.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "Pitfall: The Lost Expedition",
"title_id": "41560018",
"releases": [
{
"title_id": "41560018",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560018",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41560018",
"region": "France",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "41560018",
"region": "Germany",
"edition": "Original",
"disc_id": 4
}
]
}

22
titles/AV/025/info.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "Cabela's Dangerous Hunts",
"title_id": "41560019",
"releases": [
{
"title_id": "41560019",
"region": "USA",
"edition": "Platinum Hits",
"disc_id": 1
},
{
"title_id": "41560019",
"disc_id": 2
},
{
"title_id": "41560019",
"region": "Europe",
"edition": "Original",
"disc_id": 3
}
]
}

30
titles/AV/026/info.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "Fantastic 4",
"title_id": "4156001a",
"releases": [
{
"title_id": "4156001a",
"region": "USA, Europe",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4156001a",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "4156001a",
"region": "Europe",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "4156001a",
"region": "Italy",
"edition": "Original",
"disc_id": 4
}
]
}

18
titles/AV/027/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Soldier of Fortune II: Double Helix",
"title_id": "4156001b",
"releases": [
{
"title_id": "4156001b",
"region": "USA",
"edition": "Original",
"disc_id": 5
},
{
"title_id": "4156001b",
"region": "Europe",
"edition": "Original",
"disc_id": 6
}
]
}

18
titles/AV/030/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "X-Men Legends",
"title_id": "4156001e",
"releases": [
{
"title_id": "4156001e",
"region": "Europe",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4156001e",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

36
titles/AV/031/info.json Normal file
View File

@ -0,0 +1,36 @@
{
"name": "Lemony Snicket's A Series of Unfortunate Events",
"title_id": "4156001f",
"releases": [
{
"title_id": "4156001f",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "4156001f",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "4156001f",
"region": "France",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "4156001f",
"region": "Germany",
"edition": "Original",
"disc_id": 4
},
{
"title_id": "4156001f",
"region": "Spain",
"edition": "Original",
"disc_id": 5
}
]
}

30
titles/AV/032/info.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "Doom 3",
"title_id": "41560020",
"releases": [
{
"title_id": "41560020",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41560020",
"region": "USA",
"edition": "Limited Collector's Edition",
"disc_id": 3
},
{
"title_id": "41560020",
"region": "Europe",
"edition": "Limited Collector's Edition",
"disc_id": 4
},
{
"title_id": "41560020",
"region": "USA",
"edition": "Original",
"disc_id": 5
}
]
}

18
titles/AV/034/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "MTX Mototrax",
"title_id": "41560022",
"releases": [
{
"title_id": "41560022",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560022",
"region": "Europe",
"edition": "Original",
"disc_id": 2
}
]
}

18
titles/AV/038/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Tenchu: Return from Darkness",
"title_id": "41560026",
"releases": [
{
"title_id": "41560026",
"region": "USA, Asia",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560036",
"region": "Europe",
"edition": "Original",
"disc_id": 1
}
]
}

24
titles/AV/039/info.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "Disney's Extreme Skate Adventure",
"title_id": "41560027",
"releases": [
{
"title_id": "41560027",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560027",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41560027",
"region": "Europe",
"edition": "Original",
"disc_id": 3
}
]
}

30
titles/AV/042/info.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "Call of Duty: Finest Hour",
"title_id": "4156002a",
"releases": [
{
"title_id": "4156002a",
"region": "USA, Europe",
"edition": "Original, Platinum Hits",
"disc_id": 1
},
{
"title_id": "4156002a",
"region": "Germany",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "4156002a",
"region": "Europe",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "4156002a",
"region": "Japan",
"edition": "Original",
"disc_id": 4
}
]
}

24
titles/AV/043/info.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "Spider-Man 2",
"title_id": "4156002b",
"releases": [
{
"title_id": "4156002b",
"region": "Italy",
"edition": "Classics",
"disc_id": 3
},
{
"title_id": "4156002b",
"region": "Europe, Asia",
"edition": "Original",
"disc_id": 4
},
{
"title_id": "4156002b",
"region": "Europe",
"edition": "Original",
"disc_id": 5
}
]
}

18
titles/AV/045/info.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "Tony Hawk's Underground",
"title_id": "4156002d",
"releases": [
{
"title_id": "4156002d",
"region": "USA",
"edition": "Platinum Hits",
"disc_id": 1
},
{
"title_id": "4156002d",
"region": "Europe",
"edition": "Original, Classics",
"disc_id": 2
}
]
}

12
titles/AV/048/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Cabela's Deer Hunt: 2004 Season",
"title_id": "41560030",
"releases": [
{
"title_id": "41560030",
"region": "USA",
"edition": "Original",
"disc_id": 1
}
]
}

24
titles/AV/053/info.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "Ultimate Spider-Man",
"title_id": "41560035",
"releases": [
{
"title_id": "41560035",
"region": "USA",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560035",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41560035",
"region": "Europe",
"edition": "Original",
"disc_id": 3
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

View File

@ -1 +0,0 @@
https://www.mobygames.com/game/xbox/tenchu-return-from-darkness

36
titles/AV/055/info.json Normal file
View File

@ -0,0 +1,36 @@
{
"name": "Shrek 2",
"title_id": "41560037",
"releases": [
{
"title_id": "41560037",
"region": "France",
"edition": "Original",
"disc_id": 3
},
{
"title_id": "41560037",
"region": "Germany",
"edition": "Classics",
"disc_id": 4
},
{
"title_id": "41560037",
"region": "Italy",
"edition": "Original",
"disc_id": 5
},
{
"title_id": "41560037",
"region": "Japan",
"edition": "World Collection",
"disc_id": 7
},
{
"title_id": "41560037",
"region": "Europe",
"edition": "Original",
"disc_id": 8
}
]
}

24
titles/AV/056/info.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "DreamWorks Shark Tale",
"title_id": "41560038",
"releases": [
{
"title_id": "41560038",
"region": "Europe",
"edition": "Original",
"disc_id": 1
},
{
"title_id": "41560038",
"region": "Europe",
"edition": "Original",
"disc_id": 2
},
{
"title_id": "41560038",
"region": "Italy",
"edition": "Original",
"disc_id": 3
}
]
}

12
titles/AV/058/info.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "Rapala Pro Fishing",
"title_id": "4156003a",
"releases": [
{
"title_id": "4156003a",
"region": "Europe",
"edition": "Original",
"disc_id": 1
}
]
}

Some files were not shown because too many files have changed in this diff Show More