Improving compiler.

This commit is contained in:
2022-01-04 21:36:37 -08:00
parent c9ebb85d13
commit dfd205ce22
28 changed files with 500 additions and 183 deletions

6
.gitignore vendored
View File

@@ -78,5 +78,7 @@ yarn.lock
obj
res
./out.c
./out.c.png
out.c
out.c.png
emulator

Binary file not shown.

BIN
images/border.aseprite Normal file

Binary file not shown.

BIN
images/border.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 564 B

After

Width:  |  Height:  |  Size: 737 B

BIN
images/sm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
images/tileset.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

5
run.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
make clean
make
wine ./emulator/bgb.exe "obj\\Example.gb"

7
scripts/common.js Normal file
View File

@@ -0,0 +1,7 @@
const TILE_WIDTH = 8;
const TILE_HEIGHT = 8;
module.exports = {
TILE_WIDTH,
TILE_HEIGHT
}

88
scripts/gb2png.js Normal file
View File

@@ -0,0 +1,88 @@
const PNG = require('pngjs').PNG;
const fs = require('fs');
const {
TILE_WIDTH,
TILE_HEIGHT
} = require('./common');
const colorPixel = (id) => {
if(id === undefined) id = 3;
if(id === 3) return { r: 8, g: 24, b: 32 };
if(id === 2) return { r: 52, g: 104, b: 86 };
if(id === 1) return { r: 136, g: 192, b: 112 };
if(id === 0) return { r: 224, g: 248, b: 208 };
throw new Error();
}
const gb2png = (DATA, fileOut) => {
// Begin
const PIXELS = DATA.length / 2 * TILE_WIDTH;
const DATA_WIDTH = TILE_WIDTH;
const DATA_HEIGHT = PIXELS / DATA_WIDTH;
// Create output image
const imageData = new PNG({
width: DATA_WIDTH,
height: DATA_HEIGHT
});
// Convert data into pixels
const pixelsOut = [];
for(let i = 0; i < DATA.length; i += 2) {
const low = DATA[i];
const high = DATA[i+1];
for(let j = 0; j < 8; j++) {
const mask = 0x80 >> j;
const pixel = (low & mask ? 1 : 0) + (high & mask ? 2 : 0);
pixelsOut.push(pixel);
}
}
// Buffer data output
for(let y = 0; y < DATA_HEIGHT; y++) {
for(let x = 0; x < DATA_WIDTH; x++) {
const id = (DATA_WIDTH * y + x);
const color = colorPixel(pixelsOut[id]);
const idx = id << 2;
imageData.data[idx] = color.r;
imageData.data[idx+1] = color.g;
imageData.data[idx+2] = color.b;
imageData.data[idx+3] = 0xFF;
}
}
const buffer = PNG.sync.write(imageData, { });
fs.writeFileSync(fileOut, buffer);
}
// // Now work out tile data
// if(TILEMAP.length) {
// for(let i = 0; i < TILEMAP.length; i++) {
// const tileX = i % TILEMAP_WIDTH;
// const tileY = Math.floor(i / TILEMAP_WIDTH);
// const tile = TILEMAP[i];
// for(let j = 0; j < TILE_WIDTH*TILE_HEIGHT; j++) {
// const outI = (
// (tileX * TILE_WIDTH) + (tileY * TILE_HEIGHT * TILEMAP_PIXEL_WIDTH) +
// ((j % TILE_WIDTH) + (Math.floor(j / TILE_WIDTH) * TILEMAP_PIXEL_WIDTH))
// );
// const idx = outI << 2;
// const pixelI = (tile * TILE_WIDTH * TILE_HEIGHT) + j;
// const color = colorPixel(pixelsOut[pixelI]);
// tileData.data[idx] = color.r;
// tileData.data[idx+1] = color.g;
// tileData.data[idx+2] = color.b;
// tileData.data[idx+3] = 0xFF;
// }
// }
// const buffer2 = PNG.sync.write(tileData, { });
// fs.writeFileSync('out.png', buffer2);
// }
module.exports = {
gb2png
};

View File

