Initial commit

This commit is contained in:
chris062689 2017-02-26 16:24:53 -05:00
parent dfec052adc
commit 0330cac113
153 changed files with 9720 additions and 1 deletions

17
.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
node_modules/
# Binaries
site/hugo
site/hugo.exe
# Hugo generated static website files.
site/public/
.publish/
# Dynamic content imported on deploy.
site/content/wiki/
site/data/twitter.json
# Filesystem stuff.
.directory
.DS_Store

41
.travis.yml Normal file
View File

@ -0,0 +1,41 @@
# Build status located at https://travis-ci.org/citra-emu/citra-web
language: node_js
node_js:
- "6"
before_script:
- echo '========== Importing wiki articles into hugo =========='
- cd ./scripts/wiki/
- npm install
- node app.js
- cd $TRAVIS_BUILD_DIR
- echo '========== Importing twitter tweets into hugo =========='
- cd ./scripts/twitter/
- npm install
- node app.js
- cd $TRAVIS_BUILD_DIR
- echo '========== Installing gulp / hugo dependencies =========='
- npm install -g @alrra/travis-scripts
- npm install -g gulp
- npm install -g hugo-bin
- hugo version
- echo '========== Configuring Github Pages =========='
- git config --global user.email "citra+citrabotweb@citra-emu.org"
- git config --global user.name "CitraBotWeb"
- set-up-ssh --key "$encrypted_e58a91e8d3ce_key" --iv "$encrypted_e58a91e8d3ce_iv" --path-encrypted-key "bf215181b5140522137b3d4f6b73544a.enc"
- echo '========== Starting gulp deploy task =========='
- gulp deploy
- cd $TRAVIS_BUILD_DIR
env:
- HUGO_ENV=PRD
# set-up-ssh is provided by travis-scripts.
# Setting up the SSH key for Github is described here.
# https://github.com/alrra/travis-scripts/blob/master/doc/github-deploy-keys.md

View File

@ -1 +1 @@
# citra-web
# Citra Official Website

Binary file not shown.

96
gulpfile.js Normal file
View File

