mirror of
https://github.com/orangeglo/gbnp.git
synced 2026-09-14 03:25:16 -05:00
Load games from rom, save all settings, fix pokemon font, remove Pixeltype
This commit is contained in:
@@ -6,11 +6,10 @@ This tool can build the data necessary to flash new games to a [Nintendo Power G
|
||||
- GB Memory Maker: https://github.com/Infinest/GB-Memory-Binary-Maker
|
||||
- Without this source, this project would have been much more difficult!
|
||||
- NesDev Forum Thread: http://forums.nesdev.com/viewtopic.php?f=12&t=11453
|
||||
- Pixeltype Font: https://www.dafont.com/pixeltype.font
|
||||
- Early GameBoy Font: https://www.dafont.com/early-gameboy.font
|
||||
- Pokemon GB Font: https://www.fontspace.com/pokemon-gb-font-f9621
|
||||
- Nokia Cellphone FC Font: https://www.dafont.com/nokia-cellphone.font
|
||||
- Gamer Font: https://www.dafont.com/gamer-2.font
|
||||
- Pokemon Classic Font: https://www.dafont.com/pokemon-classic.font
|
||||
|
||||
## Ideas
|
||||
- Load roms from menu file
|
||||
|
||||
Binary file not shown.
Binary file not shown.
15
index.html
15
index.html
@@ -31,10 +31,10 @@
|
||||
<p>Menu is not valid. Please upload GB Memory Multi Menu (NP M-MENU) ROM.</p>
|
||||
</div>
|
||||
<div v-if="menu.loadedFromStorage && menu.valid()">
|
||||
<p>Menu loaded from storage! You're all set.</p>
|
||||
<p>Menu loaded from browser storage. Any existing games were added. You're all set!</p>
|
||||
</div>
|
||||
<div v-if="!menu.loadedFromStorage && menu.ready()">
|
||||
<p>Menu loaded and cached! You're all set.</p>
|
||||
<p>Menu loaded and cached. Any existing games were added. You're all set!</p>
|
||||
</div>
|
||||
<button v-on:click="triggerAddMenuLabel" class="upload" type="button">
|
||||
<label for="menuFileInput" ref="addMenuLabel" v-on:click="stopPropagation">Upload Menu</label>
|
||||
@@ -51,7 +51,11 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>
|
||||
<button v-on:click="removeAllRoms" class="remove-all" :disabled="roms.length == 0" type="button" >
|
||||
<label>Remove All</label>
|
||||
</button>
|
||||
</th>
|
||||
<th>Title</th>
|
||||
<th>Mapper</th>
|
||||
<th>ROM</th>
|
||||
@@ -114,16 +118,13 @@
|
||||
<label for="font0" id="gameboy" class="radio-label">Game Boy</label>
|
||||
|
||||
<input type="radio" id="font1" name="font" value="1" v-model="fontIndex">
|
||||
<label for="font1" id="pixeltype" class="radio-label">Pixeltype</label>
|
||||
<label for="font1" id="pokemon" class="radio-label">POKEMON</label>
|
||||
|
||||
<input type="radio" id="font2" name="font" value="2" v-model="fontIndex">
|
||||
<label for="font2" id="nokia" class="radio-label">Nokia</label>
|
||||
|
||||
<input type="radio" id="font3" name="font" value="3" v-model="fontIndex">
|
||||
<label for="font3" id="gamer" class="radio-label">Gamer</label>
|
||||
|
||||
<input type="radio" id="font4" name="font" value="4" v-model="fontIndex">
|
||||
<label for="font4" id="pokemon" class="radio-label">Pokemon</label>
|
||||
</div>
|
||||
|
||||
<div class="settings-row">
|
||||
|
||||
@@ -16,27 +16,42 @@ let app = new Vue({
|
||||
this.processor.disableCGB = this.disableCGB;
|
||||
this.processor.forceDMG = this.forceDMG;
|
||||
},
|
||||
mounted: function() {
|
||||
this.loadSettings();
|
||||
document.fonts.load(FONTS[this.fontIndex].style).then(() => {
|
||||
this.roms = this.processor.parseMenuData(this.fontIndex);
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
downloadEnabled: function() {
|
||||
return (this.roms.length > 0) && this.menu.present() && this.menu.valid() && !this.romOverflow;
|
||||
return this.menu.present() && this.menu.valid() && !this.romOverflow;
|
||||
},
|
||||
romOverflow: function() { return this.processor.romOverflow(); }
|
||||
},
|
||||
watch: {
|
||||
fontIndex: function() {
|
||||
for (let i = 0; i < this.roms.length; i++) { this.roms[i].updateBitmap(this.fontIndex); }
|
||||
localStorage.setItem('fontIndex', this.fontIndex);
|
||||
},
|
||||
filename: function() {
|
||||
localStorage.setItem('filename', this.filename);
|
||||
},
|
||||
disableCGB: function() {
|
||||
this.processor.disableCGB = this.disableCGB;
|
||||
localStorage.setItem('disableCGB', this.disableCGB);
|
||||
},
|
||||
forceDMG: function() {
|
||||
this.processor.forceDMG = this.forceDMG;
|
||||
localStorage.setItem('forceDMG', this.forceDMG);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addMenu: function(e) {
|
||||
let fileReader = new FileReader()
|
||||
fileReader.onload = () => this.menu.setData(fileReader.result);
|
||||
fileReader.onload = () => {
|
||||
this.menu.setData(fileReader.result);
|
||||
this.roms = this.processor.parseMenuData();
|
||||
}
|
||||
fileReader.readAsArrayBuffer(e.target.files[0]);
|
||||
|
||||
e.target.value = '';
|
||||
@@ -59,6 +74,10 @@ let app = new Vue({
|
||||
this.roms.splice(index, 1);
|
||||
this.processor.roms = this.roms;
|
||||
},
|
||||
removeAllRoms: function() {
|
||||
this.roms = [];
|
||||
this.processor.roms = this.roms;
|
||||
},
|
||||
moveUp: function(index) {
|
||||
let rom = this.roms[index];
|
||||
this.roms.splice(index, 1);
|
||||
@@ -85,6 +104,12 @@ let app = new Vue({
|
||||
rom.updateMenuText(val, this.fontIndex);
|
||||
}, 500);
|
||||
},
|
||||
loadSettings: function() {
|
||||
this.filename = localStorage.getItem('filename');
|
||||
this.fontIndex = Number(localStorage.getItem('fontIndex'));
|
||||
this.disableCGB = localStorage.getItem('disableCGB') === 'true'
|
||||
this.forceDMG = localStorage.getItem('forceDMG') === 'true'
|
||||
},
|
||||
stopPropagation: function(e) { e.stopImmediatePropagation(); },
|
||||
triggerAddMenuLabel: function(e) { this.$refs.addMenuLabel.click(); },
|
||||
triggerAddRomLabel: function(e) { this.$refs.addRomLabel.click(); }
|
||||
|
||||
@@ -15,10 +15,9 @@ const BITMAP_PREVIEW_BYTES = [
|
||||
]
|
||||
const FONTS = [
|
||||
{ style: 'normal 8px Gameboy', y: 7 },
|
||||
{ style: 'normal 16px Pixeltype', y: 7 },
|
||||
{ style: 'normal 8px PokemonGB', y: 7 },
|
||||
{ style: 'normal 8px Nokia', y: 7 },
|
||||
{ style: 'normal 16px Gamer', y: 7 },
|
||||
{ style: 'normal 8px Pokemon', y: 7 },
|
||||
{ style: 'normal 16px Gamer', y: 7 }
|
||||
]
|
||||
|
||||
class Menu {
|
||||
@@ -83,8 +82,8 @@ class ROM {
|
||||
this.updateBitmap(fontIndex);
|
||||
|
||||
if (!this.valid()) { alert('File is not a valid Game Boy ROM!') }
|
||||
if (!this.type) { alert('Cartridge type could not be determined!') }
|
||||
if (this.ramSizeKB() > 32) { alert('Game requires more than 32 KB of RAM!') }
|
||||
else if (!this.type) { alert('Cartridge type could not be determined!') }
|
||||
else if (this.ramSizeKB() > 32) { alert('Game requires more than 32 KB of RAM!') }
|
||||
}
|
||||
|
||||
valid() {
|
||||
@@ -362,6 +361,32 @@ class Processor {
|
||||
|
||||
return new Uint8Array(romBuffer);
|
||||
}
|
||||
|
||||
parseMenuData(fontIndex) {
|
||||
this.roms = [];
|
||||
const menuBuffer = (new Uint8Array(this.menu.data)).buffer;
|
||||
const menuFile = new FileSeeker(menuBuffer);
|
||||
|
||||
let romSizes = [];
|
||||
for (let i = 0; i < 7; i++) {
|
||||
const indexPosition = 0x1C200 + i * 512
|
||||
menuFile.seek(indexPosition);
|
||||
const byte = menuFile.readByte();
|
||||
if (byte > 0 && byte < 8) {
|
||||
menuFile.seek(indexPosition + 3)
|
||||
romSizes.push(menuFile.readByte());
|
||||
}
|
||||
}
|
||||
|
||||
menuFile.seek(0x20000)
|
||||
for (let i = 0; i < romSizes.length; i++) {
|
||||
const romData = menuFile.read(romSizes[i] * 128 * 1024);
|
||||
const romBuffer = (new Uint8Array(romData)).buffer;
|
||||
this.roms.push(new ROM(romBuffer, fontIndex))
|
||||
}
|
||||
|
||||
return this.roms;
|
||||
}
|
||||
}
|
||||
|
||||
class FileSeeker {
|
||||
|
||||
18
style.css
18
style.css
@@ -27,7 +27,7 @@
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Pokemon";
|
||||
font-family: "PokemonGB";
|
||||
src: url("./font/Pokemon.woff") format("woff");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
@@ -86,6 +86,10 @@ button#remove-rom {
|
||||
color: red;
|
||||
}
|
||||
|
||||
button.remove-all{
|
||||
color: red;
|
||||
}
|
||||
|
||||
button[disabled='disabled'] {
|
||||
color: grey;
|
||||
}
|
||||
@@ -165,14 +169,6 @@ label.radio-label {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
label#pixeltype {
|
||||
font-family: 'Pixeltype';
|
||||
font-size: 32px;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
label#gameboy {
|
||||
font-family: 'Gameboy';
|
||||
}
|
||||
@@ -190,9 +186,9 @@ label#gamer {
|
||||
}
|
||||
|
||||
label#pokemon {
|
||||
font-family: 'Pokemon';
|
||||
font-family: 'PokemonGB';
|
||||
position: relative;
|
||||
top: -2px;
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
noscript {
|
||||
|
||||
Reference in New Issue
Block a user