@@ -1,104 +0,0 @@
// let DATA = [
// 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
// 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
// 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
// ];
const TILEMAP = [
];
const TILEMAP_WIDTH = 8;
const convertData = (DATA, fileOut) => {
// Begin
const PNG = require('pngjs').PNG;
const fs = require('fs');
const PIXELS = DATA.length / 2 * 8;
const TILE_WIDTH = 8;
const TILE_HEIGHT = 8;
const DATA_WIDTH = TILE_WIDTH;
const DATA_HEIGHT = PIXELS / DATA_WIDTH;
const TILEMAP_HEIGHT = TILEMAP.length / TILEMAP_WIDTH;
const TILEMAP_PIXEL_WIDTH = TILEMAP_WIDTH * TILE_WIDTH;
const TILEMAP_PIXEL_HEIGHT = TILEMAP_HEIGHT * TILE_HEIGHT;
const colorPixel = (id) => {
if(id === undefined) id = 3;
if(id === 3) return { r: 8, g: 24, b: 32 };
if(id === 2) return { r: 52, g: 104, b: 86 };
if(id === 1) return { r: 136, g: 192, b: 112 };
if(id === 0) return { r: 224, g: 248, b: 208 };
throw new Error();
}
// Create output image
const imageData = new PNG({
width: DATA_WIDTH,
height: DATA_HEIGHT
});
const tileData = new PNG({
width: TILEMAP_PIXEL_WIDTH,
height: TILEMAP_PIXEL_HEIGHT
});
// Convert data into pixels
const pixelsOut = [];
for(let i = 0; i < DATA.length; i += 2) {
const low = DATA[i];
const high = DATA[i+1];
for(let j = 0; j < 8; j++) {
const mask = 0x80 >> j;
const pixel = (low & mask ? 1 : 0) + (high & mask ? 2 : 0);
pixelsOut.push(pixel);
}
}
// Buffer data output
for(let y = 0; y < DATA_HEIGHT; y++) {
for(let x = 0; x < DATA_WIDTH; x++) {
const id = (DATA_WIDTH * y + x);
const color = colorPixel(pixelsOut[id]);
const idx = id << 2;
imageData.data[idx] = color.r;
imageData.data[idx+1] = color.g;
imageData.data[idx+2] = color.b;
imageData.data[idx+3] = 0xFF;
}
}
const buffer = PNG.sync.write(imageData, { });
fs.writeFileSync(fileOut, buffer);
}
// Now work out tile data
if(TILEMAP.length) {
for(let i = 0; i < TILEMAP.length; i++) {
const tileX = i % TILEMAP_WIDTH;
const tileY = Math.floor(i / TILEMAP_WIDTH);
const tile = TILEMAP[i];
for(let j = 0; j < TILE_WIDTH*TILE_HEIGHT; j++) {
const outI = (
(tileX * TILE_WIDTH) + (tileY * TILE_HEIGHT * TILEMAP_PIXEL_WIDTH) +
((j % TILE_WIDTH) + (Math.floor(j / TILE_WIDTH) * TILEMAP_PIXEL_WIDTH))
);
const idx = outI << 2;
const pixelI = (tile * TILE_WIDTH * TILE_HEIGHT) + j;
const color = colorPixel(pixelsOut[pixelI]);
tileData.data[idx] = color.r;
tileData.data[idx+1] = color.g;
tileData.data[idx+2] = color.b;
tileData.data[idx+3] = 0xFF;
}
}
const buffer2 = PNG.sync.write(tileData, { });
fs.writeFileSync('out.png', buffer2);
}
module.exports = convertData;

View File