@ -0,0 +1,96 @@
var gulp = require('gulp');
var gutil = require('gulp-util');
var exec = require('child_process').exec;
var rimraf = require('rimraf');
var postcss = require('gulp-postcss');
var cssImport = require('postcss-import');
var cssnext = require('postcss-cssnext');
var md5 = require("gulp-md5-plus");
var ghPages = require('gulp-gh-pages');
var uncss = require('gulp-uncss');
var cleanCSS = require('gulp-clean-css');
var image = require('gulp-image');
var jimp = require("gulp-jimp-resize");
var htmlmin = require('gulp-htmlmin');
const distPath = './site/public';
const cname = 'citra-emu.org';
const deployOptions = {
remoteUrl: "git@github.com:CitraBotWeb/CitraBotWeb.github.io.git",
branch: "master"
};
gulp.task("default", ['html']);
gulp.task('setup', function(cb) {
process.env.HUGO_ENV = 'PRD';
process.env.GULP = 'true';
rimraf(`${distPath}`, cb);
});
gulp.task('hugo', ['setup'], function (cb) {
exec('hugo -s ./site/ -v', function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
cb(err);
});
});
gulp.task("css", ['hugo'], () => (
gulp.src(`${distPath}/css/**/*.css`, {base: './'})
.pipe(postcss([cssnext(), cssImport({from: `${distPath}/css/main.css`})]))
.pipe(uncss({
html: [`${distPath}/**/*.html`],
ignore: [/\w\.in/,
".fade",
".collapse",
".collapsing",
".table",
".thumbnail",
/(#|\.)navbar(\-[a-zA-Z]+)?/,
/(#|\.)dropdown(\-[a-zA-Z]+)?/,
/(#|\.)carousel(\-[a-zA-Z]+)?/,
]}))
.pipe(cleanCSS())
.pipe(md5(10, `${distPath}/**/*.html`))
.pipe(gulp.dest('./'))
));
gulp.task('images', ['hugo'], () => (
gulp.src(`${distPath}/images/*`, {base: './'})
.pipe(image({
mozjpeg: false,
jpegoptim: false
}))
.pipe(gulp.dest('./')),
gulp.src(`${distPath}/images/jumbotron/*`, {base: './'})
.pipe(jimp({ sizes: [{"width": 786, "height": 471 }] }))
.pipe(image({
mozjpeg: false,
jpegoptim: false
}))
.pipe(gulp.dest('./')),
gulp.src(`${distPath}/images/banners/*`, {base: './'})
.pipe(jimp({ sizes: [{"width": 824, "height": 306 }] }))
.pipe(image({
mozjpeg: false,
jpegoptim: false
}))
.pipe(gulp.dest('./'))
));
gulp.task('html', ['hugo', 'css', 'images'], () => (
gulp.src(`${distPath}/**/*.html`, {base: './'})
.pipe(htmlmin({collapseWhitespace: true}))
.pipe(gulp.dest('./'))
));
gulp.task('deploy', ['hugo', 'css', 'images', 'html'], () => {
require('fs').writeFileSync(`${distPath}/CNAME`, `${cname}`);
return gulp.src(`${distPath}/**/*`).pipe(ghPages(deployOptions));
});

22
package.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "citra-web",
"version": "1.0.0",
"description": "The Citra Official Website",
"author": "",
"license": "GPLv3",
"dependencies": {
"gulp": "^3.9.1",
"gulp-clean-css": "^3.0.3",
"gulp-gh-pages": "^0.5.4",
"gulp-htmlmin": "^3.0.0",
"gulp-image": "^2.7.5",
"gulp-jimp-resize": "^2.0.2",
"gulp-md5-plus": "^0.2.5",
"gulp-postcss": "^6.3.0",
"gulp-uncss": "^1.0.6",
"gulp-util": "^3.0.8",
"postcss-cssnext": "^2.9.0",
"postcss-import": "^8.2.0",
"rimraf": "^2.6.1"
}
}

2
scripts/twitter/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules/
*.log

37
scripts/twitter/app.js Normal file
View File

@ -0,0 +1,37 @@
var fs = require('fs');
var logger = require('winston');
var jsonfile = require('jsonfile');
var outputFile = '../../site/data/twitter.json';
var tweets = [
{
"id": "817201197065109505",
"order": 1,
"date": "01/05/2017",
"author": "citraemu",
"image": "https://pbs.twimg.com/profile_images/699782793736359936/eMLbnRNR_normal.png",
"message": "Citra nightlies are back up and better than ever! Sorry for the delay and Happy New Year!"
},
{
"id": "776626520110399488",
"order": 2,
"date": "09/15/2016",
"author": "citraemu",
"image": "https://pbs.twimg.com/profile_images/699782793736359936/eMLbnRNR_normal.png",
"message": "After much anticipation, Citra now has a JIT! Props again to @MerryMage for another massive contribution to the project!!"
},
{
"id": "733831257398747137",
"order": 3,
"date": "05/20/2016",
"author": "citraemu",
"image": "https://pbs.twimg.com/profile_images/699782793736359936/eMLbnRNR_normal.png",
"message": "Props to @MerryMage for a fantastic job on Citra's audio support https://t.co/Z23AWxcDkf"
}
];
jsonfile.writeFile(outputFile, tweets, function (err) {
if (err) { logger.error(err); return; }
logger.info(`Wrote ${tweets.length} tweets to ${outputFile}`)
})

View File

@ -0,0 +1,15 @@
{
"name": "citra-twitter",
"version": "1.0.0",
"description": "Used in Citra Hugo to import Twitter tweets.",
"homepage": "https://citra-emu.org/",
"author": "Flame Sage <chris062689@gmail.com>",
"main": "app.js",
"dependencies": {
"jsonfile": "^2.4.0",
"winston": "^2.2.0"
},
"preferGlobal": false,
"private": true,
"license": "GPLv3"
}

3
scripts/wiki/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
node_modules/
citra.wiki/
*.log

90
scripts/wiki/app.js Normal file
View File

@ -0,0 +1,90 @@
var fs = require('fs');
var util = require('util');
var logger = require('winston');
var sanitizeHtml = require('sanitize-html');
var del = require('delete');
var exec = require('sync-exec');
var inputDirectory = './citra.wiki/';
var outputDirectory = '../../site/content/wiki/';
function url(title) {
return '/wiki/' + title.replace(/\s+/g, '-');
}
if (fs.existsSync(inputDirectory)) {
logger.info(`Purging input directory: ${outputDirectory}`);
del.sync(outputDirectory, {force: true});
}
exec('git clone https://github.com/citra-emu/citra.wiki.git');
if (fs.existsSync(outputDirectory) == false) {
logger.info(`Creating missing output directory: ${outputDirectory}`);
fs.mkdirSync(outputDirectory);
}
fs.readdir(inputDirectory, function(err, items) {
try {
// Look for all .md files within the wiki directory.
items.filter(file => file.substr(-3) === '.md').forEach(function(item) {
// Generate the title from the filename.
let title = item.replace(/-/g, ' ').slice(0, -3);
var stats = fs.statSync(`${inputDirectory}${item}`);
var modified = new Date(util.inspect(stats.mtime));
// Read the .md file.
fs.readFile(`${inputDirectory}${item}`, 'utf8', function (err,data) {
if (err) { logger.error(err); return; }
try {
// Convert various data inside of the markdown language.
let cleanData = sanitizeHtml(data);
// Blackfriday Markdown Rendering requires a blank line before lists.
try {
var lines = cleanData.split(/\r?\n/);
for(var i = 0; i < lines.length; i++) {
// If it's the start of the file, ignore to prevent an index issue.
if (i > lines.length) { return; }
if (i == 0 || lines[i] == '\n') { continue; }
// Search for the start of a list designated by the * character.
if (lines[i].startsWith("* ") && lines[i - 1].startsWith("* ") == false) {
i = i + 1;
lines.splice(i - 1, 0, '');
}
}
cleanData = lines.join('\n');
} catch (ex) {
logger.error(ex);
}
// Replacing tags like [[Common Issues on Windows|Common Issues]]
cleanData = cleanData.replace(/\[\[(.*)\|(.*)\]\]/g, function(match, p1, p2) {
return `[${p1}](${url(p2)})`
});
// Replacing tags like [[Common Issues]]
cleanData = cleanData.replace(/\[\[(.*)\]\]/g, function(match, p1) {
return `[${p1}](${url(p1)})`
});
// Create the new markdown header for Hugo.
let newFileContents = `+++\ntitle = "${title}"\ndate = "${modified.toISOString()}"\n+++\n${cleanData}`;
fs.writeFile(`${outputDirectory}${item}`, newFileContents, function(err) {
if (err) return logger.error(err);
logger.info(`Wrote file ${item} to filesystem.`);
});
} catch (ex) {
logger.error(ex);
}
});
});
} catch (ex) {
logger.error(ex);
}
});

18
scripts/wiki/package.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "citra-wiki",
"version": "1.0.0",
"description": "Used in Citra Hugo to import Wiki articles.",
"homepage": "https://citra-emu.org/",
"author": "Flame Sage <chris062689@gmail.com>",
"main": "app.js",
"dependencies": {
"delete": "^0.3.2",
"rimraf": "^2.6.1",
"sanitize-html": "^1.14.1",
"sync-exec": "^0.6.2",
"winston": "^2.2.0"
},
"preferGlobal": false,
"private": true,
"license": "GPLv3"
}

14
site/config.toml Normal file
View File

@ -0,0 +1,14 @@
baseurl = "/"
languageCode = "en-us"
theme = "citra-bs-theme"
googleAnalytics = "UA-73966905-1"
# Define how many objects appear per pagination.
paginate = 10
[Languages]
[Languages.en]
title = "Citra"
description = "Citra is an open-source emulator for the Nintendo 3DS capable of playing many of your favorite 3DS games."
weight = 1

5
site/content/chat.md Normal file
View File

@ -0,0 +1,5 @@
+++
title = "IRC Chat"
+++
<iframe src="https://kiwiirc.com/client/irc.freenode.net/?nick=citraguest|?&amp;theme=basic#citra" style="border:0; width:100%; height:600px;"></iframe>

18
site/content/donate.md Normal file
View File

@ -0,0 +1,18 @@
+++
title = "Support Citra with your Donations"
+++
Developing an emulator for a modern, complex system like the Nintendo 3DS requires significant hard work and dedication from a large team of developers. We will never charge you for Citra and will always make our source code freely available. We do not make any money from our work, however development has many expenses that are often paid out-of-pocket by our team members, among them:
* 3DS consoles to explore and reverse-engineer the hardware</li>
* 3DS games for testing, reverse-engineering, and implementing new features
* Web hosting and infrastructure setup
* Software licenses
* Additional hardware (e.g. 3D monitors to eventually support 3D output, GPUs as-needed to improve rendering support, other peripherals to add support for, etc.)
Your generous donation will go directly toward providing these to our team. Previous donations have already been used to purchase several 3DS consoles, games, and host our current website! However, our costs will continue as our team grows, our website grows, and we strive to achieve high game compatibility with Citra.
### Donate your 3DS/games/etc.
We will more than gladly accept used 3DS consoles and games! Please contact: [bunneidev@gmail.com](mailto:bunneidev@gmail.com)
Thank you for your support!

115
site/content/download.md Normal file
View File

@ -0,0 +1,115 @@
+++
title = "Download Citra"
advertisement = true
+++
The nightly build of Citra contains already reviewed and tested features. If you require support with the installation or use of Citra, or you want to report bugs you should use this version. This version is still in development, so expect crashes and bugs.
The Bleeding Edge build of Citra is the same as our nightly builds, with additional features that are still waiting on review before making it into the official Citra builds. We will not provide support for issues found only in this version. If you believe you've found a bug, please retest on our nightly builds. This version is still in development, so expect crashes and bugs.
<div class="visible-xs">
<h3>Citra currently does not support Android or iOS.</h3>
</div>
<h3>Nightly Build <span style='font-size: smaller; margin-left: 6px;'> Last release was <span id='last-updated-nightly'></span></span></h3>
<table id="downloads-nightly" class="table">
<thead>
<tr>
<th>Build Date</th>
<th>Commit Information</th>
<th>Download</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div style="text-align: center; padding: 0px; margin: 0px;"><a href = "https://github.com/citra-emu/citra-nightly/releases">Click here to view previous versions...</a></div>
<h3>Bleeding Edge Build <span style='font-size: smaller; margin-left: 6px;'> Last release was <span id='last-updated-bleeding-edge'></span></span></h3>
<table id="downloads-bleeding-edge" class="table">
<thead>
<tr>
<th>Build Date</th>
<th>Commit Information</th>
<th>Download</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div style="text-align: center; padding: 0px; margin: 0px;"><a href = "https://github.com/citra-emu/citra-bleeding-edge/releases">Click here to view previous versions...</a></div>
<style>
.table-first { background-color: #fcf8e3; }
.dl-icon { display: inline-block; border-bottom: 0px !important; }
.dl-icon img { width: 32px; height: 32px; padding: 4px; }
.dl-icon img:hover { cursor: pointer; }
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
getRelease('nightly');
getRelease('bleeding-edge');
function getRelease(v, count = 5) {
$.getJSON('https://api.github.com/repos/citra-emu/citra-' + v + '/releases', function(releases) {
$("#last-updated-" + v).text(moment(releases[0].published_at).fromNow());
for (var i = 0; i < releases.length; ++i) {
var release = releases[i];
let release_date = moment(release.published_at).fromNow();
let release_commit = null;
let release_commit_url = null;
if (v == 'nightly') {
release_commit = release.assets[0].name.split('-').pop().trim().split('.')[0];
release_commit_url = 'https://github.com/citra-emu/citra-' + v + '/commit/' + release_commit;
}
let release_title = '';
if (v == 'nightly') {
release_title = 'Nightly Build';
} else if (v == 'bleeding-edge') {
release_title = 'Bleeding Edge Build';
}
if (release_commit) {
release_title += ' - ' + release_commit;
}
var download_span = '';
var table_style = '';
if (i == 0) { table_style = 'table-first'; }
release.assets.forEach(function(asset) {
if (asset.name.includes('nupkg')) return;
if (asset.name.includes('RELEASES')) return;
let env_icon = './images/icons/file.png';
if (asset.name.includes('windows')) env_icon = '/images/icons/windows.png';
else if (asset.name.includes('exe')) env_icon = '/images/icons/windows.png';
else if (asset.name.includes('osx')) env_icon = '/images/icons/apple.png';
else if (asset.name.includes('linux')) env_icon = '/images/icons/linux.png';
let download_url = 'https://github.com/citra-emu/citra-' + v + '/releases/download/' + release.tag_name + '/' + asset.name;
download_span += '<a class="dl-icon" href="' + download_url + '"><img src="' + env_icon + '"></i></a>';
});
// Generate the link to the Github release.
download_span += '<a class="dl-icon" href="' + release.html_url + '"><img src="/images/icons/github.png"></i></a>';
if (release_commit_url != null) {
$('#downloads-' + v).append('<tr class="' + table_style + '"><td>' + release_date + '</td>' +
'<td><a href="' + release_commit_url + '/">' + release_title + '</a></td><td>' + download_span + '</td></tr>');
} else {
$('#downloads-' + v).append('<tr class="' + table_style + '"><td>' + release_date + '</td>' +
'<td>' + release_title + '</td><td>' + download_span + '</td></tr>');
}
if (i + 1 >= count) { break; }
};
});
}
});
</script>

