tree-wide: adapt to latest Hugo layout ...
* Use Hugo to process SCSS and images * Use co-location page bundles * Use Hugo/ESBuild to minify JS files * Update NPM dependencies
|
@ -8,6 +8,7 @@ site/hugo.exe
|
|||
build/
|
||||
public/
|
||||
site/public/
|
||||
site/resources/_gen/
|
||||
.publish/
|
||||
|
||||
# Dynamic content imported on deploy.
|
||||
|
|
44
gulpfile.js
|
@ -5,13 +5,9 @@ const merge = require('merge-stream');
|
|||
const exec = require('child_process').exec;
|
||||
const log = require('fancy-log');
|
||||
const parseArgs = require('minimist');
|
||||
const sass = require('gulp-sass')(require('sass'));
|
||||
const postcss = require('gulp-postcss');
|
||||
const cssnano = require('cssnano');
|
||||
const browserSync = require('browser-sync').create();
|
||||
const concat = require('gulp-concat');
|
||||
const imageResize = require('gulp-image-resize');
|
||||
const hugo = require('hugo-bin');
|
||||
|
||||
gulp.task('scripts:games', function (callback) {
|
||||
exec('yarn install && node app.js', { cwd: './scripts/shared-hugo-scripts/compatdb/' }, function (err, stdout, stderr) {
|
||||
|
@ -26,24 +22,24 @@ gulp.task('scripts:wiki', function (callback) {
|
|||
});
|
||||
|
||||
gulp.task('assets:images', function() {
|
||||
var baseImages = gulp.src('build/images/*', {base: './'})
|
||||
const baseImages = gulp.src('build/images/*', {base: './'})
|
||||
.pipe(gulp.dest('./'));
|
||||
var jumbotronImages = gulp.src('build/images/jumbotron/*', {base: './'})
|
||||
const jumbotronImages = gulp.src('build/images/jumbotron/*', {base: './'})
|
||||
.pipe(imageResize({ width: 786, height: 471, crop: true }))
|
||||
.pipe(gulp.dest('./'));
|
||||
var bannerImages = gulp.src('build/images/banners/*', {base: './'})
|
||||
const bannerImages = gulp.src('build/images/banners/*', {base: './'})
|
||||
.pipe(imageResize({ width: 824, height: 306, crop: false }))
|
||||
.pipe(gulp.dest('./'));
|
||||
var boxartImages = gulp.src('build/images/game/boxart/*', {base: './'})
|
||||
const boxartImages = gulp.src('build/images/game/boxart/*', {base: './'})
|
||||
.pipe(imageResize({ width: 328, height: 300, crop: true }))
|
||||
.pipe(gulp.dest('./'));
|
||||
var iconImages = gulp.src('build/images/game/icons/*', {base: './'})
|
||||
const iconImages = gulp.src('build/images/game/icons/*', {base: './'})
|
||||
.pipe(imageResize({ width: 48, height: 48, crop: true }))
|
||||
.pipe(gulp.dest('./'));
|
||||
var screenshotImages = gulp.src('build/images/screenshots/*')
|
||||
const screenshotImages = gulp.src('build/images/screenshots/*')
|
||||
.pipe(imageResize({ width: 400, height: 240, crop: false }))
|
||||
.pipe(gulp.dest('build/images/screenshots/thumbs'));
|
||||
|
||||
|
||||
return merge(baseImages, jumbotronImages, bannerImages, boxartImages, iconImages, screenshotImages);
|
||||
});
|
||||
|
||||
|
@ -58,20 +54,12 @@ gulp.task('assets:fonts', function(){
|
|||
.pipe(gulp.dest('build/fonts/'));
|
||||
});
|
||||
|
||||
gulp.task('assets:scss', function () {
|
||||
var postCssOptions = [ cssnano ];
|
||||
return gulp.src('src/scss/style.scss')
|
||||
.pipe(sass().on('error', sass.logError))
|
||||
.pipe(postcss(postCssOptions))
|
||||
.pipe(gulp.dest('build/css'))
|
||||
.pipe(browserSync.stream());
|
||||
});
|
||||
|
||||
gulp.task('hugo', function (cb) {
|
||||
exec(hugo + ' -s ./site/ -d ../build/ -v', function (err, stdout, stderr) {
|
||||
console.log(stdout);
|
||||
console.log(stderr);
|
||||
cb(err);
|
||||
gulp.task('hugo', (callback) => {
|
||||
import('hugo-bin').then((hugo) => {
|
||||
exec(hugo.default + ' -s ./site/ -d ../build/ -v --gc', (err, stdout, stderr) => {
|
||||
console.log(stdout);
|
||||
callback(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -84,7 +72,7 @@ gulp.task('final:serve', function(done) {
|
|||
});
|
||||
|
||||
gulp.watch('src/js/**/*', gulp.series('assets:js'));
|
||||
gulp.watch('src/scss/**/*', gulp.series('assets:scss'));
|
||||
gulp.watch('src/scss/**/*', gulp.series('hugo'));
|
||||
gulp.watch('site/**/*.html', gulp.series('hugo'));
|
||||
gulp.watch('site/**/*.md', gulp.series('hugo'));
|
||||
|
||||
|
@ -124,6 +112,6 @@ if (parseArgs(process.argv).production) {
|
|||
log.info(`process.env.HUGO_ENV = '${process.env.HUGO_ENV}'`);
|
||||
log.info(`process.env.HUGO_BASEURL = '${process.env.HUGO_BASEURL}'`);
|
||||
|
||||
gulp.task('default', gulp.series(gulp.parallel('assets:js', 'assets:fonts', 'assets:scss'), 'hugo', 'assets:images', finalCommand));
|
||||
gulp.task('all', gulp.series(gulp.parallel('scripts:games', 'scripts:wiki'), gulp.parallel('assets:js', 'assets:fonts', 'assets:scss'), 'hugo', 'assets:images', finalCommand));
|
||||
gulp.task('default', gulp.series(gulp.parallel('assets:js', 'assets:fonts'), 'hugo', 'assets:images', finalCommand));
|
||||
gulp.task('all', gulp.series(gulp.parallel('scripts:games', 'scripts:wiki'), gulp.parallel('assets:js', 'assets:fonts'), 'hugo', 'assets:images', finalCommand));
|
||||
gulp.task('content', gulp.series('hugo', finalCommand));
|
||||
|
|
15
package.json
|
@ -9,11 +9,10 @@
|
|||
"serve": "gulp all"
|
||||
},
|
||||
"dependencies": {
|
||||
"bootstrap-sass": "^3.4.1",
|
||||
"browser-sync": "^2.27.7",
|
||||
"cssnano": "^5.0.17",
|
||||
"bootstrap-sass": "^3.4.3",
|
||||
"browser-sync": "^2.27.11",
|
||||
"cssnano": "^5.1.14",
|
||||
"fancy-log": "^2.0.0",
|
||||
"hugo-bin": "0.40.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-changed": "^4.0.3",
|
||||
"gulp-clean-css": "^4.3.0",
|
||||
|
@ -22,9 +21,13 @@
|
|||
"gulp-image-resize": "^0.13.1",
|
||||
"gulp-postcss": "^9.0.1",
|
||||
"gulp-sass": "^5.1.0",
|
||||
"hugo-bin": "0.98.0",
|
||||
"merge-stream": "^2.0.0",
|
||||
"minimist": "^1.2.5",
|
||||
"minimist": "^1.2.7",
|
||||
"postcss": "^8.4",
|
||||
"sass": "^1.49.7"
|
||||
"sass": "^1.57.1"
|
||||
},
|
||||
"hugo-bin": {
|
||||
"buildTags": "extended"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
function getRelease(v, count = 5) {
|
||||
$.getJSON(
|
||||
`https://api.github.com/repos/citra-emu/citra-${v}/releases`,
|
||||
function (releases) {
|
||||
$(`#last-updated-${v}`).text(dayjs(releases[0].published_at).fromNow());
|
||||
|
||||
for (let i = 0; i < releases.length; ++i) {
|
||||
const release = releases[i];
|
||||
let release_date = dayjs(release.published_at).fromNow();
|
||||
|
||||
let release_commit = release.assets[0].name
|
||||
.split("-")
|
||||
.pop()
|
||||
.trim()
|
||||
.split(".")[0];
|
||||
let 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 == "canary") {
|
||||
release_title = "Canary Build";
|
||||
} else if (v == "android") {
|
||||
release_title = "Android Build";
|
||||
}
|
||||
|
||||
if (release_commit) {
|
||||
release_title += " - " + release_commit;
|
||||
}
|
||||
|
||||
let download_span = "";
|
||||
|
||||
let table_style = "";
|
||||
if (i == 0) {
|
||||
table_style = "table-first";
|
||||
}
|
||||
|
||||
release.assets.forEach(function (asset) {
|
||||
const is_windows =
|
||||
asset.name.includes("windows") || asset.name.includes("exe");
|
||||
if (asset.name.includes("nupkg")) return;
|
||||
if (asset.name.includes(".aab")) return;
|
||||
if (!is_windows && asset.name.includes(".7z")) return;
|
||||
if (is_windows && asset.name.includes(".tar.gz")) return;
|
||||
if (asset.name.includes("RELEASES")) return;
|
||||
|
||||
/* We only want to provide mingw builds on the downloads page. */
|
||||
if (asset.name.includes("-msvc-")) return;
|
||||
|
||||
let env_icon = "/images/icons/file.png";
|
||||
if (is_windows) 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";
|
||||
else if (asset.name.includes(".apk"))
|
||||
env_icon = "/images/icons/android.png";
|
||||
else if (asset.name.includes("unified-source"))
|
||||
env_icon = "/images/icons/file-code.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function fetchReleases() {
|
||||
getRelease("nightly");
|
||||
getRelease("canary");
|
||||
getRelease("android");
|
||||
}
|
||||
|
||||
dayjs.extend(dayjs_plugin_relativeTime);
|
||||
// Attempt autodetection of their operating system
|
||||
const userAgent = navigator.userAgent.toLowerCase();
|
||||
|
||||
const allPlatforms = ["windows", "mac", "linux", "android"];
|
||||
|
||||
let os = undefined;
|
||||
if (userAgent.indexOf("windows") !== -1) {
|
||||
os = "Windows";
|
||||
} else if (
|
||||
userAgent.indexOf("mac") !== -1 &&
|
||||
userAgent.indexOf("mobile") === -1 &&
|
||||
userAgent.indexOf("phone") === -1
|
||||
) {
|
||||
os = "Mac";
|
||||
} else if (
|
||||
userAgent.indexOf("linux") !== -1 &&
|
||||
userAgent.indexOf("android") === -1
|
||||
) {
|
||||
os = "Linux";
|
||||
} else if (userAgent.indexOf("android") !== -1) {
|
||||
os = "Android";
|
||||
}
|
||||
|
||||
if (os !== undefined) {
|
||||
$("#dl-" + os.toLowerCase() + "-x64").css("display", "block");
|
||||
|
||||
const autodetect = $("#dl-autodetect");
|
||||
autodetect.text("Autodetected platform: " + os);
|
||||
autodetect.css("display", "inline");
|
||||
} else {
|
||||
$("#dl-unknown").css("display", "block");
|
||||
}
|
||||
|
||||
$("#no-js-view").css("display", "none");
|
||||
$("#updater-view").css("display", "block");
|
||||
|
||||
$("#other-platforms-link").click(function () {
|
||||
for (let i = 0; i < allPlatforms.length; i++) {
|
||||
const platform = allPlatforms[i];
|
||||
$("#dl-" + platform + "-x64").css("display", "block");
|
||||
$("#other-container").css("display", "none");
|
||||
}
|
||||
});
|
||||
|
||||
$("#manual-link").click(function () {
|
||||
$("#updater-view").css("display", "none");
|
||||
$("#manual-view").css("display", "block");
|
||||
fetchReleases();
|
||||
});
|
|
@ -9,7 +9,7 @@ $font-family-sans-serif: "Ubuntu";
|
|||
$headings-font-family: "Dosis";
|
||||
$headings-color: #888;
|
||||
|
||||
@import "./node_modules/bootstrap-sass/assets/stylesheets/bootstrap.scss";
|
||||
@import "../../../node_modules/bootstrap-sass/assets/stylesheets/_bootstrap.scss";
|
||||
@import "vendor/slick.scss";
|
||||
@import "citra-theme.scss";
|
||||
@import "citra-theme-media.scss";
|
|
@ -123,119 +123,6 @@ links to get you started however:<br />
|
|||
</div>
|
||||
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
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 = release.assets[0].name.split('-').pop().trim().split('.')[0];
|
||||
let 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 == 'canary') {
|
||||
release_title = 'Canary Build';
|
||||
} else if (v == 'android') {
|
||||
release_title = 'Android 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) {
|
||||
var is_windows = asset.name.includes('windows') || asset.name.includes('exe');
|
||||
if (asset.name.includes('nupkg')) return;
|
||||
if (asset.name.includes('.aab')) return;
|
||||
if (!is_windows && asset.name.includes('.7z')) return;
|
||||
if (is_windows && asset.name.includes('.tar.gz')) return;
|
||||
if (asset.name.includes('RELEASES')) return;
|
||||
|
||||
/* We only want to provide mingw builds on the downloads page. */
|
||||
if (asset.name.includes('-msvc-')) return;
|
||||
|
||||
let env_icon = '/images/icons/file.png';
|
||||
if (is_windows) 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';
|
||||
else if (asset.name.includes('.apk')) env_icon = '/images/icons/android.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; }
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function fetchReleases() {
|
||||
getRelease('nightly');
|
||||
getRelease('canary');
|
||||
getRelease('android');
|
||||
}
|
||||
|
||||
// Attempt autodetection of their operating system
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
|
||||
var allPlatforms = ["windows", "mac", "linux", "android"];
|
||||
|
||||
var os = undefined;
|
||||
if (userAgent.indexOf("windows") !== -1) {
|
||||
os = "Windows";
|
||||
} else if (userAgent.indexOf("mac") !== -1 && userAgent.indexOf("mobile") === -1 && userAgent.indexOf("phone") === -1) {
|
||||
os = "Mac";
|
||||
} else if (userAgent.indexOf("linux") !== -1 && userAgent.indexOf("android") === -1) {
|
||||
os = "Linux";
|
||||
} else if (userAgent.indexOf("android") !== -1) {
|
||||
os = "Android";
|
||||
}
|
||||
|
||||
if (os !== undefined) {
|
||||
$("#dl-" + os.toLowerCase() + "-x64").css("display", "block");
|
||||
|
||||
var autodetect = $("#dl-autodetect");
|
||||
autodetect.text("Autodetected platform: " + os);
|
||||
autodetect.css("display", "inline");
|
||||
} else {
|
||||
$("#dl-unknown").css("display", "block");
|
||||
}
|
||||
|
||||
$("#no-js-view").css("display", "none");
|
||||
$("#updater-view").css("display", "block");
|
||||
|
||||
$("#other-platforms-link").click(function() {
|
||||
for (var i = 0; i < allPlatforms.length; i++) {
|
||||
var platform = allPlatforms[i];
|
||||
$("#dl-" + platform + "-x64").css("display", "block");
|
||||
$("#other-container").css("display", "none");
|
||||
}
|
||||
});
|
||||
|
||||
$("#manual-link").click(function() {
|
||||
$("#updater-view").css("display", "none");
|
||||
$("#manual-view").css("display", "block");
|
||||
fetchReleases();
|
||||
});
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.7/dayjs.min.js" integrity="sha512-hcV6DX35BKgiTiWYrJgPbu3FxS6CsCjKgmrsPRpUPkXWbvPiKxvSVSdhWX0yXcPctOI2FJ4WP6N1zH+17B/sAA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.7/plugin/relativeTime.min.js" integrity="sha512-MVzDPmm7QZ8PhEiqJXKz/zw2HJuv61waxb8XXuZMMs9b+an3LoqOqhOEt5Nq3LY1e4Ipbbd/e+AWgERdHlVgaA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
{{< js-download >}}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
+++
|
||||
title = "Blog Entries"
|
||||
+++
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 903 KiB After Width: | Height: | Size: 903 KiB |
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
|
@ -11,7 +11,7 @@ forum = 67781
|
|||
|
||||
You've been asking for it for years now, and we've been listening, we promise!
|
||||
|
||||
{{< figure src="/images/entry/accurate-audio-emulation/pokemonleague.png"
|
||||
{{< figure src="pokemonleague.png"
|
||||
title="The Pokémon league awaits your challenge!"
|
||||
>}}
|
||||
|
||||
|
@ -33,7 +33,7 @@ We've been able to test a few of the fan favorites such as Pokémon X / Y, Fire
|
|||
|
||||
In the Audio tab of the Configuration menu, there is a new option for Emulation. Selecting "LLE (Accurate)" will use the new feature, while the default value "HLE (Fast)" will continue to use the original audio code.
|
||||
|
||||
{{< figure src="/images/entry/accurate-audio-emulation/configuration.png"
|
||||
{{< figure src="configuration.png"
|
||||
title="You can find the dropdown here. Keep in mind you cannot switch between Fast and Accurate while a game is running"
|
||||
>}}
|
||||
|
||||
|
@ -53,7 +53,7 @@ We can't ever say for sure, but we really hope that it'll be soon! We've done so
|
|||
|
||||
---
|
||||
|
||||
{{< figure src="/images/entry/accurate-audio-emulation/levelup.png"
|
||||
{{< figure src="levelup.png"
|
||||
title="With the level up freeze fixed, Citra has levelled up too!"
|
||||
>}}
|
||||
|
||||
|
@ -73,7 +73,7 @@ It's much simpler to look at disassembly and see what the code is doing than it
|
|||
Simply put, writing HLE audio support means diving deep into how the code for the game's audio works, and recreating its functionality in Citra, without ever running any actual audio code from the game.
|
||||
But there's a very different way to handle audio, and this is hinted about at the end of the 2016 article: Low Level Audio Emulation (or LLE for short).
|
||||
|
||||
{{< figure src="/images/entry/accurate-audio-emulation/echoes.png"
|
||||
{{< figure src="echoes.png"
|
||||
title="Fire Emblem Echoes: Shadows of Valentia can get past the intro now as well"
|
||||
>}}
|
||||
|
||||
|
@ -91,7 +91,7 @@ The game would transition from state to state, and, mysteriously, whenever the g
|
|||
As cool as it is to learn what causes the softlock, it doesn't answer the big question of *why* the game doesn't transition to the next state like it should.
|
||||
After spending more time than anyone could have asked, eventually he burned out and moved on to develop other amazing features for Citra such as multiplayer network support, leaving us without any more clues to why the game freezes.
|
||||
|
||||
{{< figure src="/images/entry/accurate-audio-emulation/kirby.png"
|
||||
{{< figure src="kirby.png"
|
||||
title="Kirby Battle Royale's missing sounds have been found!"
|
||||
>}}
|
||||
|
||||
|
@ -114,7 +114,7 @@ One short level up later, and the game froze, just like in Citra!
|
|||
We double-checked the results by recreating this on different copies of Pokémon X and different 3DSes, and it all went the exact same way.
|
||||
Audio issues were very likely the cause, but what then should be the fix?
|
||||
|
||||
{{< figure src="/images/entry/accurate-audio-emulation/dp.png"
|
||||
{{< figure src="dp.png"
|
||||
title="Detective Pikachu cutscenes no longer skip parts and now run at the proper speed"
|
||||
>}}
|
||||
|
||||
|
@ -174,11 +174,11 @@ When it comes to writing an LLE DSP emulator, it's all or nothing.
|
|||
Either all of your code works, or absolutely nothing happens.
|
||||
Time to work on DMA.
|
||||
|
||||
{{< figure src="/images/entry/accurate-audio-emulation/dspnotes.png"
|
||||
{{< figure src="dspnotes.png"
|
||||
title="A small sample of what it looks like when you are trying to understand all of this DSP stuff"
|
||||
>}}
|
||||
|
||||
<h4 style="text-align: center;"><a href="/resources/entry/accurate-audio-emulation/dspnote.pdf">The full notes are uploaded as a pdf in case someone finds this useful.</a></h4>
|
||||
<h4 style="text-align: center;"><a href="dspnote.pdf">The full notes are uploaded as a pdf in case someone finds this useful.</a></h4>
|
||||
|
||||
## Burnout Strikes
|
||||
|
||||
|
@ -192,7 +192,7 @@ At this point, the stress was too much to handle.
|
|||
The fear of failure after spending so much time and effort on this project really sunk in, and [wwylele](https://github.com/wwylele) just stopped working on Teakra.
|
||||
By the middle of September, [wwylele](https://github.com/wwylele) had just had enough, and decided to work on something else in the meantime.
|
||||
|
||||
{{< figure src="/images/entry/accurate-audio-emulation/conversation.png"
|
||||
{{< figure src="conversation.png"
|
||||
title="It turns out developers are still just regular human beings. Thankfully everything turned out okay!"
|
||||
>}}
|
||||
|
||||
|
@ -206,22 +206,22 @@ Now that data was going to the right spot, it was much easier to debug.
|
|||
|
||||
After some more reverse engineering and hardware testing, wwylele had a good idea of how to recreate DMA completely, and tried it out on a custom application that just produces a simple sine wave.
|
||||
|
||||
{{< audio src="/resources/entry/accurate-audio-emulation/sine_wav_deformed.ogg" >}}
|
||||
{{< audio src="sine_wav_deformed.ogg" >}}
|
||||
|
||||
After some more tinkering, and with renewed enthusiasm, he started finding and fixing minor bugs here and there.
|
||||
All of a sudden, everything just started working.
|
||||
|
||||
{{< audio src="/resources/entry/accurate-audio-emulation/kirby_bad.ogg" >}}
|
||||
{{< audio src="kirby_bad.ogg" >}}
|
||||
|
||||
And with a few more fixes...
|
||||
|
||||
{{< audio src="/resources/entry/accurate-audio-emulation/kirby_good.ogg" >}}
|
||||
{{< audio src="kirby_good.ogg" >}}
|
||||
|
||||
Finally, on Dec 6th, this is what happened after we hooked it into Citra's audio framework (sped up to full speed.)
|
||||
|
||||
{{< audio src="/resources/entry/accurate-audio-emulation/pokemonx.ogg" >}}
|
||||
{{< audio src="pokemonx.ogg" >}}
|
||||
|
||||
{{< figure src="/images/entry/accurate-audio-emulation/mhgen_najarala_armor_4K.png"
|
||||
{{< figure src="mhgen_najarala_armor_4K.png"
|
||||
title="The audio used to be too loud after changing to certain armor in Monster Hunter Generations, but this bug is no more!"
|
||||
>}}
|
||||
|
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
Before Width: | Height: | Size: 584 KiB After Width: | Height: | Size: 584 KiB |
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 682 KiB After Width: | Height: | Size: 682 KiB |
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 186 KiB |
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 168 KiB |
Before Width: | Height: | Size: 854 KiB After Width: | Height: | Size: 854 KiB |
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.0 MiB |
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 966 KiB After Width: | Height: | Size: 966 KiB |
Before Width: | Height: | Size: 645 KiB After Width: | Height: | Size: 645 KiB |
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
@ -23,7 +23,7 @@ During the glory days of Citra development, users would ask almost daily if we h
|
|||
This had become such a frequent occurence that we had to add it to our [Discord server](https://Discord.com/invite/FAXfZV9) FAQ.
|
||||
`Do you plan on making an Android app? No, not at this moment.`
|
||||
|
||||
{{< figure src="/images/entry/announcing-citra-android/discord.png"
|
||||
{{< figure src="discord.png"
|
||||
title="Discord FAQ (Old vs. New)" >}}
|
||||
|
||||
From the users' perspective, it seemed as if the devs disliked the idea of an Android app.
|
||||
|
@ -72,7 +72,7 @@ Android being a diverse OS, each fix had to be extensively tested on a plethora
|
|||
|
||||
|
||||
<div style="width:75%; display:block; margin:auto;" >
|
||||
{{< sidebyside "image" "/images/entry/announcing-citra-android/"
|
||||
{{< sidebyside "image" ""
|
||||
"button_clip.jpg=Before"
|
||||
"button_noclip.jpg=After"
|
||||
>}}
|
||||
|
@ -95,7 +95,7 @@ And since we were trying to improve usability, we revamped the settings menu to
|
|||
[Flamboyant Ham](https://github.com/Schplee) helped ensure that the UI met certain accessibility standards, and designed the new controller overlay — thus helped add support for all the 3DS buttons.
|
||||
|
||||
|
||||
{{< sidebyside "image" "/images/entry/announcing-citra-android/"
|
||||
{{< sidebyside "image" ""
|
||||
"1.jpg"
|
||||
"2.jpg"
|
||||
"3.jpg"
|
||||
|
@ -143,23 +143,23 @@ He also made a few changes to Citra Desktop that translated to performance gains
|
|||
Here are a few screenshots of various games running on the app:
|
||||
|
||||
|
||||
{{< sidebyside "image" "/images/entry/announcing-citra-android/"
|
||||
{{< sidebyside "image" ""
|
||||
"xy.jpg"
|
||||
"smash.jpg"
|
||||
>}}
|
||||
{{< sidebyside "image" "/images/entry/announcing-citra-android/"
|
||||
{{< sidebyside "image" ""
|
||||
"img3.jpg"
|
||||
"oot.jpg"
|
||||
>}}
|
||||
{{< sidebyside "image" "/images/entry/announcing-citra-android/"
|
||||
{{< sidebyside "image" ""
|
||||
"img5.jpg"
|
||||
"ac.jpg"
|
||||
>}}
|
||||
{{< sidebyside "image" "/images/entry/announcing-citra-android/"
|
||||
{{< sidebyside "image" ""
|
||||
"img7.jpg"
|
||||
"img8.jpg"
|
||||
>}}
|
||||
{{< sidebyside "image" "/images/entry/announcing-citra-android/"
|
||||
{{< sidebyside "image" ""
|
||||
"img1.jpg"
|
||||
"img2.jpg"
|
||||
>}}
|
||||
|
@ -193,9 +193,9 @@ These are relatively high requirements; however, they allow us to ensure that ev
|
|||
As for hardware, we recommend a device with a `Snapdragon 835` or better.
|
||||
Your experience may vary greatly depending on the quality of your device's GPU drivers.
|
||||
|
||||
{{< figure src="/images/entry/announcing-citra-android/poke_bugged.jpg"
|
||||
{{< figure src="poke_bugged.jpg"
|
||||
title="Pokémon on an older device" >}}
|
||||
{{< figure src="/images/entry/announcing-citra-android/poke_fixed.png"
|
||||
{{< figure src="poke_fixed.png"
|
||||
title="Pokémon on a newer device" >}}
|
||||
|
||||
## Fin
|
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.6 MiB |
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 796 KiB After Width: | Height: | Size: 796 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 101 KiB |
Before Width: | Height: | Size: 227 KiB After Width: | Height: | Size: 227 KiB |
Before Width: | Height: | Size: 218 KiB After Width: | Height: | Size: 218 KiB |
Before Width: | Height: | Size: 319 KiB After Width: | Height: | Size: 319 KiB |
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
|
@ -12,7 +12,7 @@ _Networked Multiplayer_ is one of those features that was so surprising to see,
|
|||
|
||||
The Nintendo 3DS heavily relies on wireless for its slew of multiplayer compatible titles. Considering that so many games feel empty without their multiplayer features, we're excited to announce that in select titles, you'll be able to play together with your friends across the world in the latest Canary builds of Citra!
|
||||
|
||||
{{< figure src="/images/entry/announcing-networking-support/LetsBattle.png"
|
||||
{{< figure src="LetsBattle.png"
|
||||
title="Let's Battle!" >}}
|
||||
|
||||
#### Bringing Multiplayer to Citra
|
||||
|
@ -23,7 +23,7 @@ This emulates the 3DS' ability to do *local wireless* multiplayer. As such, it
|
|||
|
||||
Unlike single console netplay used in most emulators, users won't have to worry about desyncs, synchronizing saves, or any other issues typical of netplay. Each user is using their instance of Citra as a unique emulated 3DS that is communicating with everyone else through that particular server.
|
||||
|
||||
{{< figure src="/images/entry/announcing-networking-support/GameBrowser.png"
|
||||
{{< figure src="GameBrowser.png"
|
||||
title="Join your friends!" >}}
|
||||
|
||||
Currently, servers created in Citra can hold up to 16 players. High player counts should be avoided for now due to bandwidth issues. In this initial release, each connected Citra instance sends raw packets to the host (or server) and the server then forwards those packets to every single client. As such, with each player added, the bandwidth requirements increase greatly.
|
||||
|
@ -44,7 +44,7 @@ Do note that verified users **will** have their privileges revoked for violating
|
|||
|
||||
_Super Smash Brother's_ local wireless play works perfectly in Citra for up to four players. Because the game expects all players to be running in lockstep, users will need to maintain similar framerates for a stable connection. Some stages, such as the pictochat stage, can run full speed even on moderately powerful computers.
|
||||
|
||||
{{< figure src="/images/entry/announcing-networking-support/SmashLocal.png"
|
||||
{{< figure src="SmashLocal.png"
|
||||
title="1v1 me fox only no items final destination" >}}
|
||||
|
||||
##### Pokémon X/Y, Pokémon Omega Ruby/Alpha Sapphire, and Pokémon Sun/Moon
|
||||
|
@ -53,14 +53,14 @@ Almost everything works perfectly in the _Pokémon_ games. The only thing that
|
|||
|
||||
Because of compatibility issues in general with X and Y, using wireless support may be problematic for those two titles.
|
||||
|
||||
{{< figure src="/images/entry/announcing-networking-support/ChallengePok.png"
|
||||
{{< figure src="ChallengePok.png"
|
||||
title="Challenge your friends in beautifully upscaled Pokémon battles!" >}}
|
||||
|
||||
##### New Super Mario Bros. 2
|
||||
|
||||
_New Super Mario Bros. 2_ runs perfectly, and our testers were able to play together multiple worlds into the game flawlessly. Users on the same server can search for partners and join up just fine.
|
||||
|
||||
{{< figure src="/images/entry/announcing-networking-support/NSMB2.jpg"
|
||||
{{< figure src="NSMB2.jpg"
|
||||
title="Your princess is in another castle? Save her together!" >}}
|
||||
|
||||
#### Functional But Flawed
|
||||
|
@ -69,14 +69,14 @@ _New Super Mario Bros. 2_ runs perfectly, and our testers were able to play toge
|
|||
|
||||
This title has perfectly functional wireless support for trying to tackle the "Scarescraper"! Unfortunately, the game is so demanding that getting a fun experience out of it is near impossible.
|
||||
|
||||
{{< figure src="/images/entry/announcing-networking-support/LuigisMansionLobby.png"
|
||||
{{< figure src="LuigisMansionLobby.png"
|
||||
title="Happy Hallowe- oh, it's November. Whatever, Luigi doesn't care!" >}}
|
||||
|
||||
##### Monster Hunter 3U and 4U
|
||||
|
||||
The _Monster Hunter_ games are extremely demanding in Citra, but wireless support _does_ somewhat work. A second player can join a game, share quests and trade guild cards. But, the game supports up to four local players on console, and anything more than two causes disconnections in Citra.
|
||||
|
||||
{{< figure src="/images/entry/announcing-networking-support/image.png"
|
||||
{{< figure src="image.png"
|
||||
title="Go out and hunt with all your friends! ... as long as that number is only 2." >}}
|
||||
|
||||
#### Incompatible
|
|
@ -18,7 +18,7 @@ Citra Android has now reached 500,000+ installs on the Google Play Store!
|
|||
This is an absolutely incredible achievement and your enthusiasm is a big factor in what drives development of the app.
|
||||
Thank you all for your support!
|
||||
|
||||
{{< figure src="/images/entry/citra-android-update/installs.png"
|
||||
{{< figure src="installs.png"
|
||||
title="Incredible!" >}}
|
||||
|
||||
# Save States Announcement
|
||||
|
@ -32,7 +32,7 @@ Check it out in the [Google Play Store now](https://play.google.com/store/apps/d
|
|||
|
||||
<p style="color:red";><b>Reminder: Do <i>not</i> rely on Save States entirely. Remember to create normal saves occasionally to prevent loss of progress in the event the save state becomes corrupt or incompatible with a future version of Citra.</b></p>
|
||||
|
||||
{{< figure src="/images/entry/citra-android-update/save_states.jpg"
|
||||
{{< figure src="save_states.jpg"
|
||||
title="Save states, on mobile!?" >}}
|
||||
|
||||
# Additional Questions
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 886 B After Width: | Height: | Size: 886 B |
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
|
@ -42,7 +42,7 @@ In late 2014, Citra was a very small project developed primarily by [bunnei](htt
|
|||
Until one day...
|
||||
<br></br>
|
||||
|
||||
{{< img src="entry/citra-progress-report-2015-p1/image01.png" center="true" >}}
|
||||
{{< img src="image01.png" center="true" >}}
|
||||
|
||||
<br></br>
|
||||
Recognize the game? That's The Legend of Zelda: Ocarina of Time 3D rendering on Citra on
|
||||
|
@ -64,7 +64,7 @@ Propelled by this breakthrough, [neobrain](http://github.com/neobrain) and [bunn
|
|||
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" >}}
|
||||
{{< img src="image03.png" center="true" >}}
|
||||
<br></br>
|
||||
|
||||
This breakthrough only motivated developers further. With a 3D rendered scene under its belt, users had taken notice
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 139 KiB |
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 176 KiB |
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 121 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 222 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 183 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
@ -50,25 +50,25 @@ With the summer, development slowed down a bit – but several additional improv
|
|||
booting, such as Super Mario 3D Land, Fire Emblem: Awakening, The Legend of Zelda: A Link Between Worlds, Mario Kart 7,
|
||||
and many more.
|
||||
|
||||
{{< img src="entry/citra-progress-report-2015-p2/earlyunknown1.png" center="true" >}}
|
||||
{{< img src="earlyunknown1.png" center="true" >}}
|
||||
|
||||
{{< img src="entry/citra-progress-report-2015-p2/earlyunknown2.png" center="true" >}}
|
||||
{{< img src="earlyunknown2.png" center="true" >}}
|
||||
|
||||
{{< img src="entry/citra-progress-report-2015-p2/earlycrush3d.png" center="true" >}}
|
||||
{{< img src="earlycrush3d.png" center="true" >}}
|
||||
|
||||
{{< img src="entry/citra-progress-report-2015-p2/earlymario3dland.png" center="true" >}}
|
||||
{{< img src="earlymario3dland.png" center="true" >}}
|
||||
|
||||
{{< img src="entry/citra-progress-report-2015-p2/earlysteeldiver.png" center="true" >}}
|
||||
{{< img src="earlysteeldiver.png" center="true" >}}
|
||||
|
||||
{{< img src="entry/citra-progress-report-2015-p2/earlyluigi.png" center="true" >}}
|
||||
{{< img src="earlyluigi.png" center="true" >}}
|
||||
|
||||
{{< img src="entry/citra-progress-report-2015-p2/earlylinkbetweenworlds.png" center="true" >}}
|
||||
{{< img src="earlylinkbetweenworlds.png" center="true" >}}
|
||||
|
||||
{{< img src="entry/citra-progress-report-2015-p2/earlymajorasmask.png" center="true" >}}
|
||||
{{< img src="earlymajorasmask.png" center="true" >}}
|
||||
|
||||
{{< img src="entry/citra-progress-report-2015-p2/earlymk7.png" center="true" >}}
|
||||
{{< img src="earlymk7.png" center="true" >}}
|
||||
|
||||
{{< img src="entry/citra-progress-report-2015-p2/earlyfireemblem.png" center="true" >}}
|
||||
{{< img src="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
|
||||
|
@ -78,7 +78,7 @@ But there was still one major issue that was blocking many games: video playback
|
|||
[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>
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2015-p2/3.png"
|
||||
{{< figure src="3.png"
|
||||
alt="Bravely Default"
|
||||
title="Bravely Default's intro sequence relies on MOFLEX video support" >}}
|
||||
|
||||
|
@ -108,17 +108,17 @@ After a brief summer hiatus, development on Citra began to pick up again with au
|
|||
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.
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2015-p2/rotatecube.gif"
|
||||
{{< figure src="rotatecube.gif"
|
||||
alt="Fragment shader test"
|
||||
title="An early fragment lighting demo running in Citra" >}}
|
||||
|
||||
Despite that it’s not a fully complete implementation of fragment lighting, the results have significantly improved
|
||||
Citra’s visuals!
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2015-p2/moonbefore.png"
|
||||
{{< figure src="moonbefore.png"
|
||||
title="It's a super moon!" >}}
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2015-p2/moonafter.png"
|
||||
{{< figure src="moonafter.png"
|
||||
title="With fragment lighting implemented, the moon became even scarier! H-hurray?" >}}
|
||||
|
||||
While no more major features were merged into Citra by the turn of the year, [Subv](https://github.com/Subv) came up
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 140 KiB |
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 550 KiB After Width: | Height: | Size: 550 KiB |
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 146 KiB |
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 200 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 223 KiB |
|
@ -27,7 +27,7 @@ Immediate Mode Vertex Submission is a second way for the PICA200 (aka the 3DS GP
|
|||
for *vertex restart*. Vertex Restart is a feature necessary when drawing using triangle strips, in order to break apart
|
||||
consecutive strips.
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2016-p1/etrianodysseytop.png"
|
||||
{{< figure src="etrianodysseytop.png"
|
||||
alt="Etrian Odyssey IV"
|
||||
title="Etrian Odyssey IV running in Citra with Immediate Mode Vertex Submission" >}}
|
||||
|
||||
|
@ -62,9 +62,9 @@ Handling these instructions correctly, much like a CPU emulator, is paramount fo
|
|||
gibberish textures and incorrect positioning, as can be seen in this The Legend of Zelda: A Link Between Worlds
|
||||
screenshot:
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2016-p1/albwbefore.png" >}}
|
||||
{{< figure src="albwbefore.png" >}}
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2016-p1/albwafter.jpg"
|
||||
{{< figure src="albwafter.jpg"
|
||||
title="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
|
||||
|
@ -79,10 +79,10 @@ Vertex Attributes are an integral step in rendering. They can tell the GPU the b
|
|||
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.
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2016-p1/smashbrosbefore.jpg"
|
||||
{{< figure src="smashbrosbefore.jpg"
|
||||
title="Pikachu has seen better days." >}}
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2016-p1/smashbrosafter.png"
|
||||
{{< figure src="smashbrosafter.png"
|
||||
title="While lighting is a bit off, the game looks fairly playable!" >}}
|
||||
|
||||
With this fix, the Super Smash Bros. 4 actually looks fairly playable! The align attributes fixes should also fix other
|
||||
|
@ -101,7 +101,7 @@ The save fixes recently merged mostly have to do with formatting the cartridge s
|
|||
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!
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2016-p1/mk7.jpg"
|
||||
{{< figure src="mk7.jpg"
|
||||
title="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
|
||||
|
@ -120,9 +120,9 @@ Citra's GPU shader JIT had a bit of a flaw: It would keep previously compiled sh
|
|||
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:
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2016-p1/b.png" >}}
|
||||
{{< figure src="b.png" >}}
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2016-p1/c.png"
|
||||
{{< figure src="c.png"
|
||||
title="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)
|
||||
|
@ -142,9 +142,9 @@ To fix this, [bunnei](https://github.com/bunnei) refactored the shader JIT to do
|
|||
|
||||
This change fixes IronFall: Invasion, Pokemon: Rumble Blast, and several other games:
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2016-p1/1.png" >}}
|
||||
{{< figure src="1.png" >}}
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2016-p1/2.png"
|
||||
{{< figure src="2.png"
|
||||
title="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)
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 238 KiB |
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 144 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
|
@ -29,14 +29,12 @@ adding almost all of the features the hardware renderer had received over the ye
|
|||
In fact, every addition to the hardware renderer has been given an equivalent
|
||||
in software:
|
||||
|
||||
{{% table %}}
|
||||
| Feature | Hardware | Software |
|
||||
| ----------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| Fragment Lighting | [#1264](https://github.com/citra-emu/citra/pull/1264) | [#2766](https://github.com/citra-emu/citra/pull/2766), [#2822](https://github.com/citra-emu/citra/pull/2822) |
|
||||
| Spot Lighting | [#2727](https://github.com/citra-emu/citra/pull/2727) | [#2871](https://github.com/citra-emu/citra/pull/2871) |
|
||||
| Geometric Factor | [#2776](https://github.com/citra-emu/citra/pull/2776) | [#2872](https://github.com/citra-emu/citra/pull/2872) |
|
||||
| Bump Mapping | [#2762](https://github.com/citra-emu/citra/pull/2762) | [#2891](https://github.com/citra-emu/citra/pull/2891) |
|
||||
{{% /table %}}
|
||||
|
||||
Despite the software backend being incredibly slow, it is important to have a
|
||||
complete software implementation of the 3DS' GPU so that Citra can be used as a
|
||||
|
@ -110,7 +108,7 @@ on hardware in Pokémon Super Mystery Dungeon below. But when it came to running
|
|||
something that took advantage of this feature in Citra, it didn't always work the
|
||||
same as it would on console.
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2017-august/texturecopy-before.png"
|
||||
{{< figure src="texturecopy-before.png"
|
||||
title="How jagged" alt="Pokémon Super Mystery Dungeon During Deoxy's and Rayquaza's Face Off I N S P A C E" >}}
|
||||
|
||||
Fortunately (and to much rejoicing!) wwylele stepped into the ring to wrestle with
|
||||
|
@ -119,7 +117,7 @@ to help gain an understanding of how the hardware handles the TextureCopy operat
|
|||
in comparison to Citra. After the hard work of doing the research was out of the
|
||||
way, wwylele implemented it in Citra.
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2017-august/texturecopy-after.png"
|
||||
{{< figure src="texturecopy-after.png"
|
||||
title="Deoxys is having a bit of a hard time, no?" alt="Pokémon Super Mystery Dungeon During Deoxy's and Rayquaza's Face Off I N S P A C E" >}}
|
||||
|
||||
## [Use Docker For Linux Builds](https://github.com/citra-emu/citra/pull/2869) by [j-selby](https://github.com/j-selby)
|
||||
|
@ -147,7 +145,7 @@ instead, which is much more well supported (and yes, it can compile Citra out of
|
|||
frontend to make it themeable. Now users can enjoy a dark mode and other custom
|
||||
colour schemes, just by editing a CSS stylesheet!
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2017-august/theme-comparison.png"
|
||||
{{< figure src="theme-comparison.png"
|
||||
title="CHOOSE YOUR CHARACTER" alt="Comparison of Dark Theme and Light Theme" >}}
|
||||
|
||||
## [Load Shared Font From System Archive](https://github.com/citra-emu/citra/pull/2784) by [wwylele](https://github.com/wwylele)
|
Before Width: | Height: | Size: 4.0 MiB After Width: | Height: | Size: 4.0 MiB |
Before Width: | Height: | Size: 3.5 MiB After Width: | Height: | Size: 3.5 MiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
|
@ -13,7 +13,7 @@ The summer of 2017 has just rolled in, and although we don't have a [summer of c
|
|||
|
||||
There is a rarely used feature in the 3DS' GPU called procedural textures, "proctex" for short. It allows games to generate new textures on the fly by just plugging in a few parameters. Mario & Luigi: Paper Jam, and Kirby: Planet Robobot both use it to generate realistic sea surfaces. The formula behind proctex had to be reverse-engineered in order to be implemented, which fortunately [fincs](https://github.com/fincs) did [and documented](https://gist.github.com/fincs/543f7e1375815f495f10020a053f14e9). Using this documentation, [wwylele](https://github.com/wwylele) simply translated it into code, and dropped it into Citra, fixing both those games.
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2017-june/paper-jam-foam.png" title="Look at that beautiful sea foam. ❤"
|
||||
{{< figure src="paper-jam-foam.png" title="Look at that beautiful sea foam. ❤"
|
||||
alt="Mario & Luigi: Paper Jam's intro cutscene, showing Peach's castle, and the sea behind it" >}}
|
||||
|
||||
<!--
|
||||
|
@ -43,7 +43,7 @@ In Citra, to be more efficient, we give the LUT (look-up table) to OpenGL and te
|
|||
|
||||
As a workaround, some offsets were set on the table in OpenGL so that it would pick the correct entries. But, the LUT on the 3DS also has a mode called "two's complement" in which each half of the table is "wrapped" virtually across past the beginning and end of the table, but not across the middle of the table. This completely messes up the table in OpenGL, leading to completely different results near the middle of the table, causing things like dark spots in highlighted areas.
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2017-june/lut-fix-before.png" title="Kyogre seems to have a bit of a skin blemish."
|
||||
{{< figure src="lut-fix-before.png" title="Kyogre seems to have a bit of a skin blemish."
|
||||
alt="Kyogre in Pokémon Alpha Sapphire before the fix." >}}
|
||||
|
||||
<!--
|
||||
|
@ -53,7 +53,7 @@ commit_hash = 2f746e9946f78a2e283dfdcbeda9cf332e44d099 cherry-pick 6ca816e011c03
|
|||
|
||||
Although the OpenGL hack provided a slight increase in efficiency, in the end [wwylele](https://github.com/wwylele) replaced it all with simply mimicking what the 3DS does, fixing the entire issue, and making lighting calculations significantly more accurate. Sometimes the simplest solution is the best solution.
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2017-june/lut-fix-after.png" title="Much better, guess the lighting got an acne treatment."
|
||||
{{< figure src="lut-fix-after.png" title="Much better, guess the lighting got an acne treatment."
|
||||
alt="Kyogre in Pokémon Alpha Sapphire after the fix." >}}
|
||||
|
||||
<!--
|
||||
|
@ -82,7 +82,7 @@ As a side-effect, [yuriks](https://github.com/yuriks) also had to implement the
|
|||
These new features are all just features that were not known or not researched enough when the original lighting implementation was written. A few small fixes lead to big changes, such as the fact that Super Smash Bros. for 3DS now has proper lighting, instead of colours looking washed out and very bright.
|
||||
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2017-june/frag-light-before.png"
|
||||
{{< figure src="frag-light-before.png"
|
||||
alt="Super Smash Bros. for 3DS before the new lighting features" >}}
|
||||
|
||||
<!--
|
||||
|
@ -90,7 +90,7 @@ title_id = 00040000000edf00
|
|||
commit_hash = bae3799bd5208d08bb52546ad0723103c94cada3
|
||||
-->
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2017-june/frag-light-after.png"
|
||||
{{< figure src="frag-light-after.png"
|
||||
alt="Super Smash Bros. for 3DS after the new lighting features"
|
||||
title="Finally someone turned down the lights." >}}
|
||||
|
Before Width: | Height: | Size: 661 KiB After Width: | Height: | Size: 661 KiB |
Before Width: | Height: | Size: 620 KiB After Width: | Height: | Size: 620 KiB |
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 363 KiB After Width: | Height: | Size: 363 KiB |
|
@ -20,7 +20,7 @@ Citra's video code has grown organically from the start; not much was known abou
|
|||
|
||||
The entire architecture of the 3DS was largely unknown, so development was done in small seperate bits at a time, and then trying to piece it all together into one cohesive piece of software. But, over time, as new pieces of information were found, the assumptions that were made previously broke. Some assumptions were very large, obvious, and easy to overcome, but a more subtle error that these assumptions created were not even in the design of the GPU, but rather the architecture and organization of the code itself.
|
||||
|
||||
{{< figure src="/images/entry/citra-progress-report-2017-p1/acnl-bridge.png" title="Shouldn't there be a bridge here?" alt="Animal Crossing bridge" >}}
|
||||
{{< figure src="acnl-bridge.png" title="Shouldn't there be a bridge here?" alt="Animal Crossing bridge" >}}
|
||||
|
||||
The video code was very interconnected using this interface, so despite people being aware of this, it was also extremely difficult to move code around and reorganize it, as it could very easily affect unrelated bits of code that depended on it. This was only compounded by the hardware renderer, as it was written much like earlier, slowly adding hardware support bit-by-bit to separate parts of the video code, simply falling back into the software renderer when disabled or not supported.
|
||||
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.3 MiB |