@@ -1,25 +1,29 @@
const PNG = require('pngjs').PNG;
const fs = require('fs');
const { arrayToString } = require('./util');
const {
TILE_WIDTH,
TILE_HEIGHT
} = require('./common');
const convert = (fileIn, fileOut) => {
const TILE_WIDTH = 8;
const TILE_HEIGHT = 8;
const getPixelValue = (pixel) => {
if(pixel.g === 188) return 0;
if(pixel.g === 172) return 1;
if(pixel.g === 98) return 2;
if(pixel.g === 56) return 3;
throw new Error();
}
const png2gb = (fileIn, fileOut, name) => {
const data = fs.readFileSync(fileIn);
const png = PNG.sync.read(data);
const getPixelValue = (pixel) => {
if(pixel.r === 15) return 3;
if(pixel.r === 48) return 2;
if(pixel.r === 0) return 1;
if(pixel.r === 155) return 0;
throw new Error();
}
// Convert PNG pixels into 0x00-0x03
const pixels = [];
for(let x = 0; x < png.width; x++) {
for(let y = 0; y < png.height; y++) {
for(let y = 0; y < png.height; y++) {
for(let x = 0; x < png.width; x++) {
const id = x + (y * png.width);
const idx = id << 2;
const r = png.data[idx];
@@ -39,11 +43,11 @@ const convert = (fileIn, fileOut) => {
const tileX = i % columns;
const tileY = Math.floor(i / columns) % rows;
for(let x = 0; x < TILE_WIDTH; x++) {
for(let y = 0; y < TILE_HEIGHT; y++) {
const px = (tileY * TILE_WIDTH) + x;// NO idea why I need to flipX/Y.
const py = (tileX * TILE_HEIGHT) + y;// and too lazy to figure out why.
const pi = px + (py * png.width);
for(let y = 0; y < TILE_HEIGHT; y++) {
for(let x = 0; x < TILE_WIDTH; x++) {
const px = (tileX * TILE_WIDTH) + x;
const py = (tileY * TILE_HEIGHT) + y;
const pi = (py * png.width) + px;
rearranged[n++] = pixels[pi];
}
}
@@ -62,28 +66,20 @@ const convert = (fileIn, fileOut) => {
bits.push(lowBits, highBits);
}
const b = bits.map(n => {
return '0x' + (n.toString(16).padStart(2, '0').toUpperCase());
});
let str = '';
for(let i = 0; i < b.length; i += 16) {
str += ' ';
for(let x = i; x < Math.min(i+16, b.length); x++) {
str += b[x];
str += ',';
}
str += '\n';
}
let out = '';
out += `#include "../libs.h"\n\n`
out += `#define IMAGE_WIDTH ${png.width}\n`;
out += `#define IMAGE_HEIGHT ${png.height}\n`;
out += `#define IMAGE_TILES ${columns * rows}\n`;
out += `\nconst uint8_t IMAGE[] = {\n${str}};`;
out += `#include "libs.h"\n\n`
out += `#define ${name}_IMAGE_WIDTH ${png.width}\n`;
out += `#define ${name}_IMAGE_HEIGHT ${png.height}\n`;
out += `#define ${name}_IMAGE_COLUMNS ${png.width / TILE_WIDTH}\n`;
out += `#define ${name}_IMAGE_ROWS ${png.height / TILE_HEIGHT}\n`;
out += `#define ${name}_IMAGE_TILES ${columns * rows}\n`;
out += `\nconst uint8_t ${name}_IMAGE[] = {\n${arrayToSTring(bits)}};`;
fs.writeFileSync(fileOut, out);
require('./../gb2png/')(bits, `${fileOut}.png`);
}
convert('images/font.png', 'out.c');
module.exports = {
png2gb
}
// convert('images/sm.png', 'out.c', 'PENNY');

29
scripts/string2gb.js Normal file
View File

@@ -0,0 +1,29 @@
const fs = require('fs');
const { arrayToString } = require('./util');
const FONT_CHARACTER_FIRST = 33;
const FONT_DATA_POSITION = 4;
const getCodeFrom = l => {
const cc = l.charCodeAt(0)
if(l == '\n' || l == ' ') return cc;
return cc - FONT_CHARACTER_FIRST + FONT_DATA_POSITION
}
const string2gb = (string, name) => {
const letters = [];
for(let i = 0; i < string.length; i++) {
letters.push(getCodeFrom(string[i]));
}
out = '#include "libs.h"\n\n';
out += `#define STR_${name}_LENGTH ${string.length}\n`;
out += `extern const uint8_t STR_${name}_DATA[];\n\n\n`
out += `const uint8_t STR_${name}_DATA[] = {\n` + arrayToString(letters) + `\n};`;
fs.writeFileSync('out.c', out);
}
module.exports = {
string2gb
};

21
scripts/util.js Normal file
View File

@@ -0,0 +1,21 @@
const arrayToString = arr => {
const b = arr.map(n => {
return '0x' + (n.toString(16).padStart(2, '0').toUpperCase());
});
let str = '';
for(let i = 0; i < b.length; i += 16) {
str += ' ';
for(let x = i; x < Math.min(i+16, b.length); x++) {
str += b[x];
str += ',';
}
str += '\n';
}
return str;
}
module.exports = {
arrayToString
}

View File

@@ -12,4 +12,8 @@ const uint8_t COMMON_TILES[] = {
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
};
void commonTilesInit() {
set_bkg_data(0x00, COMMON_TILE_COUNT, COMMON_TILES);
}

View File

@@ -15,4 +15,6 @@
#define COMMON_TILE_2 0x02
#define COMMON_TILE_3 0x03
extern const uint8_t COMMON_TILES[];
extern const uint8_t COMMON_TILES[];
void commonTilesInit();

View File

@@ -8,7 +8,7 @@
#include "font.h"
const uint8_t FONT_DATA[] = {
0x06,0x06,0x0E,0x0E,0x1C,0x1C,0x38,0x38,0x70,0x70,0x20,0x20,0x80,0x80,0x00,0x00,
0x06,0x06,0x0E,0x0E,0x1C,0x1C,0x18,0x18,0x30,0x30,0x00,0x00,0x40,0x40,0x00,0x00,
0x48,0x48,0x48,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x24,0x24,0x7E,0x7E,0x24,0x24,0x24,0x24,0x7E,0x7E,0x24,0x24,0x00,0x00,0x00,0x00,
0x08,0x08,0x3E,0x3E,0x28,0x28,0x3E,0x3E,0x0A,0x0A,0x3E,0x3E,0x08,0x08,0x00,0x00,
@@ -72,4 +72,36 @@ const uint8_t FONT_DATA[] = {
0x10,0x10,0x28,0x28,0x44,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x7C,0x00,0x00,
0x10,0x10,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x78,0x78,0x04,0x04,0x3C,0x3C,0x44,0x44,0x3A,0x3A,0x00,0x00,
0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x3C,0x22,0x22,0x22,0x22,0x3C,0x3C,0x00,0x00,
0x00,0x00,0x00,0x00,0x1C,0x1C,0x22,0x22,0x20,0x20,0x22,0x22,0x1C,0x1C,0x00,0x00,
0x02,0x02,0x02,0x02,0x02,0x02,0x1E,0x1E,0x22,0x22,0x22,0x22,0x1E,0x1E,0x00,0x00,
0x00,0x00,0x00,0x00,0x1C,0x1C,0x22,0x22,0x3E,0x3E,0x20,0x20,0x1E,0x1E,0x00,0x00,
0x06,0x06,0x08,0x08,0x08,0x08,0x3E,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,
0x00,0x00,0x1C,0x1C,0x22,0x22,0x22,0x22,0x1E,0x1E,0x02,0x02,0x3C,0x3C,0x00,0x00,
0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x3C,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,
0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x00,
0x00,0x00,0x02,0x02,0x00,0x00,0x02,0x02,0x02,0x02,0x12,0x12,0x0C,0x0C,0x00,0x00,
0x10,0x10,0x10,0x10,0x12,0x12,0x14,0x14,0x18,0x18,0x14,0x14,0x12,0x12,0x00,0x00,
0x0C,0x0C,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x0E,0x0E,0x00,0x00,
0x00,0x00,0x00,0x00,0x34,0x34,0x2A,0x2A,0x2A,0x2A,0x22,0x22,0x22,0x22,0x00,0x00,
0x00,0x00,0x00,0x00,0x3C,0x3C,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,
0x00,0x00,0x00,0x00,0x1C,0x1C,0x22,0x22,0x22,0x22,0x22,0x22,0x1C,0x1C,0x00,0x00,
0x00,0x00,0x00,0x00,0x3C,0x3C,0x22,0x22,0x22,0x22,0x3C,0x3C,0x20,0x20,0x00,0x00,
0x00,0x00,0x00,0x00,0x1E,0x1E,0x22,0x22,0x22,0x22,0x1E,0x1E,0x02,0x02,0x00,0x00,
0x00,0x00,0x00,0x00,0x2C,0x2C,0x32,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,
0x00,0x00,0x00,0x00,0x1E,0x1E,0x20,0x20,0x1C,0x1C,0x02,0x02,0x3C,0x3C,0x00,0x00,
0x10,0x10,0x10,0x10,0x3C,0x3C,0x10,0x10,0x10,0x10,0x12,0x12,0x0C,0x0C,0x00,0x00,
0x00,0x00,0x00,0x00,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1E,0x1E,0x00,0x00,
0x00,0x00,0x00,0x00,0x22,0x22,0x22,0x22,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00,
0x00,0x00,0x00,0x00,0x82,0x82,0x82,0x82,0x44,0x44,0x54,0x54,0x28,0x28,0x00,0x00,
0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x18,0x18,0x24,0x24,0x42,0x42,0x00,0x00,
0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x18,0x18,0x10,0x10,0x60,0x60,0x00,0x00,
0x00,0x00,0x00,0x00,0x3E,0x3E,0x04,0x04,0x08,0x08,0x10,0x10,0x3E,0x3E,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

View File

@@ -7,9 +7,12 @@
#pragma once
#include "libs.h"
#include "common_tiles.h"
#define FONT_IMAGE_WIDTH 64
#define FONT_IMAGE_HEIGHT 64
#define FONT_TILE_COUNT 64
#define FONT_IMAGE_HEIGHT 96
#define FONT_TILE_COUNT 96
#define FONT_DATA_POSITION COMMON_TILE_COUNT
extern const uint8_t FONT_DATA[];

20
src/frame.c Normal file
View File

@@ -0,0 +1,20 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "frame.h"
const uint8_t FRAME_DATA[] = {
0x00,0x00,0x00,0x00,0x3F,0x3F,0x29,0x29,0x3D,0x3D,0x2F,0x2F,0x24,0x24,0x3C,0x3C,
0x00,0x00,0x00,0x00,0xFF,0xFF,0x99,0x99,0x33,0x33,0xFF,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFC,0xFC,0x94,0x94,0xBC,0xBC,0xF4,0xF4,0x24,0x24,0x3C,0x3C,
0x2C,0x2C,0x24,0x24,0x34,0x34,0x3C,0x3C,0x2C,0x2C,0x24,0x24,0x34,0x34,0x3C,0x3C,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x2C,0x2C,0x24,0x24,0x34,0x34,0x3C,0x3C,0x2C,0x2C,0x24,0x24,0x34,0x34,0x3C,0x3C,
0x3C,0x3C,0x24,0x24,0x2F,0x2F,0x3D,0x3D,0x29,0x29,0x3F,0x3F,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFF,0xFF,0x99,0x99,0x33,0x33,0xFF,0xFF,0x00,0x00,0x00,0x00,
0x3C,0x3C,0x24,0x24,0xF4,0xF4,0xBC,0xBC,0x94,0x94,0xFC,0xFC,0x00,0x00,0x00,0x00,
};

29
src/frame.h Normal file
View File

@@ -0,0 +1,29 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "libs.h"
#include "font.h"
#define FRAME_IMAGE_WIDTH 24
#define FRAME_IMAGE_HEIGHT 24
#define FRAME_TILE_COUNT 9
#define FRAME_DATA_POSITION FONT_DATA_POSITION+FONT_TILE_COUNT
#define FRAME_TILE_TOP_LEFT FRAME_DATA_POSITION
#define FRAME_TILE_TOP_CENTER FRAME_TILE_TOP_LEFT + 1
#define FRAME_TILE_TOP_RIGHT FRAME_TILE_TOP_CENTER + 1
#define FRAME_TILE_CENTER_LEFT FRAME_TILE_TOP_RIGHT + 1
#define FRAME_TILE_CENTER FRAME_TILE_CENTER_LEFT + 1
#define FRAME_TILE_CENTER_RIGHT FRAME_TILE_CENTER + 1
#define FRAME_TILE_BOTTOM_LEFT FRAME_TILE_CENTER_RIGHT + 1
#define FRAME_TILE_BOTTOM_CENTER FRAME_TILE_BOTTOM_LEFT + 1
#define FRAME_TILE_BOTTOM_RIGHT FRAME_TILE_BOTTOM_CENTER + 1
extern const uint8_t FRAME_DATA[];

11
src/input.h Normal file
View File

@@ -0,0 +1,11 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "libs.h"
extern uint8_t INPUT_STATE;

View File

@@ -9,7 +9,8 @@
#include "textbox.h"
#include "time.h"
#include "common_tiles.h"
#include "penny.h"
#include "strings.h"
void main() {
int16_t j;
@@ -20,15 +21,18 @@ void main() {
LCDC_REG = LCDCF_OFF | LCDCF_WIN9C00 | LCDCF_BG8800 | LCDCF_BG9800 | LCDCF_BGON;
BGP_REG = OBP0_REG = OBP1_REG = 0xE4U;
// Upload the common tiles.
set_bkg_data(0x00, COMMON_TILE_COUNT, COMMON_TILES);
// Init the textbox
// Prepare tiles.
commonTilesInit();
textboxInit();
set_bkg_data(PENNY_DATA_POSITION, PENNY_IMAGE_TILES, PENNY_IMAGE);
// Fill screen white
for(j = 0; j < 0x20*0x20; j++) filled[j] = COMMON_TILE_0;
for(j = 0; j < 0x20*0x20; j++) filled[j] = COMMON_TILE_3;
set_bkg_tiles(0x00, 0x00, 0x20, 0x20, filled);
uint8_t penny[PENNY_IMAGE_TILES];
for(j = 0; j < PENNY_IMAGE_TILES; j++) penny[j] = j + PENNY_DATA_POSITION;
set_bkg_tiles(0x00, 0x00, PENNY_IMAGE_COLUMNS, PENNY_IMAGE_ROWS, penny);
SCX_REG = 0x00;
SCY_REG = 0x00;
@@ -38,7 +42,7 @@ void main() {
wait_vbl_done();
// Testing.
textboxSetText("HELLO WORLD.\nHOW ARE YOU?", 25);
textboxSetText(STR_HELLO_DATA, STR_HELLO_LENGTH);
while(1) {
wait_vbl_done();

91
src/penny.c Normal file
View File

@@ -0,0 +1,91 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "penny.h"
const uint8_t PENNY_IMAGE[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x05,0x04,0x00,0x04,0x04,0x0B,
0x00,0x00,0x00,0x00,0x78,0x78,0x84,0x86,0xCC,0x01,0x02,0x30,0x01,0x08,0x0B,0x85,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0xBF,0xFF,0xC0,0xFF,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x1F,0xFF,0xE0,0xFF,0x00,
0x00,0x00,0x00,0x00,0x03,0x03,0x0F,0x0C,0x1C,0x10,0x30,0x23,0xE0,0xE4,0xF0,0x35,
0x00,0x00,0x00,0x00,0xC0,0xC0,0xF0,0x30,0x38,0xC8,0x0C,0x04,0x04,0x74,0x0C,0x82,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x08,0x08,0x08,0x0B,0x08,0x0C,0x04,0x04,0x06,0x04,0x03,0x0E,0x01,0x11,0x02,0x24,
0x05,0x62,0x1B,0x8C,0x1F,0x70,0x3C,0x20,0x71,0x28,0xB2,0x48,0x38,0xC4,0x76,0xC0,
0xE3,0x00,0x00,0xC0,0x40,0x20,0x20,0x00,0x83,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
0x98,0x60,0xE0,0x00,0x00,0x00,0x00,0x00,0x04,0x88,0x80,0x50,0x20,0x00,0x0C,0x00,
0xF8,0x0A,0x3B,0x04,0x1C,0x03,0x0E,0x01,0x0F,0x00,0x05,0x02,0x06,0x00,0x04,0x00,
0x06,0x02,0x06,0xF2,0x84,0x0E,0xB8,0x04,0x60,0x98,0x18,0xFC,0x74,0xE4,0xBE,0x42,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x03,0x02,0x03,0x02,0x06,0x04,
0x65,0x41,0xCF,0x82,0xCF,0x84,0x8E,0x04,0x8F,0x05,0x0F,0x05,0x1B,0x02,0x1B,0x0A,
0xE0,0x00,0x80,0x00,0x60,0x40,0xC0,0x80,0xC0,0x00,0x80,0x00,0x81,0x01,0x8A,0x02,
0x00,0x00,0x08,0x00,0x08,0x11,0x10,0x22,0x12,0x22,0x7A,0x7A,0x05,0x91,0x0B,0x41,
0x10,0x00,0x00,0x4C,0x8A,0xB6,0x57,0x4D,0x32,0x32,0x00,0x00,0x00,0x01,0x01,0x82,
0x00,0x20,0x20,0x00,0x20,0x10,0x10,0x08,0x95,0x88,0xF9,0xF8,0xBD,0x94,0x68,0x32,
0x06,0x1A,0x0B,0x05,0x1B,0x15,0x07,0x08,0x0B,0x04,0x05,0x02,0x25,0x02,0x33,0x02,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,
0x06,0x04,0x06,0x04,0x02,0x04,0x00,0x04,0x0C,0x08,0x04,0x08,0x04,0x08,0x04,0x08,
0x3B,0x0A,0x39,0x09,0x31,0x13,0x33,0x12,0x31,0x11,0x71,0x11,0x70,0x10,0x60,0x20,
0xEC,0x00,0x6C,0x00,0x36,0x01,0xB0,0x02,0x9F,0x02,0xDC,0x04,0xFC,0x88,0x7E,0x54,
0x74,0x00,0xC0,0x00,0x3C,0x9C,0x62,0x22,0x5D,0x59,0xBD,0xBD,0xA4,0xA4,0x86,0xA6,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,
0x7C,0x82,0x04,0x02,0xE7,0xE0,0x12,0x11,0xEA,0xC9,0xFF,0xE4,0x24,0x35,0x23,0x30,
0x63,0x0A,0xE7,0x04,0x93,0x04,0x07,0x90,0x0B,0x24,0x17,0xC8,0x3F,0x18,0xEF,0x68,
0xC0,0x40,0xC0,0x40,0xA0,0x20,0xA0,0x20,0xA0,0x20,0xA0,0x20,0xA0,0x20,0x90,0x10,
0x1C,0x10,0x14,0x10,0x14,0x10,0x14,0x10,0x10,0x14,0x10,0x12,0x10,0x12,0x10,0x12,
0x60,0x20,0x60,0x20,0x60,0x20,0x60,0x20,0xE0,0x20,0xE0,0x20,0xE0,0x20,0xE0,0x20,
0x7E,0x64,0x36,0x2C,0x2D,0x2A,0x17,0x32,0x13,0x12,0x0C,0x0F,0x01,0x01,0x00,0x00,
0x3C,0x3E,0x14,0x36,0x10,0x1C,0x00,0x00,0x00,0x00,0x80,0x28,0x80,0x00,0xC0,0x80,
0x00,0x01,0x00,0x01,0x01,0x10,0x00,0x10,0x00,0x08,0x00,0x00,0x60,0xFC,0x78,0x84,
0xE7,0xF2,0x67,0x73,0x47,0xA2,0x02,0x04,0x02,0x04,0x0D,0x57,0x0C,0x04,0x08,0x08,
0xCF,0x48,0xCF,0x48,0x47,0x44,0x07,0x44,0x87,0x84,0x07,0x04,0x03,0x02,0x03,0x02,
0x90,0x10,0x90,0x10,0xD0,0x10,0xD0,0x10,0xC8,0x08,0xC8,0x08,0xC8,0x08,0x48,0x88,
0x10,0x12,0x10,0x12,0x30,0x21,0x30,0x21,0x30,0x21,0x31,0x20,0x30,0x20,0x30,0x20,
0x70,0x10,0x70,0x10,0x30,0x10,0x30,0x10,0x30,0x10,0x30,0x10,0xB0,0x10,0xB0,0x10,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x60,0x40,0x20,0x20,0x10,0x10,0x0C,0x08,0x08,0x0A,0x0D,0x09,0x0C,0x08,0x0C,0x08,
0x30,0x48,0x00,0x30,0x00,0x00,0x00,0x00,0x01,0x00,0xC3,0x83,0xE4,0x6A,0x04,0x12,
0x18,0x08,0x30,0x10,0x60,0x20,0xC0,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
0x03,0x02,0x03,0x02,0x03,0x02,0x03,0x02,0x03,0x02,0x03,0x02,0x07,0x04,0x07,0x04,
0x08,0x88,0x04,0x84,0x84,0x44,0x84,0x44,0xC4,0x04,0xC4,0x24,0xC4,0x24,0xC4,0x24,
0x30,0x20,0x38,0x20,0x38,0x20,0x38,0x20,0x38,0x20,0x38,0x20,0x38,0x20,0x18,0x10,
0x70,0x10,0x70,0x10,0x18,0x28,0x18,0x28,0x28,0x18,0x28,0x18,0x3C,0x08,0x39,0x09,
0x00,0x00,0x00,0x00,0x01,0x01,0x06,0x07,0x18,0x1F,0x60,0x7F,0x84,0xE7,0xB8,0xB9,
0x08,0x08,0x68,0x78,0x38,0xF8,0x1C,0xF0,0x0C,0xF8,0x04,0xFC,0x03,0xFE,0x01,0xFF,
0x06,0x02,0x07,0x03,0x03,0x03,0x03,0x02,0x03,0x00,0x00,0x00,0x01,0x82,0x00,0x44,
0x00,0x00,0x80,0x80,0x60,0xE0,0x9C,0xFC,0x82,0xFE,0x81,0xFF,0x80,0xFF,0x80,0xFE,
0x07,0x04,0x07,0x04,0x07,0x04,0x07,0x04,0x0F,0x08,0x8F,0xC8,0x7F,0x70,0xDF,0xDC,
0x84,0x24,0xA4,0x04,0x24,0x04,0x24,0x04,0x14,0x04,0x14,0x04,0x14,0x04,0x14,0x04,
0x1C,0x10,0x1C,0x10,0x1C,0x10,0x1C,0x10,0x1C,0x10,0x1C,0x10,0x0C,0x08,0x0D,0x08,
0x3F,0x07,0x38,0x08,0x70,0x10,0x60,0x20,0xC2,0x40,0x81,0x81,0x80,0x80,0x81,0x80,
0xE6,0xE6,0x39,0x39,0x04,0x06,0x01,0x01,0x00,0x00,0x80,0x00,0xC0,0x80,0xC1,0x40,
0x01,0x7F,0x80,0xBF,0x40,0x5F,0x80,0xAF,0x80,0xD7,0x20,0x2B,0x10,0x14,0x88,0x0B,
0x01,0x00,0x81,0x80,0xC1,0x80,0x61,0xC1,0x63,0xC1,0x23,0xE1,0x33,0xE1,0x32,0x63,
0x80,0xFE,0x81,0xFD,0x82,0xFA,0x02,0xFA,0x05,0xF5,0x03,0xEB,0x06,0xD6,0x2C,0xAC,
0x33,0xB2,0x71,0x61,0xE0,0xC1,0x80,0x80,0x80,0x80,0x00,0x00,0x03,0x00,0x07,0x00,
0x14,0x04,0x84,0x14,0xC0,0x08,0x48,0x88,0xC8,0x88,0xE8,0x48,0x68,0x48,0x68,0x48,
0x0F,0x08,0x0F,0x08,0x0F,0x08,0x0F,0x08,0x07,0x04,0x07,0x04,0x07,0x04,0x07,0x04,
0x81,0x80,0x81,0x80,0x80,0x80,0xC0,0x40,0xC0,0x40,0xC0,0x40,0x80,0x80,0x80,0x80,
0xE9,0x41,0xD6,0x27,0xD8,0x2F,0x78,0x0F,0x78,0x0F,0x78,0x0F,0x78,0x0F,0xF8,0x0F,
0xF4,0xC4,0x3E,0xFF,0x03,0xFF,0x00,0xFF,0x08,0xF7,0x06,0xF9,0x02,0xFD,0x04,0xFB,
0x12,0xB3,0x1E,0x52,0x3F,0xBF,0x70,0xE1,0xE0,0xCC,0xC0,0x92,0xA0,0xBD,0xA1,0xBD,
0x1F,0x5F,0x38,0xBF,0x60,0x7F,0x80,0xFF,0x98,0xE7,0x50,0x6F,0x50,0x6F,0x48,0x77,
0xC7,0xC0,0x27,0xE0,0x17,0xF0,0x97,0x70,0x56,0xB0,0x52,0xB0,0x52,0xB0,0x52,0xB0,
0x68,0x48,0x68,0x48,0x70,0x50,0x70,0x50,0x70,0x50,0x70,0x50,0x70,0x50,0x38,0x28,
0x07,0x04,0x07,0x04,0x03,0x02,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x80,0x80,0xC0,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x07,0x02,
0xF8,0x0F,0x7C,0x27,0x7C,0x07,0xFC,0x2F,0xFC,0x2F,0xDC,0x2F,0xFB,0x2F,0xF0,0x6F,
0x08,0xF7,0x00,0xFF,0x03,0xFF,0x0C,0xFF,0x30,0xFF,0xC1,0xFF,0x83,0xFE,0x06,0xFC,
0x52,0x9E,0xED,0xCC,0x33,0xE1,0x7D,0xDE,0xFF,0x80,0xFF,0x00,0xE0,0x00,0x00,0x00,
0xC4,0x7B,0x80,0xFF,0x60,0xFF,0x90,0xFF,0xC8,0x7F,0xE4,0x3F,0x73,0x1F,0x38,0x0F,
0x1C,0xFC,0x14,0xFC,0x14,0xFC,0x10,0xFC,0x10,0xFC,0x16,0xFC,0x26,0xFC,0xC4,0xFC,
0x38,0x28,0x38,0x28,0x38,0x28,0x38,0x28,0x38,0x28,0x38,0x10,0x18,0x10,0x10,0x10,
};

20
src/penny.h Normal file
View File

@@ -0,0 +1,20 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "libs.h"
#include "frame.h"
#define PENNY_IMAGE_WIDTH 64
#define PENNY_IMAGE_HEIGHT 80
#define PENNY_IMAGE_COLUMNS 8
#define PENNY_IMAGE_ROWS 10
#define PENNY_IMAGE_TILES 80
#define PENNY_DATA_POSITION FRAME_DATA_POSITION+FRAME_TILE_COUNT
extern const uint8_t PENNY_IMAGE[];

13
src/strings.c Normal file
View File

@@ -0,0 +1,13 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "strings.h"
const uint8_t STR_HELLO_DATA[] = {
0x2B,0x48,0x4F,0x4F,0x52,0x20,0x3A,0x52,0x55,0x4F,0x47,0x04,0x0A,0x2B,0x52,0x5A,
0x20,0x44,0x55,0x48,0x20,0x5C,0x52,0x58,0x20,0x57,0x52,0x47,0x44,0x5C,0x22,
};

12
src/strings.h Normal file
View File

@@ -0,0 +1,12 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "libs.h"
#define STR_HELLO_LENGTH 31
extern const uint8_t STR_HELLO_DATA[];

View File

@@ -11,30 +11,62 @@ char *TEXTBOX_TEXT;
uint8_t TEXTBOX_TEXT_LENGTH;
uint8_t TEXTBOX_STATE;
uint8_t TEXTBOX_SCROLL;
uint8_t TEXTBOX_TILES[TEXTBOX_TILES_MAX];
void textboxInit() {
uint8_t i;
// Reset textbox state
TEXTBOX_TEXT = NULL;
TEXTBOX_STATE = 0;
TEXTBOX_TEXT_LENGTH = 0;
TEXTBOX_SCROLL = 0;
move_win(7, SCREENHEIGHT - (TEXTBOX_TILES_ROWS * 8));
set_win_data(TEXTBOX_TILES_DATA_POSITION, FONT_TILE_COUNT, FONT_DATA);
// Setup window data
move_win(7, SCREENHEIGHT - (TEXTBOX_HEIGHT_IN_TILES * 8));
set_win_data(FONT_DATA_POSITION, FONT_TILE_COUNT, FONT_DATA);
set_win_data(FRAME_DATA_POSITION, FRAME_TILE_COUNT, FRAME_DATA);
// Corners
TEXTBOX_TILES[0] = FRAME_TILE_TOP_LEFT;
TEXTBOX_TILES[TEXTBOX_WIDTH_IN_TILES-1] = FRAME_TILE_TOP_RIGHT;
TEXTBOX_TILES[TEXTBOX_TILES_MAX-1] = FRAME_TILE_BOTTOM_RIGHT;
TEXTBOX_TILES[TEXTBOX_TILES_MAX-TEXTBOX_WIDTH_IN_TILES] = FRAME_TILE_BOTTOM_LEFT;
// Edges
for(i = 1; i < TEXTBOX_WIDTH_IN_TILES - 1; i++) {
TEXTBOX_TILES[i] = FRAME_TILE_TOP_CENTER;
TEXTBOX_TILES[TEXTBOX_TILES_MAX - 1 - i] = FRAME_TILE_BOTTOM_CENTER;
}
for(i = 1; i < TEXTBOX_HEIGHT_IN_TILES - 1; i++) {
TEXTBOX_TILES[TEXTBOX_WIDTH_IN_TILES * i] = FRAME_TILE_CENTER_LEFT;
TEXTBOX_TILES[TEXTBOX_WIDTH_IN_TILES * (i+1) - 1] = FRAME_TILE_CENTER_RIGHT;
}
}
void textboxSetText(char *text, uint8_t length) {
uint8_t tiles[TEXTBOX_TILES_MAX];
uint8_t i;
uint8_t i, j;
// Reset textbox state
TEXTBOX_TEXT = text;
TEXTBOX_TEXT_LENGTH = length;
TEXTBOX_STATE = TEXTBOX_STATE_VISIBLE;
TEXTBOX_SCROLL = 0;
// Fill blank characters
for(j = 0; j < TEXTBOX_CHAR_ROWS; j++) {
for(i = 0; i < TEXTBOX_CHARS_PER_ROW ; i++) {
TEXTBOX_TILES[(i+1) + ((j + 1) * TEXTBOX_WIDTH_IN_TILES)] = (
TEXTBOX_TILE_BLANK
);
}
}
for(i = 0; i < TEXTBOX_TILES_MAX; i++) tiles[i] = TEXTBOX_TILE_BLANK;
set_win_tiles(0, 0, TEXTBOX_TILES_PER_ROW, TEXTBOX_TILES_ROWS, tiles);
set_win_tiles(
0, 0,
TEXTBOX_WIDTH_IN_TILES, TEXTBOX_HEIGHT_IN_TILES,
TEXTBOX_TILES
);
SHOW_WIN;
}
@@ -44,7 +76,6 @@ void textboxClose() {
}
void textboxUpdate() {
uint8_t tiles[TEXTBOX_TILES_MAX];
uint8_t i, j;
if(!(TEXTBOX_STATE & TEXTBOX_STATE_VISIBLE)) return;
@@ -53,30 +84,27 @@ void textboxUpdate() {
}
TEXTBOX_SCROLL++;
j = 0;
j = TEXTBOX_WIDTH_IN_TILES + 1;
for(i = 0; i < TEXTBOX_SCROLL; i++) {
if(TEXTBOX_TEXT[i] == ' ') {
j++;
continue;
}
if(TEXTBOX_TEXT[i] == '\n') {
j = TEXTBOX_TILES_PER_ROW;
j = (
(j / TEXTBOX_WIDTH_IN_TILES)*TEXTBOX_WIDTH_IN_TILES
) + TEXTBOX_WIDTH_IN_TILES + 1;
continue;
}
tiles[j] = TILE_FROM_CHAR(TEXTBOX_TEXT[i]);
TEXTBOX_TILES[j] = TEXTBOX_TEXT[i];
j++;
}
for(i = j; i < TEXTBOX_TILES_MAX; i++) {
tiles[i] = TEXTBOX_TILE_BLANK;
}
set_win_tiles(
0, 0,
TEXTBOX_TILES_PER_ROW,
TEXTBOX_TILES_ROWS,
tiles
TEXTBOX_WIDTH_IN_TILES,
TEXTBOX_HEIGHT_IN_TILES,
TEXTBOX_TILES
);
if(TEXTBOX_SCROLL == TEXTBOX_TEXT_LENGTH) {

View File

@@ -8,26 +8,30 @@
#pragma once
#include "libs.h"
#include "font.h"
#include "frame.h"
#include "util.h"
#include "common_tiles.h"
#define TEXTBOX_STATE_VISIBLE 1 << 0
#define TEXTBOX_STATE_SCROLLED 1 << 1
#define TEXTBOX_TILES_PER_ROW 20
#define TEXTBOX_TILES_ROWS 2
#define TEXTBOX_TILES_MAX TEXTBOX_TILES_PER_ROW * TEXTBOX_TILES_ROWS
#define TEXTBOX_CHARACTER_FIRST 33
#define TEXTBOX_WIDTH_IN_TILES 20
#define TEXTBOX_HEIGHT_IN_TILES 5
#define TEXTBOX_TILES_MAX (TEXTBOX_WIDTH_IN_TILES * TEXTBOX_HEIGHT_IN_TILES)
#define TEXTBOX_CHARS_PER_ROW (TEXTBOX_WIDTH_IN_TILES - 2)
#define TEXTBOX_CHAR_ROWS (TEXTBOX_HEIGHT_IN_TILES - 2)
#define TEXTBOX_TILES_PER_ROW TEXTBOX_WIDTH_IN_TILES
#define TEXTBOX_TILES_ROWS 3
#define TEXTBOX_TILE_BLANK COMMON_TILE_3
#define TEXTBOX_TILES_DATA_POSITION 0x04
#define TILE_FROM_CHAR(c) c-TEXTBOX_CHARACTER_FIRST+TEXTBOX_TILES_DATA_POSITION
extern char *TEXTBOX_TEXT;
extern uint8_t TEXTBOX_TEXT_LENGTH;
extern uint8_t TEXTBOX_STATE;
extern uint8_t TEXTBOX_SCROLL;
extern uint8_t TEXTBOX_TILES[];
void textboxInit();
void textboxSetText(char *text, uint8_t length);