View File

@ -0,0 +1,23 @@
+++
date = "2016-10-11T14:49:00-05:00"
title = "Announcing Bleeding Edge Builds"
tags = [ "citra-release" ]
author = "jmc47"
coauthor = "jroweboy"
forum = 42
+++
Sometimes it's hard to wait. We've noticed that users are very excited about the future of Citra, which means wanting to try all of the changes all of the time.
But, emulator development can be a slow, arduous process as new changes can bring big regressions and problems with the much wanted new features.
In order to satiate the needs of our users, we'll be adding new builds for download: bleeding edge builds!
These builds will contain experimental features and changes designed to give the absolute fastest builds with the most features combined into one download!
Since these releases are official, unlike other random builds you might find on the internet, there is no chance that they will contain a virus, or anything else that can potentially be harmful.
Because updates will come at a rapid pace and there is a chance of these changes adversely affecting emulation, the builds will let you know when a newer version is available and **auto-update** if you allow it.
You can download the bleeding edge development builds at our <a href="https://citra-emu.org/page/download">downloads page</a> right now!
While Windows is the only operating system targeted at this time, the other operating systems will follow shortly.
While these builds aren't technically supported, they can be extremely useful for catching regressions and other issues from the various experimental features rolled into them.
If you experience a bug, please make sure that the latest nightly builds do not have the issue before reporting it.

View File

@ -0,0 +1,39 @@
+++
date = "2016-02-23T23:30:00-05:00"
title = "Citra Progress Report - 2015 P1"
tags = [ "progress-report" ]
author = "bunnei"
forum = 33
+++
While Citra was first founded in April of 2014, visible progress for the emulator didn't really happen until the turn of the year. After a long struggle to get anything to boot, 2015 saw Citra evolve from an experimental emulator that couldn't run games into an experimental emulator that can run games. And while it may not seem like Citra is that far along, it is truly amazing how much things have progressed in just a year since the first commercial title booted.
However, with Citra's success and high visibility within the emulation community, it may be easy to think that we've gotten this far on our own, but that would be quite misguided. Citra would not exist without the work that others have done before and alongside it: Particularly the folks behind [3dmoo](https://github.com/plutooo/3dmoo/) ([Normmatt](http://github.com/normmatt), [ichfly](http://github.com/ichfly), and [plutoo](https://github.com/plutooo)), who did a lot of the early reverse-engineering to boot commercial games; as well as those who have worked tirelessly to break open the 3DS and [share their work](https://www.3dbrew.org/wiki/Main_Page) publically ([yellows8](https://github.com/yellows8), [Bond697](https://github.com/bond697), [fincs](https://github.com/fincs), among many others), and [smea](https://github.com/smealum) for providing a public [way to run](http://smealum.net/ninjhax/) (and a [library](https://github.com/smealum/ctrulib) to create) homebrew. We've been lucky to be part of a much larger community of hackers, developers and researchers that have always been willing to lend a hand in some way, which is something that many other emulator teams are not quite as fortunate to have!
Like most young projects, Citra didn't have a great website infrastructure featuring a blog last year; there was no need to as it didn't boot games or have a big fanbase interested in its development. It was just one of several emulators that had promise. With that promise starting to be fulfilled and a shiny new blog ready and waiting, let us look back at the year that Citra rose above the rest and became **THE** 3DS emulator.
## Winter: The First Retail Games
In late 2014, Citra was a very small project developed primarily by [bunnei](https://github.com/bunnei) and [neobrain](http://github.com/neobrain). The heart and soul behind the effort to get a game rendering was their reverse-engineering skills put into figuring out how the 3DS GPU worked and accurately represented it in an accuracy focused software renderer. Meanwhile, [bunnei](https://github.com/bunnei) assisted with that while figuring out how to recreate the environment that the 3DS games run in, with a particular focus on emulating the 3DS' operating system. Because they focused on accurate emulation, parts of the emulator were fairly advanced despite no commercial games booting.
Until one day...
<br></br>
{{< img src="entry/citra-progress-report-2015-p1/image01.png" center="true" >}}
<br></br>
Recognize the game? That's The Legend of Zelda: Ocarina of Time 3D rendering on Citra on [December 13, 2014](https://twitter.com/fail_cluez/status/543796766270046210). This distorted upside-down Triforce loading icon was the first rendering of a commercial title in Citra. After that, Ocarina of Time 3D would promptly hang, but even this little blip caused excitement from the developers. To get a retail game to show any graphics at all be it a simple icon or a complex 3D scene requires that a virtual environment be created that is sufficiently complete such that from the perspective of a game, it is running on an actual Nintendo 3DS. This isnt just a matter of being able to execute the games native machine code, but also provide it with enough of the essential features it expects when running on a real 3DS. For example, 3DS games run within a full operating system (much like your PC or smart phone), that of which Citra needed to duplicate.
Propelled by this breakthrough, [neobrain](http://github.com/neobrain) and [bunnei](https://github.com/bunnei) worked tirelessly day and night to push Ocarina of Time just a little bit further. With [bunnei](https://github.com/bunnei) focused on fixing core emulation bugs and implementing necessary OS features, [neobrain](http://github.com/neobrain) continued with GPU reverse-engineering based on the features that Ocarina of Time was lacking within the software renderer. While it took months to get the game booting, getting it to the title screen only took a few more days. The result of this hard work may look like nothing but a screenshot from a glitchy emulator, but when it happened it was a huge cause for celebration: Citra's first fully 3D-rendered scene. <br></br>
{{< img src="entry/citra-progress-report-2015-p1/image03.png" center="true" >}}
<br></br>
This breakthrough only motivated developers further. With a 3D rendered scene under its belt, users had taken notice and news of Citra had spread. This fervor was met with more than just hype, but also results. It was only a matter of weeks before several more retail games were booting in Citra, some of which were able to be played in-game. It became a sort of friendly competition among the developers to see who could be the first to get a new game booting it. Among the next few games to fall were Cave Story and Cave Story 3D, VVVVVV, Ikachan, Gunman Clive, Super Little Acorns, and Retro City Rampage. <br></br>
{{< youtube ZGQWVMCdfK0 >}}
<br></br>
While this was cause for excitement, there is a pattern to be noticed in the games that booted. Most of the titles were either simple 2D games, or ports from other systems. This actually has some meaning: ports and simple games are less likely to use new features of a system than say a blockbuster title from Nintendo designed for the system to show off what it can really do.
In the [next part](https://citra-emu.org/entry/citra-progress-report-2015-p2), we'll continue our 2015 retrospective with Spring. By then, Citra fever was in full effect, with new devs and old faces showing up to throw their hat in the ring and see who could make the next big breakthrough. No one was ready for how much could change in just three more months.

View File

@ -0,0 +1,103 @@
+++
date = "2016-03-09T15:30:00-05:00"
title = "Citra Progress Report - 2015 P2"
tags = [ "progress-report" ]
author = "bunnei"
forum = 36
+++
This month we bring you the second installment of our two-part progress report on Citra in 2015! With this part, we discuss the evolution from Citra being able to barely run a few commercial games at a few frames-per-second, to where it is in 2016: Running many retail games at reasonable speeds, some of which are fully playable with near flawless graphics! We discuss Citra's new "dyncom" CPU core, the OpenGL renderer, per-pixel lighting, and various bug fixes. Lastly, we wrap up with an outlook for 2016, and a special thanks to everyone who has helped make Citra what it is today!
## Spring 2015: A New CPU, Renderer and More
The arms race to get games booting ran into a wall. Often, testing games and getting to crash points would be incredibly painful because of how slow the emulator ran. Instead of measuring frames-per-second, testers often referred to seconds-per-frame. Donkey Kong Country Returns 3D would sometimes require three realtime seconds to render a single in-game frame in the software renderer! It took over 90 minutes to capture all of the footage for a three minute video of Super Monkey Ball 3D! <br></br>
{{< youtube t0TGSeQe1wE >}}
<br></br>
Within the next few months, [bunnei](https://github.com/bunnei) and [Lioncash](https://github.com/lioncash) replaced the old "ARMULATOR" CPU core in Citra with a better implementation that was both several times faster and much more accurate. Despite the fact that it was still an interpreter, this new core was still efficient enough that the performance implications were huge. With this new core, games that were light on graphics could reach above half-speed on very strong processors.
Shortly thereafter, a new developer joined the Citra team [tfarley](https://github.com/tfarley) with the ambitious goal of implementing a hardware renderer using OpenGL. Up until this point, Citra had used a software renderer primarily developed by [neobrain](http://github.com/neobrain) to render graphics. While a software renderer is great for development and achieving pixel-perfect accuracy, Citras GPU emulation had become the major performance bottleneck. Even with infinitely fast CPU emulation, the software renderer was so slow that no games would run full speed despite this.
While the rest of the team continued with other development efforts, [tfarley](https://github.com/tfarley) went on a month-long battle developing this new OpenGL renderer. All of this resulted in Ocarina of Time 3D running nearly perfect in Citra using OpenGL while running at a fairly decent speed! Below is a very early video of Ocarina of Time, before the renderer was completed and merged into CItra's mainline repository. <br></br>
{{< youtube Hj8sPsB5qXQ >}}
## Summer: More Accuracy, More Performance
With the summer, development slowed down a bit but several additional improvements were made. By this point, the team had already made lots of incremental advances in 3DS emulation, resulting in a significant number of retail games booting, such as Super Mario 3D Land, Fire Emblem: Awakening, The Legend of Zelda: A Link Between Worlds, Mario Kart 7, and many more. <br></br>
{{< img src="entry/citra-progress-report-2015-p2/earlyunknown1.png" center="true" >}}
{{< img src="entry/citra-progress-report-2015-p2/earlyunknown2.png" center="true" >}}
{{< img src="entry/citra-progress-report-2015-p2/earlycrush3d.png" center="true" >}}
{{< img src="entry/citra-progress-report-2015-p2/earlymario3dland.png" center="true" >}}
{{< img src="entry/citra-progress-report-2015-p2/earlysteeldiver.png" center="true" >}}
{{< img src="entry/citra-progress-report-2015-p2/earlyluigi.png" center="true" >}}
{{< img src="entry/citra-progress-report-2015-p2/earlylinkbetweenworlds.png" center="true" >}}
{{< img src="entry/citra-progress-report-2015-p2/earlymajorasmask.png" center="true" >}}
{{< img src="entry/citra-progress-report-2015-p2/earlymk7.png" center="true" >}}
{{< img src="entry/citra-progress-report-2015-p2/earlyfireemblem.png" center="true" >}}
<br></br>
But there was still one major issue that was blocking many games: video playback. 3DS games use a proprietary format known as “MOFLEX” to play video clips, which are commonly used for intro logos, cut scenes, and more. Not only was the video format unknown, but any time a MOFLEX video was used, Citra would hang in an infinite loop for unknown reasons. However, this issue proved to be no match for our team within a matter of weeks, Citra developers [yuriks](https://github.com/yuriks) and [Subv](https://github.com/Subv) reverse-engineered and implemented all of the mechanisms necessary to prevent hanging and play MOFLEX videos!<br></br>
{{< img src="entry/citra-progress-report-2015-p2/3.png" center="true" >}}
<p style="text-align: center;">Bravely Default's intro sequence relies on MOFLEX video support <br></br>
With many games now running stable with fairly accurate rendering, it became evident that with a bit more speed some titles would not only be playable in Citra, but enjoyable to play. On top of this, more speed would make testing even easier, so with a huge library of games now working, the task again came to making things faster.
The cause of the slowdown was very obvious: Citras emulation of 3DS vertex shaders. With emulators like Dolphin and PPSSPP, your GPU uses shaders to emulate the target systems GPU, which does not actually use any shaders of its own. The 3DS, on the other hand, has a more modern GPU that natively supports its own shaders which are not as trivial to emulate in the same manner. The approach that we took was similar to CPU emulation and we were using a pure interpreter for the job. As such, the solution was pretty obvious; Even a naively implemented Just-In-Time (JIT) compiler would make our shader emulation scream. With that in mind, [bunnei](https://github.com/bunnei) set out to implement a vertex shader JIT.
While it took several weeks to develop, the difference in speed was very obvious. Vertex heavy games were sometimes two or three times as fast, allowing some games like Ocarina of Time 3D to near full speed in many areas! <br></br>
{{< youtube yhLEs4yEmlU >}}
## Autumn: Closing out the Year with a Bang!
After a brief summer hiatus, development on Citra began to pick up again with autumn 2015. While Citra now had a library of games running without severe problems, many still relied on more advanced graphics features that had yet to be reverse-engineered. One of these more widely used features is fragment lighting a feature that enables complex lighting calculations to be performed on a per-pixel basis. A major breakthrough was made when hacker and homebrew developer fincs made major strides in figuring out the 3DS fragment lighting implementation. Immediately, [bunnei](https://github.com/bunnei) began embodying this work into Citra. <br></br>
{{< img src="entry/citra-progress-report-2015-p2/rotatecube.gif" center="true" >}}
<p style="text-align: center;"> An early fragment lighting demo running in Citra <br></br>
Despite that its not a fully complete implementation of fragment lighting, the results have significantly improved Citras visuals!
<div class="row" style="margin-top:3em; margin-bottom:1em;">
<div class="col-xs-12 col-sm-6" style="text-align:center; margin-bottom: 1em;"><img alt="" src="/images/entry/citra-progress-report-2015-p2/moonbefore.png" style="max-width: 100%; border-style: none; margin-bottom: 1em;" />
It's a super moon!
</div>
<div class="col-xs-12 col-sm-6" style="text-align:center; margin-bottom: 1em;"><img alt="" src="/images/entry/citra-progress-report-2015-p2/moonafter.png" style="max-width: 100%; border-style: none; margin-bottom: 1em;" />
With fragment lighting implemented, the moon became even scarier! H-hurray?
</div>
While no more major features were merged into Citra by the turn of the year, [Subv](https://github.com/Subv) came up with one final teaser of things to come before letting 2015 come to a close. CROs, the dynamically linked libraries of the 3DS (similiar to DLLs on Windows), blocked several very popular 3DS games from booting in Citra, such as Pokemon X, Y, Omega Ruby, Alpha Sapphire and Super Smash Bros. for 3DS. While the implementation was far from done, it still was able to boot up some of the games that relied heavily on this feature.
<br></br>
{{< youtube 30NwGUYmIpU >}}
## Citra in 2016
With 2016 already upon us, it's shaping up to be a pretty exciting year for Citra! In addition to the many tasks discussed in the 2015 progress reports that are still ongoing, we've got several exciting new features to look forward to:
* [MerryMage](https://github.com/merrymage) has been making some exciting progress on an HLE implementation of the DSP, meaning audio support may come sooner than expected!
* [tfarley](https://github.com/tfarley) has been working on a HW renderer optimization - "texture forwarding" - that minimizes copies of textures/framebuffers to/from emulated RAM. The result of this effort will be both a performance improvement as well as support for upscaled rendering!
* [yuriks](https://github.com/yuriks) has plans to rewrite the vertex shader JIT to fix several inherent flaws, which will improve accuracy and address the crashing issues, as well as improved memory and IPC emulation in the kernel HLE
* [Subv](https://github.com/Subv) is still looking into CRO support, as well as mipmapping and scissor testing
* [ds84182](http://github.com/ds84182) is currently working on an implementation of Pica's geometry shaders
* [bunnei](https://github.com/bunnei) has plans to work on Circle Pad Pro (required for getting Majora's Mask in game), CROs, and a JIT compiler for faster CPU emulation
* [Lioncash](https://github.com/lioncash) has plans to continue working on ARM11 CPU emulation, improving both accuracy and performance
With all of these exciting new features upcoming, it's quite possible that 2016 might be the year that Citra becomes official with a v1.0 release!
## Special Thanks from Bunnei
While working on this article, I found that it was easy to find major changes to write about, but that these really only captured a fraction of the progress made in 2015 as there was work done literally every single day to make Citra what it is now. While I wish I could draw attention to every contribution made, thats just not reasonable to do in one article so instead Id like to personally thank each person that impacted Citra in the past year: [Lioncash](https://github.com/lioncash), [yuriks](https://github.com/yuriks), [neobrain](http://github.com/neobrain), [Subv](https://github.com/Subv), [archshift](http://github.com/archshift), [linkmauve](http://github.com/linkmauve), [tfarley](https://github.com/tfarley), [purpasmart96](http://github.com/purpasmart96),[aroulin](http://github.com/aroulin), [chinhodado](https://github.com/chinhodado), [polaris-](https://github.com/polaris-), [zawata](http://github.com/zawata), [kevinhartman](http://github.com/kevinhartman), [Cruel](http://github.com/cruel), [Lectem](http://github.com/lectem), [jroweboy](http://github.com/jroweboy), [LittleWhite-tb](http://github.com/littlewhite-tb), [Normmatt](http://github.com/normmatt), [kemenaran](http://github.com/kemenaran), [rohit-n](http://github.com/rohit-n), [Yllodra](http://github.com/yllodra), [xsacha](http://github.com/xsacha), [darkf](http://github.com/darkf), [filfat](http://github.com/filfat), [SeannyM](http://github.com/seannym), [uppfinnarn](http://github.com/uppfinnarn), [Kingcom](http://github.com/kingcom), [Zaneo](http://github.com/zaneo), [wwylele](http://github.com/wwylele), [Zangetsu38](http://github.com/zangetsu38), [Apology11](http://github.com/apology11), [Kloen](http://github.com/kloen), [MoochMcGee](http://github.com/moochmcgee), [gwicks](http://github.com/gwicks), [vaguilar](http://github.com/vaguilar), [chrisvj](http://github.com/chrisvj), [Sethpaien](http://github.com/sethpaien), [Gareth422](http://github.com/gareth422), [JSFernandes](http://github.com/jsfernandes), [esoteric-programmer](http://github.com/esoteric-programmer), [martinlindhe](http://github.com/martinlindhe), [clienthax](http://github.com/clienthax), [ILOVEPIE](http://github.com/ILOVEPIE), [zhuowei](http://github.com/zhuowei), [Bentley](http://github.com/bentley), [mailwl](http://github.com/mailwl), [Disruption](http://github.com/disruption), [LFsWang](http://github.com/lfswang), [Antidote](http://github.com/antidote), [ichfly](http://github.com/ichfly). I cant wait to see what you guys bring for 2016!

View File

@ -0,0 +1,103 @@
+++
date = "2016-04-19T12:12:00-05:00"
title = "Citra Progress Report - 2016 P1"
tags = [ "progress-report" ]
author = "jmc47"
forum = 37
+++
Welcome to the first Citra Progress Report of 2016! While 2015 will be considered the year that Citra first played games, 2016 is quickly shaping up as a year filled with higher compatibility, greater stability and much more as Citra matures. The avalanche of new features from tons of contributors has made it hard to keep up with everything even for developers!
Because there have been so many changes and there are so many different games, it can be very hard to keep up with what is working and what is not. To try and make things a little easier, we've compiled some of the biggest changes of the new year together to show you just how far Citra has come already!
## [Immediate Mode Vertex Submission Part 1](https://github.com/citra-emu/citra/pull/1394) and [Part 2](https://github.com/citra-emu/citra/pull/1461) by [ds84182](https://github.com/ds84182) & [yuriks](https://github.com/yuriks)
Immediate Mode Vertex Submission is a second way for the PICA200 (aka the 3DS GPU) to draw vertices. Unlike the normal method, Immediate Mode trades off some efficiency when drawing complex models for less overhead on each object. This makes it a suitable option for things such as UI elements. Despite all of that, it's capable of being used for just about anything, and some games use it for drawing all of their graphics.
[ds84182](https://github.com/ds84182) first implemented the feature and showed just how many games it could fix. After it was merged, some issues were found and [yuriks](https://github.com/yuriks) fixed some edge cases and added support for *vertex restart*. Vertex Restart is a feature necessary when drawing using triangle strips, in order to break apart consecutive strips.
<p style="text-align: center;"> <img alt="" src="/images/entry/citra-progress-report-2016-p1/etrianodysseytop.png" style="width: 400px; height: 240px;" /><img alt="" src="/images/entry/citra-progress-report-2016-p1/etrianodysseybottom.png" style="width: 320px; height: 240px;" />
<p style="text-align: center;">Etrian Odyssey IV running in Citra with Immediate Mode Vertex Submission
With this, along with previous fixes of [#1462](https://github.com/citra-emu/citra/pull/1462) and [#1624](https://github.com/citra-emu/citra/pull/1624) for correct depth writing behaviors, Etrian Odyssey IV and other games appear to be playable in Citra.
## [Unicode Support on Windows](https://github.com/citra-emu/citra/pull/1541) by [LFsWang](https://github.com/LFsWang)
Due to the different way Windows reports filenames to programs compared to Linux or OS X, Citra was previously unable to load any files with a path containing non-English characters. That is, if your file was named using accented letters, Chinese, Japanese characters, emoji, or in general any characters not present in the [ASCII](https://en.wikipedia.org/wiki/ASCII) character set, Citra would be unable to find the file! Considering Citra is developed and used by people around the world, this was a very important issue. We did not want people to need to rename files or directories to be able to open them with Citra.
[LFsWang](https://github.com/LFsWang) took the time to fix the frontend code so that Citra was able to correctly load these files. [More recently](https://github.com/citra-emu/citra/pull/1620) further improvements were made so that this works correctly even if you're loading files with characters from a language different than the one running on your operating system.
## [Fix MAD/MADI Shader Instruction Encoding](https://github.com/citra-emu/citra/pull/1479) by [JayFoxRox](https://github.com/JayFoxRox)
MAD and MADI (Multiply-Add and Multiply-Add Inverted, respectively.) are shader instructions in the PICA200 GPU, handled by Citra's shader JIT and interpreter. These instructions execute a multiplication followed by an addition (*d* = *a* × *b* + *c*) in the same instruction. They're unique in that they're the only instructions that works with 3 source operands, and thus have a special way of being encoded into the program. Citra interpreted this format incorrectly, causing it to sometimes operate on the wrong values!
Handling these instructions correctly, much like a CPU emulator, is paramount for accurate emulation. In this case, it happened that these instructions were commonly used in font rendering shaders, and this bug often manifested as gibberish textures and incorrect positioning, as can be seen in this The Legend of Zelda: A Link Between Worlds screenshot:
<p style="text-align: center;"><img alt="" src="/images/entry/citra-progress-report-2016-p1/albwbefore.png" style="width: 400px; height: 480px;" /><img alt="" src="/images/entry/citra-progress-report-2016-p1/albwafter.jpg" style="width: 400px; height: 480px;" />
<p style="text-align: center;">The Hylian language just seems to get harder and harder to read every game! Oh... wait.
Considering that emulators over a decade older than Citra are still finding problems with how CPU instructions are handled, it's no surprise that our shaders aren't bullet-proof yet either. There should be many, many games affected by the encoding fixes, so if you've been seeing gibberish text or other problems, there's a fair chance that this change could have fixed the bug.
## [Align Attribute Components](https://github.com/citra-emu/citra/pull/1496) by [JayFoxRox](https://github.com/JayFoxRox)
Vertex Attributes are an integral step in rendering. They can tell the GPU the bone weight, color, position, etc. So when [JayFoxRox](http://github.com/JayFoxRox) discovered that the Vertex Attributes were misaligned and pulling the incorrect values, he knew he stumbled upon a major problem. One game in particular affected by this was Super Smash Bros. 4, which since the MAD/MADI fixes had been displaying some graphics, although things looked pretty messed up.
<p style="text-align: center;"><img alt="Pikachu has seen better days." src="/images/entry/citra-progress-report-2016-p1/smashbrosbefore.jpg" style="width: 400px; height: 240px;" /><img alt="While lighting is a bit off, the game looks fairly playable!" src="/images/entry/citra-progress-report-2016-p1/smashbrosafter.png" style="width: 400px; height: 240px;" />
<p style="text-align: center;">With this fix, the Super Smash Bros. 4 actually looks fairly playable!
The align attributes fixes should also fix other games where the graphics tend to explode like Super Smash Bros. 4.
## [Save Fixes](https://github.com/citra-emu/citra/pull/1302) by [Subv](https://github.com/Subv)
One of the more notable problems that Citra has currently is that many games require a savefile extracted from the 3DS in order to get in game. This is due to many reasons, including partial or incorrect file system and OS emulation. Because getting saves from newer games can be problematic due to encryption (and it's generally a pain anyway), getting Citra to create and load savegames properly is a very important task that will continue to be a priority for the forseeable future.
The save fixes recently merged mostly have to do with formatting the cartridge saves correctly. 3DS titles are very picky about how their saves are formatted and will often fail if all of the files aren't handled *exactly* like they want. This was the reason why Mario Kart 7 would hang in Citra! And once you're in game, it is quite the visual treat for a 3DS title!
<p style="text-align: center;"><img alt="" src="/images/entry/citra-progress-report-2016-p1/mk7.jpg" style="width: 800px; height: 441px;" />
<p style="text-align: center;">Mario Kart 7 is now fully playable in Citra and looking better than ever!
The above change fixes Mario Kart 7, Final Fantasy Explorers, Lego Batman 3: Beyond Gotham, The Amazing Spiderman, and likely many others games that previously hung while creating or deleting savefiles.
## [Clear Shader JIT Cache](https://github.com/citra-emu/citra/pull/1503) by [bunnei](https://github.com/bunnei)
Citra's GPU shader JIT had a bit of a flaw: It would keep previously compiled shaders in memory forever. Furthermore, it only allocated a fixed amount of space for all compiled shader code. When testing the early games that booted on Citra, none of this seemed to matter and things continued fine. But, as Citra has been running more complex games and was being used by more users for longer periods of time, it became apparent that this simply wasn't good enough. Games were managing to fill up the fixed amount of space that Citra had allocated for the Shader JIT Cache and crashing the emulator!
[bunnei](https://github.com/bunnei) added a simple fix to the memory management which allows Citra to drop old, unused shaders in order to free up space for new ones being requested by the game, fixing these crashes and allowing for longer game sessions. For example, Kirby: Triple Deluxe is now stable in Citra, even when using the Shader JIT:
<p style="text-align: center;"><img alt="" src="/images/entry/citra-progress-report-2016-p1/b.png" style="width: 400px; height: 240px;" /><img alt="" src="/images/entry/citra-progress-report-2016-p1/c.png" style="width: 400px; height: 240px;" />
<p style="text-align: center;">Kirby: Triple Deluxe used to crash almost immediately while in game
## [Shader JIT Refactor](https://github.com/citra-emu/citra/pull/1546) by [bunnei](https://github.com/bunnei)
While most of the issues with the shader JIT were fixed with the aforemoentioned changes, there remained a fundamental flaw with how flow control was handled. Previously, the shader JIT inlined CALL and JMP instructions. This had several issues: 1) Inlining all subroutines resulted in bloated shaders being generated, and 2) jumping to arbitrary addresses (and nested jumps) couldn't be supported. This is because when inlining code, the same source shader code might be recompiled multiple times. To support arbitrary jumps, there needed to be a one-to-one mapping of source code to compiled code.
To fix this, [bunnei](https://github.com/bunnei) refactored the shader JIT to do a multiple step compile: First, analyze the shader and identify subroutines, jumps, and return locations. Next, compile the code (just once), and insert additional code to handle the returns and jumps. In addition to enabling arbitrary CALL/JMP instructions, this results in pretty constant compiled shader sizes of around 40kb, which significantly reduced the memory footprint of the shader JIT.
This change fixes IronFall: Invasion, Pokemon: Rumble Blast, and several other games:
<p style="text-align: center;"><img alt="" src="/images/entry/citra-progress-report-2016-p1/1.png" style="width: 400px; height: 240px;" /><img alt="" src="/images/entry/citra-progress-report-2016-p1/2.png" style="width: 320px; height: 240px;" />
<p style="text-align: center;">With these changes, all known graphical glitches with IronFall: Invasion are fixed in Citra
## [Audio Framework](https://github.com/citra-emu/citra/pull/1386) by [MerryMage](https://github.com/merrymage)
We'd like to mention the amazing work done by [MerryMage](https://github.com/merrymage) to bring proper DSP HLE and audio support to Citra. Over the past few months, she has been carefully chipping away at figuring out how audio 3DS works, removing several hacks in Citra along the way. While many of her efforts have been transparent to users up until this point, they have laid the groundwork for soon-to-come audio support. With changes [#1386](https://github.com/citra-emu/citra/pull/1386), [#1403]https://github.com/citra-emu/citra/pull/1403), [#1441](https://github.com/citra-emu/citra/pull/1441), [#1566](https://github.com/citra-emu/citra/pull/1566), and [#1572](https://github.com/citra-emu/citra/pull/1572), we're now closer than ever to hearing games for the first time in Citra! While [MerryMage](http://github.com/merrymage) has audio nearly complete in unofficial branches, there are still a few remaining issues before it gets merged.
## Contributors of 2016
We've got a fortunate problem to have: It's often too difficult to mention every contribution made to Citra when writing progress reports! We'd like to extend a special thanks [to all that helped advance Citra further](https://github.com/citra-emu/citra/graphs/contributors?from=2016-01-01&amp;to=2016-04-19&amp;type=c) since our last progress report, you guys rock!

View File

@ -0,0 +1,44 @@
+++
date = "2016-05-20T18:04:00-05:00"
title = "HLE Audio Comes to Citra"
tags = [ "feature-update" ]
author = "merrymage"
forum = 38
+++
*Special thanks must be given to fincs and the rest of the 3DS community for their work reverse-engineering the DSP firmware. Without that work, Citra would not be this far with audio emulation.*
As of [May 19th, 2016](https://github.com/citra-emu/citra/commit/af258584d978f02d462743012491a273c61b067e), Citra now has preliminary High Level Emulation (HLE) audio support! This means that users playing on Citra no longer have to listen to the deafening sound of silence in many titles. To get to this point was a huge reverse-engineering effort done by multiple people, with much of the reverse-engineering and the final implementation for Citra coming from MerryMage. This undertaking has required many months of development but the end result brings sound to the masses.
{{< youtube 8LCUlyjvTJU >}}
## **Technical Details on how Audio Works for the 3DS**
Audio processing and output is done by a specialised coprocessor. These kinds of coprocessors are called Digital Signal Processors (DSPs).
Games that run on the 3DS need to communicate with the DSP in order to play audio. They do this by two ways: via the the <span style="font-family:'Courier New'">dsp::DSP</span> service and via a shared memory region. The <span style="font-family:'Courier New'">dsp::DSP</span> service provides service calls for initialization of the DSP hardware including firmware upload. The shared memory region is used for communication between the game on the CPU and the firmware on the DSP.
In order to emulate audio, Citra must emulate the <span style="font-family:'Courier New'">dsp::DSP</span> service and also understand the layout of the DSP shared memory region. One must understand what writing to various addresses in the shared memory region does. One must also understand what happens between data being fed to the DSP firmware and audio coming out of the speakers.
## **Early Reverse Engineering**
With this known MerryMage set out to trace reads and writes to shared memory that games did. She eventually ended up playing these back on hardware and figured out what the appropriate firmware responses were. This eventually lead to the early implementations of audio output that originally were shown in January by various users. Many other aspects, including ADPCM decoding, took a while to figure out. <br></br>
{{< youtube 1c_A7gpAZ8A >}}
<br></br>
MerryMage had raw audio output working but she still didnt understand how various parameters were applied to the audio by the firmware. It was at this point where she discovered that the firmware writes back what is output to the speakers into the shared memory region. This discovery made future work with audio effects much easier as bit perfect audio could be dumped as the 3DS produced it without any extra hardware. Having real hardware audio output on hand meant MerryMage could also apply signal processing techniques like system identification to figure out what internal processing the firmware does.
With this newfound knowledge and this new set of tools MerryMage rapidly conquered what the firmware was doing.
## **Time Stretching**
Emulation speed can vary a lot between games or even parts of games. To accomodate this, time streching was added as an audio enhancement. This post-processing effect adjusts audio speed to match emulation speed and helps prevent audio stutter. This is an effect completely separate from emulation and is only to alter and improve audio played back when the emulator is not going full speed.
## **Future Plans for Audio**
Audio is still not complete! There are still a number of unimplemented features and accuracy improvements to have. Many of these features have been reverse engineered already but simply aren't implemented. This includes reverb, delay, and other minor audio effects. Some features require more reverse engineering work, such as looped buffers and surround sound.
While the black-box reverse engineering approach has served well so far, further improvements in accuracy can more easily be made by decompiling the firmware and perhaps implementing Low Level Emulation (LLE) audio. This comes with its own set of challenges especially as the DSP architecture is not well known and there is little documentation on it.
Until then, we at Citra hope that everyone enjoys this initial HLE audio implementation!

View File

@ -0,0 +1,26 @@
+++
date = "2016-12-06T16:56:00-05:00"
title = "Migrate Your Savefiles"
author = "thekoopakingdom"
forum = 40
+++
In new versions of Citra, the location of saves has changed, so this guide will show how to migrate your saves to the new location on Window (Linux and macOS Bleeding Edge builds are planned, we are currently busy working on bringing nightly builds back.).
1. Press Windows + R, type ```explorer %localappdata%```, this should bring up a Windows Explorer window in a ```Local``` folder. Navigate to the ```citra``` folder.
<br></br>
{{< img src="entry/migrate-your-savefiles/ex_1.png" width="574px" height="142px">}}
2. Navigate to the ```app-x.x.x``` folder with the highest version number.
<br></br>
{{< img src="entry/migrate-your-savefiles/ex_2.png" width="570px" height="497px">}}
3. Move the ```user``` folder to your desktop. **<u>Make sure the user folder no longer exists in the existing folder.</u>**
4. Run ```citra-qt.exe```. The settings should now be reset, and Citra will begin using the new location. Now you can exit it.
5. Press Windows + R, type ```explorer %appdata%```, this should bring up a Windows Explorer window in a ```Roaming``` folder. Navigate to the ```Citra ```folder.
6. Move the contents of the ```user``` folder on your desktop to the ```Citra``` folder, overwrite any files if asked.
Now, all of your settings and saves for Citra have been moved to the new location, which has the advantage of being able to be accessed by any new version of Citra, bringing stability improvements and storing your user data in a safe place.

View File

@ -0,0 +1,25 @@
+++
date = "2016-05-01T21:56:00-05:00"
title = "Texture Forwarding brings HD output to Citra"
tags = ["feature-update"]
author = "jmc47"
coauthor = "tfarley"
forum = 190
+++
One of the big things everyone has been wondering about Citra is when it will be able to render games at HD resolutions. One of the great things about emulators is that they can surpass the limitations of the original console, especially when it comes to graphical fidelity. With the 3DS specifically, many beautifully detailed games are hidden behind staggeringly low resolution screens topping out at 400x240. With **Texture Forwarding** (from tfarley, based on yuriks early implementation), Citra can now output games at any resolution, and runs faster as well!
{{< youtube 7XFcTqoZ3nk >}}
## What is Texture Forwarding?
To understand Texture Forwarding, we've created a diagram to show what's actually going on.
{{< img src="entry/texture-forwarding-brings-hd-output-to-citra/citra-texture-forwarding.png" width="481px" height="367px" center="true" >}}
<br></br>
The diagram is a simplified representation of the actual pipeline, as 3DS games perform multiple additional steps such as framebuffer copies between rendering and display - but the concept remains the same. The main idea is to keep framebuffers rendered by the HW Renderer as textures on the GPU as much as possible, to avoid the performance overhead of transferring them between the CPU and GPU as in the Slow Path. In most instances, the CPU never accesses (reads from/writes to) a rendered frame so it can safely stay on the GPU from rendering all the way through to ultimate display in Citra. This eliminates CPU/GPU sync points and makes the emulator faster overall.
<br></br>
In addition to a performance boost, Texture Forwarding also allows the HW Renderer to render and display at higher resolutions than the native 3DS when the pixel data is not accessed from anywhere else. But in the event that the memory region of some texture is reador writtenby the CPU, the renderer will fall back to the slow path and downsample the texture back to native resolution to ensure that the accesses are reflected accurately.
If you're interested in seeing just how nice some 3DS games look, [HD screenshots have been added to Citra's screenshots page!](https://citra-emu.org/screenshots) Or you can try it yourself on your 3DS games by downloading the latest build of Citra from the [download's page](https://citra-emu.org/page/download).

View File

@ -0,0 +1,12 @@
+++
date = "2017-01-05T00:00:00-05:00"
title = "The Nightly Builds are back!"
tags = ["citra-release"]
author = "leo121"
coauthor = "flamboyant_ham"
forum = 41
+++
As you all know, the Nightly builds have been down for some time now due to the former maintainer not being around, but the issues have been resolved, and the Nightly builds are now available on our [downloads page](https://citra-emu.org/page/download) once again! With downloads available for Windows, macOS, and Linux, you're no longer required to compile the build yourself.
Likewise, we'd like to remind all users that any bugs found within Citra, or during emulation, be reported from the Nightly builds, and not the Bleeding Edge ones. From hereon out, support for the latter will no longer be given. If you believe you've found a bug in Bleeding Edge, please retest on the latest Nightly build. Thank you everyone for your patience, and Happy New Year!

View File

@ -0,0 +1,24 @@
+++
date = "2016-09-02T15:05:00-05:00"
title = "We now have a Discord server!"
author = "thekoopakingdom"
forum = 39
+++
If you haven't heard of [Discord](https://discordapp.com/) yet, it's basically an alternative to Skype, featuring servers with both voice and text chat. You can use it in your browser, download the desktop program, or get the mobile app.
If you don't have an account already, you can make one for free [here](https://discordapp.com/register).
Once you've done that, you can join Citra's official server by going [here](https://discord.gg/fZwvKPu).
There are 5 channels:
* #read-first - A read-only introduction to the server, and announcements.
* #citra-general - Any discussion related to Citra.
* #citra-support - If you are having trouble with Citra, you can ask for help here. **Please read #read-first, first.**
* #dumping-support - Support for dumping games/system files for Citra.
* #offtopic - Anything not related to Citra that doesn't belong in #citra-general goes here.
The [Citra](https://citra-emu.org/page/rules) Community Rules also apply to this server.
Have fun!

View File

@ -0,0 +1,32 @@
+++
date = "2016-02-22T22:18:00-05:00"
title = "Welcome to the New Citra!"
author = "flamesage"
forum = 8
+++
Welcome to the brand new Citra website! This new site has been a sort of secret project off and on for over a year now. A lot of hard work, a few false starts, but here we are! This has been a big team effort - we'd like to especially thank [Flame Sage](https://community.citra-emu.org/users/flamesage/activity), the primary architect behind the new website backend; [MaJoR](https://community.citra-emu.org/users/mayimilae/activity) for the design and artwork, and lastly jchadwick for his early on role in the project. Here's a brief overview of some of our new features!
**[Blog](https://citra-emu.org):** Citra now *finally* has a platform to share information with everyone directly! It will allow Citra to communicate directly to users and fans in long form, fully exploring 3DS emulation in ways that were impossible to express before. An article is already up talking about the past year of development, and more will come!
**[Community](https://community.citra-emu.org/):** Citra now has its own discussion forum! It is now open, so come on everyone and join! Instead of the typical forum software, we are using a brand new open source forum software that is focused on streamlining and simplifying bulletin boards. It's a little different from what you might be used to, but it is a joy to use!
**[Wiki](https://citra-emu.org/wiki/Home):** The site has it's own wiki! But not a mediawiki - select articles from github can be elevated here for easy access to user-update guides and other materials. In time, it will make Citra much easier to use.
**[Screenshots](https://citra-emu.org/screenshots):** We have our own screenshots gallery, which will give us a *lot* more room for a lot more screenshots! With easy navigation and viewing to boot.
**Logo:** And finally, this is the official reveal of our new logo!
{{< img src="entry/welcome-to-the-new-citra/citralogoforarticle.jpg" width="640px" height="320px" center="true" >}}
There's a LOT more work to be done, so things are definitely a work in progress. For example, a new download page with archives is high on our list! But we're going to keep working hard and keep making things better.

View File

@ -0,0 +1,17 @@
+++
date = "2017-01-17T20:36:00-05:00"
title = "We're Moving to Discourse!"
author = "flamesage"
coauthor = "bunnei"
forum = 54
+++
As we approach the first birthday of Citra's website, we'd like to announce yet another project infrastructure update:
**We've decided to launch a [new forum](http://community.citra-emu.org/) based on the [Discourse](https://www.discourse.org/) forum software!**
When we first introduced the new website back in February of 2016, we chose to use [Flarum](http://flarum.org/) over more classic forums used on other websites (such as phpBB, MyBB, or vBulletin). The reason for this was because Flarum was a much more modern platform, with better mobile support, and a attractive and innovative UI. It seemingly had a very promising future, receiving multiple large updates in a very short timeframe. But while it was great to use at first, it ultimately left us wanting some critical features that never seemed to come - such as the ability to send private messages.
Meet [Discourse](https://www.discourse.org/), an open source forum platform with the features that we need. Not only does it improve our ability to moderate, but the every day user experience should also be enhanced. Discourse is a widely used and established platform, used by such communities as [Imgur](https://community.imgur.com/), [Twitter](https://twittercommunity.com/), [Github](https://discuss.atom.io/), [Ubuntu](http://discourse.ubuntu.com/), and [more](https://www.discourse.org/faq/customers/). The layout of the new forums are simple, users of Flarum should have no problem getting used to it!
You can visit the new forums at https://community.citra-emu.org/, come say Hello! You'll need to create a new account, but we now support using your Google or GitHub credentials to log in!

40
site/content/rules.md Normal file
View File

@ -0,0 +1,40 @@
+++
title = "Community Rules"
+++
## Warez/downloading games talk is prohibited.
To prevent legal issues, you may not request or refer to any kind of ROM, NAND, ISO, game, or other copyrighted material that has been illegally obtained or shared. This rule also applies to pre-release leaks. We don't allow discussion / support requests about games until they are officially released.
If any post like that is found, the thread containing it will be locked and further support revoked. Stating that you've downloaded a ROM or telling others where to download a ROM will get you suspended from the forum immediately, no matter if you purchased the game or not. You must <a href="https://citra-emu.org/wiki/dumping-game-cartridges">legally dump/rip your own games</a>, NAND, etc. <a href="https://citra-emu.org/wiki/home-folder">Home Folder Files</a> fall under warez / NAND files, do not ask for download links or post them!
## Do not link unofficial builds.
Unofficial builds (Versions of Citra not downloaded from here) are not supported. Because they may introduce new bugs, contain GPL violations, or be a virus. You may not ask for support with non-nightly builds, or provide download links to them.
## Asking for help
When asking for support, please always provide the githash - located in the title bar of citra's GUI - your full PC specs (CPU, RAM, GPU, Operating System), any relevant settings, and detailed information on what you are attempting to do (such as what game you are trying to run). Ignoring this rule may result in your thread being locked.
## General posting guidelines
Flaming/harassment of other members will not be tolerated. We want to keep our forums civil and friendly. If you have an issue with a member that you cannot resolve on your own, please ask a moderator or administrator to help.
You may not post or display any content (images, text, videos) that is sexually explicit or erotic, i.e. content whose sole purpose is arousal. This forum does not currently have spoiler tags, so any questionable content for artistic use involving nudity or highly offensive/descriptive language must be hosted outside of the forum and showed here only as a link with suitable NFSW warnings.
No spamming, off-topic posts. We will not tolerate posts that are either irrelevant to a thread's subject or solely for advertising. Also before posting, please assign appropriate tags that fit your thread. Users on the forum are allowed to self-promote if they are involved with the community, but random promotion from unknown accounts is SPAM and will be deleted.
## How many accounts can I have at one time?
Users may only have one active account at a time. Alternate, duplicate, or multiple active accounts will be suspended from the forums.
## Can I post in other languages?
This is an English only forum, please do not post in any other language. If you are not a native English speaker and are using a translator to assist, you may write your post in your own language as long as you provide the text of the automatic translation in the post.
## Repercussions
First and foremost, breaking a rule related to piracy will result in an immediate suspension of your account, and likely the deletion of the infringing post.
The moderation staff will discuss prolonged or permanent suspension beforehand on every case, with the only exceptions being SPAM, or anything imminently harmful such as harassment.
Short suspensions of under one month are left to the discretion of the staff involved per the situation.

View File

@ -0,0 +1,4 @@
+++
title = "Screenshots"
type = "screenshots"
+++

11
site/data/authors.json Normal file
View File

@ -0,0 +1,11 @@
{
"flamesage": { "key": "flamesage", "name": "Flame Sage", "avatar": "https://community.citra-emu.org/user_avatar/community.citra-emu.org/flamesage/120/6_1.png" },
"bunnei": { "key": "bunnei", "name": "bunnei", "avatar": "https://community.citra-emu.org/user_avatar/community.citra-emu.org/bunnei/120/21_1.png" },
"thekoopakingdom": { "key": "thekoopakingdom", "name": "The Koopa Kingdom", "avatar": "https://community.citra-emu.org/user_avatar/community.citra-emu.org/thekoopakingdom/120/8_1.png" },
"leo121": { "key": "leo121", "name": "leo121", "avatar": "https://community.citra-emu.org/user_avatar/community.citra-emu.org/leo121/120/10_1.png" },
"flamboyant_ham": { "key": "flamboyant_ham", "name": "Flamboyant_Ham", "avatar": "https://community.citra-emu.org/user_avatar/community.citra-emu.org/flamboyant_ham/120/9_1.png" },
"tfarley": { "key": "tfarley", "name": "tfarley", "avatar": "https://community.citra-emu.org/user_avatar/community.citra-emu.org/citrabot/120/28_1.png" },
"merrymage": { "key": "merrymage", "name": "Merry Mage", "avatar": "https://community.citra-emu.org/user_avatar/community.citra-emu.org/citrabot/120/28_1.png" },
"jroweboy": { "key": "jroweboy", "name": "jroweboy", "avatar": "https://community.citra-emu.org/user_avatar/community.citra-emu.org/jroweboy/120/30_1.png" },
"jmc47": { "key": "jmc47", "name": "JMC47", "avatar": "https://community.citra-emu.org/user_avatar/community.citra-emu.org/citrabot/120/28_1.png" }
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 503 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

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