VASTLY improved how I generate tiles and tiledata
170
.gitignore
vendored
@@ -1,84 +1,86 @@
|
|||||||
# Prerequisites
|
# Prerequisites
|
||||||
*.d
|
*.d
|
||||||
|
|
||||||
# Object files
|
# Object files
|
||||||
*.o
|
*.o
|
||||||
*.ko
|
*.ko
|
||||||
build/*.obj
|
build/*.obj
|
||||||
*.elf
|
*.elf
|
||||||
|
|
||||||
# Linker output
|
# Linker output
|
||||||
*.ilk
|
*.ilk
|
||||||
*.map
|
*.map
|
||||||
*.exp
|
*.exp
|
||||||
|
|
||||||
# Precompiled Headers
|
# Precompiled Headers
|
||||||
*.gch
|
*.gch
|
||||||
*.pch
|
*.pch
|
||||||
|
|
||||||
# Libraries
|
# Libraries
|
||||||
*.lib
|
*.lib
|
||||||
*.a
|
*.a
|
||||||
*.la
|
*.la
|
||||||
*.lo
|
*.lo
|
||||||
|
|
||||||
# Shared objects (inc. Windows DLLs)
|
# Shared objects (inc. Windows DLLs)
|
||||||
*.dll
|
*.dll
|
||||||
*.so
|
*.so
|
||||||
*.so.*
|
*.so.*
|
||||||
*.dylib
|
*.dylib
|
||||||
|
|
||||||
# Executables
|
# Executables
|
||||||
*.exe
|
*.exe
|
||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
*.i*86
|
*.i*86
|
||||||
*.x86_64
|
*.x86_64
|
||||||
*.hex
|
*.hex
|
||||||
|
|
||||||
# Debug files
|
# Debug files
|
||||||
*.dSYM/
|
*.dSYM/
|
||||||
*.su
|
*.su
|
||||||
*.idb
|
*.idb
|
||||||
*.pdb
|
*.pdb
|
||||||
|
|
||||||
# Kernel Module Compile Results
|
# Kernel Module Compile Results
|
||||||
*.mod*
|
*.mod*
|
||||||
*.cmd
|
*.cmd
|
||||||
.tmp_versions/
|
.tmp_versions/
|
||||||
modules.order
|
modules.order
|
||||||
Module.symvers
|
Module.symvers
|
||||||
Mkfile.old
|
Mkfile.old
|
||||||
dkms.conf
|
dkms.conf
|
||||||
|
|
||||||
# CMake
|
# CMake
|
||||||
CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
CMakeScripts
|
CMakeScripts
|
||||||
Testing
|
Testing
|
||||||
Makefile
|
Makefile
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
install_manifest.txt
|
install_manifest.txt
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
CTestTestfile.cmake
|
CTestTestfile.cmake
|
||||||
_deps
|
_deps
|
||||||
|
|
||||||
# Custom
|
# Custom
|
||||||
build
|
build
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
assets/testworld/tileset.png
|
assets/testworld/tileset.png
|
||||||
oldsrc
|
oldsrc
|
||||||
|
|
||||||
node_modules
|
node_modules
|
||||||
yarn.lock
|
yarn.lock
|
||||||
|
|
||||||
*.log
|
*.log
|
||||||
obj
|
obj
|
||||||
res
|
res
|
||||||
|
|
||||||
out.c
|
out.c
|
||||||
out.c.png
|
out.c.png
|
||||||
|
|
||||||
emulator
|
emulator
|
||||||
|
|
||||||
|
bgb/*
|
235
archive/main.c
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
inline uint8_t mainGetChar(char c) {
|
||||||
|
return c - TEXTBOX_FONT_START + FONT_DATA_POSITION;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void mainBufferCard(uint8_t card, uint8_t *tiles) {
|
||||||
|
uint8_t suit, number;
|
||||||
|
|
||||||
|
if(card >= CARD_DECK_SIZE) {
|
||||||
|
tiles[0] = mainGetChar('N');
|
||||||
|
tiles[1] = mainGetChar('A');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
suit = cardGetSuit(card);
|
||||||
|
number = cardGetNumber(card);
|
||||||
|
|
||||||
|
switch(suit) {
|
||||||
|
case CARD_SUIT_CLUBS:
|
||||||
|
tiles[0] = mainGetChar('C');
|
||||||
|
break;
|
||||||
|
case CARD_SUIT_DIAMONDS:
|
||||||
|
tiles[0] = mainGetChar('D');
|
||||||
|
break;
|
||||||
|
case CARD_SUIT_HEARTS:
|
||||||
|
tiles[0] = mainGetChar('H');
|
||||||
|
break;
|
||||||
|
case CARD_SUIT_SPADES:
|
||||||
|
tiles[0] = mainGetChar('S');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(number) {
|
||||||
|
case CARD_TWO:
|
||||||
|
tiles[1] = mainGetChar('2');
|
||||||
|
break;
|
||||||
|
case CARD_THREE:
|
||||||
|
tiles[1] = mainGetChar('3');
|
||||||
|
break;
|
||||||
|
case CARD_FOUR:
|
||||||
|
tiles[1] = mainGetChar('4');
|
||||||
|
break;
|
||||||
|
case CARD_FIVE:
|
||||||
|
tiles[1] = mainGetChar('5');
|
||||||
|
break;
|
||||||
|
case CARD_SIX:
|
||||||
|
tiles[1] = mainGetChar('6');
|
||||||
|
break;
|
||||||
|
case CARD_SEVEN:
|
||||||
|
tiles[1] = mainGetChar('7');
|
||||||
|
break;
|
||||||
|
case CARD_EIGHT:
|
||||||
|
tiles[1] = mainGetChar('8');
|
||||||
|
break;
|
||||||
|
case CARD_NINE:
|
||||||
|
tiles[1] = mainGetChar('9');
|
||||||
|
break;
|
||||||
|
case CARD_TEN:
|
||||||
|
tiles[1] = mainGetChar('T');
|
||||||
|
break;
|
||||||
|
case CARD_JACK:
|
||||||
|
tiles[1] = mainGetChar('J');
|
||||||
|
break;
|
||||||
|
case CARD_QUEEN:
|
||||||
|
tiles[1] = mainGetChar('Q');
|
||||||
|
break;
|
||||||
|
case CARD_KING:
|
||||||
|
tiles[1] = mainGetChar('K');
|
||||||
|
break;
|
||||||
|
case CARD_ACE:
|
||||||
|
tiles[1] = mainGetChar('A');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void mainDebugDraw() {
|
||||||
|
uint8_t j, i, n;
|
||||||
|
|
||||||
|
// DEBUG DRAW
|
||||||
|
uint8_t tiles[15];
|
||||||
|
char buffer[6];
|
||||||
|
buffer[0] = '\0';
|
||||||
|
|
||||||
|
for(j = 0; j < POKER_PLAYER_COUNT; j++) {
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
if(j == POKER_PLAYER_BETTER) {
|
||||||
|
tiles[n++] = mainGetChar('>');
|
||||||
|
} else {
|
||||||
|
tiles[n++] = COMMON_TILE_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
mainBufferCard(POKER_PLAYERS[j].hand[0], tiles+n);
|
||||||
|
n+=2;
|
||||||
|
mainBufferCard(POKER_PLAYERS[j].hand[1], tiles+n);
|
||||||
|
n+=2;
|
||||||
|
|
||||||
|
tiles[n++] = COMMON_TILE_3;
|
||||||
|
|
||||||
|
if((POKER_PLAYERS[j].state & POKER_PLAYER_STATE_FOLDED) == 0) {
|
||||||
|
tiles[n++] = COMMON_TILE_3;
|
||||||
|
} else {
|
||||||
|
tiles[n++] = mainGetChar('F');
|
||||||
|
}
|
||||||
|
|
||||||
|
if((POKER_PLAYERS[j].state & POKER_PLAYER_STATE_HAS_BET_THIS_ROUND) == 0) {
|
||||||
|
tiles[n++] = COMMON_TILE_3;
|
||||||
|
} else {
|
||||||
|
tiles[n++] = mainGetChar('H');
|
||||||
|
}
|
||||||
|
|
||||||
|
if((POKER_PLAYERS[j].state & POKER_PLAYER_STATE_OUT) == 0) {
|
||||||
|
tiles[n++] = COMMON_TILE_3;
|
||||||
|
} else {
|
||||||
|
tiles[n++] = mainGetChar('O');
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles[n++] = COMMON_TILE_3;
|
||||||
|
|
||||||
|
// Print chips
|
||||||
|
sprintf(buffer, "%u", (uint16_t)POKER_PLAYERS[j].chips);
|
||||||
|
for(i = 0; i < strlen(buffer); i++) {
|
||||||
|
tiles[n++] = mainGetChar(buffer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(n < 15) tiles[n++] = COMMON_TILE_3;
|
||||||
|
set_bkg_tiles(0x00, j, n - 1, 1, tiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(j = 0; j < POKER_COMMUNITY_SIZE_MAX; j++) {
|
||||||
|
if(j >= POKER_COMMUNITY_SIZE) {
|
||||||
|
tiles[j*2] = COMMON_TILE_3;
|
||||||
|
tiles[(j*2) + 1] = COMMON_TILE_3;
|
||||||
|
} else {
|
||||||
|
mainBufferCard(POKER_COMMUNITY[j], tiles + (j * 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_bkg_tiles(0x00, POKER_PLAYER_COUNT + 1, POKER_COMMUNITY_SIZE_MAX * 2, 1, tiles);
|
||||||
|
|
||||||
|
|
||||||
|
// Print Pot
|
||||||
|
n = 0;
|
||||||
|
sprintf(buffer, "%u", (uint16_t)POKER_POTS[POKER_POT_CURRENT].chips);
|
||||||
|
for(i = 0; i < strlen(buffer); i++) {
|
||||||
|
tiles[n++] = mainGetChar(buffer[i]);
|
||||||
|
}
|
||||||
|
while(n < 5) tiles[n++] = COMMON_TILE_3;
|
||||||
|
set_bkg_tiles(0x00, POKER_PLAYER_COUNT + 2, n, 1, tiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
int16_t j;
|
||||||
|
uint8_t filled[GB_BACKGROUND_COLUMNS*GB_BACKGROUND_ROWS];
|
||||||
|
|
||||||
|
// Set up the GAMEBOY's registers.
|
||||||
|
disable_interrupts();
|
||||||
|
DISPLAY_OFF;
|
||||||
|
LCDC_REG = LCDCF_OFF | LCDCF_BG8000 | LCDCF_BG9800 | LCDCF_BGON;
|
||||||
|
// Set the background color palette register
|
||||||
|
BGP_REG = OBP0_REG = OBP1_REG = 0xE4U;
|
||||||
|
|
||||||
|
// Init the random seed
|
||||||
|
initarand(DIV_REG);
|
||||||
|
|
||||||
|
// Init things
|
||||||
|
spriteTilesetBuffer(0x00);
|
||||||
|
spriteFontBuffer(TEXTBOX_SPRITE_FONT_POSITION);
|
||||||
|
spriteBorderBuffer(TEXTBOX_SPRITE_BORDER_POSITION);
|
||||||
|
spriteCardsBuffer(TEXTBOX_SPRITE_BORDER_POSITION + BORDER_IMAGE_TILES);
|
||||||
|
|
||||||
|
conversationTextboxInit();
|
||||||
|
conversationQueueInit();
|
||||||
|
pokerInit();
|
||||||
|
|
||||||
|
// Fill screen white
|
||||||
|
for(j = 0; j < GB_BACKGROUND_COLUMNS * GB_BACKGROUND_ROWS; j++) filled[j] = TILESET_WHITE;
|
||||||
|
set_bkg_tiles(0x00, 0x00, GB_BACKGROUND_COLUMNS, GB_BACKGROUND_ROWS, filled);
|
||||||
|
SCX_REG = 0x00;
|
||||||
|
SCY_REG = 0x00;
|
||||||
|
|
||||||
|
// Card Test
|
||||||
|
uint8_t cardTiles[4 * 6];
|
||||||
|
spriteCardBufferTiles(
|
||||||
|
TEXTBOX_SPRITE_BORDER_POSITION+BORDER_IMAGE_TILES,
|
||||||
|
cardTiles,
|
||||||
|
CARD_HEARTS_TWO
|
||||||
|
);
|
||||||
|
set_bkg_tiles(0x00, 0x00, 4, 6, cardTiles);
|
||||||
|
|
||||||
|
// Now turn the screen on
|
||||||
|
DISPLAY_ON;
|
||||||
|
enable_interrupts();
|
||||||
|
wait_vbl_done();
|
||||||
|
|
||||||
|
// Begin game
|
||||||
|
conversationQueueNext();
|
||||||
|
|
||||||
|
// Begin the loop
|
||||||
|
while(1) {
|
||||||
|
// Perform non-graphical code updates
|
||||||
|
wait_vbl_done();
|
||||||
|
|
||||||
|
// Update the input state
|
||||||
|
INPUT_LAST = INPUT_STATE;
|
||||||
|
INPUT_STATE = joypad();
|
||||||
|
INPUT_PRESSED = (~INPUT_LAST) & INPUT_STATE;
|
||||||
|
|
||||||
|
// Tick time.
|
||||||
|
timeUpdate();
|
||||||
|
|
||||||
|
// Update conversation pause effect
|
||||||
|
conversationPauseUpdate();
|
||||||
|
|
||||||
|
// Update question box and textbox
|
||||||
|
questionBoxUpdate();
|
||||||
|
conversationTextboxUpdate();
|
||||||
|
|
||||||
|
// Update conversation fade effect
|
||||||
|
conversationFadeUpdate();
|
||||||
|
// mainDebugDraw();
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 175 B After Width: | Height: | Size: 240 B |
BIN
assets/images/cards_tiles.png
Normal file
After Width: | Height: | Size: 832 B |
BIN
assets/images/cards_tiles.pxo
Normal file
BIN
assets/images/tileset.png
Normal file
After Width: | Height: | Size: 120 B |
BIN
assets/images_noconvert/FINISHEDV2.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/images_noconvert/cards.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/images_noconvert/cards.pxo
Normal file
BIN
assets/images_noconvert/tileset.png
Normal file
After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 119 B |
34
package.json
@@ -1,17 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "Dawn-GB",
|
"name": "Dawn-GB",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"repository": "https://github.com/YourWishes/Dawn-GB.git",
|
"repository": "https://github.com/YourWishes/Dawn-GB.git",
|
||||||
"author": "Dominic Masters <dominic@domsplace.com>",
|
"author": "Dominic Masters <dominic@domsplace.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "node ./scripts/clean",
|
"clean": "node ./scripts/clean",
|
||||||
"build": "npm run clean && node ./scripts/build",
|
"build": "npm run clean && node ./scripts/build",
|
||||||
"start": "npm run build && bgb64.exe ./build/Penny.gb"
|
"start": "npm run build && wine ./bgb/bgb64.exe ./build/Penny.gb"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pngjs": "^6.0.0",
|
"pngjs": "^6.0.0",
|
||||||
"rimraf": "^3.0.2"
|
"rimraf": "^3.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
const process = require('process');
|
const process = require('process');
|
||||||
const { spawnSync, execSync } = require('child_process');
|
const { spawnSync, execSync } = require('child_process');
|
||||||
|
|
||||||
execSync(`scp ./build/Penny.gb root@ywbud3:/storage/roms/gb/Penny.gb`);
|
execSync(`scp ./build/Penny.gb root@ywbud3:/storage/roms/gb/Penny.gb`);
|
||||||
execSync(`echo "systemctl stop emustation.service; killall emulationstation; retroarch -L /lib/libretro/gambatte_libretro.so '/storage/roms/gb/Penny.gb';" | ssh root@ywbud3 /bin/bash`);
|
execSync(`echo "systemctl stop emustation.service; killall emulationstation; retroarch -L /lib/libretro/gambatte_libretro.so '/storage/roms/gb/Penny.gb';" | ssh root@ywbud3 /bin/bash`);
|
246
scripts/build.js
@@ -1,124 +1,124 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const process = require('process');
|
const process = require('process');
|
||||||
const { spawnSync, execSync } = require('child_process');
|
const { spawnSync, execSync } = require('child_process');
|
||||||
const { png2gb } = require('./png2gb');
|
const { png2gb } = require('./png2gb');
|
||||||
const { string2gb } = require('./string2gb');
|
const { string2gb } = require('./string2gb');
|
||||||
|
|
||||||
const DIR_BUILD = path.resolve('build');
|
const DIR_BUILD = path.resolve('build');
|
||||||
const DIR_GENERATED = path.resolve(DIR_BUILD, 'generated');
|
const DIR_GENERATED = path.resolve(DIR_BUILD, 'generated');
|
||||||
const DIR_OBJ = path.resolve(DIR_BUILD, 'obj');
|
const DIR_OBJ = path.resolve(DIR_BUILD, 'obj');
|
||||||
const DIR_SRC = path.resolve('src');
|
const DIR_SRC = path.resolve('src');
|
||||||
const DIR_GBDK = path.resolve(process.env['GBDKDIR']);
|
const DIR_GBDK = path.resolve(process.env['GBDKDIR']);
|
||||||
const DIR_ASSETS = path.resolve('assets');
|
const DIR_ASSETS = path.resolve('assets');
|
||||||
const DIR_IMAGES = path.resolve(DIR_ASSETS, 'images');
|
const DIR_IMAGES = path.resolve(DIR_ASSETS, 'images');
|
||||||
|
|
||||||
const FILE_OUT = path.resolve(DIR_BUILD, 'Penny.gb');
|
const FILE_OUT = path.resolve(DIR_BUILD, 'Penny.gb');
|
||||||
const FILE_LINKFILE = path.join(DIR_BUILD, `linkflile.lk`);
|
const FILE_LINKFILE = path.join(DIR_BUILD, `linkflile.lk`);
|
||||||
|
|
||||||
const LCC = path.join(DIR_GBDK, 'bin', 'lcc');
|
const LCC = path.join(DIR_GBDK, 'bin', 'lcc');
|
||||||
const LCCFLAGS = `-I${DIR_GENERATED} -I${DIR_SRC}`;
|
const LCCFLAGS = `-I${DIR_GENERATED} -I${DIR_SRC}`;
|
||||||
|
|
||||||
const compiledSources = [];
|
const compiledSources = [];
|
||||||
|
|
||||||
// Create build dirs
|
// Create build dirs
|
||||||
[
|
[
|
||||||
DIR_BUILD, DIR_GENERATED, DIR_OBJ
|
DIR_BUILD, DIR_GENERATED, DIR_OBJ
|
||||||
].forEach(d => {
|
].forEach(d => {
|
||||||
if(fs.existsSync(d)) return;
|
if(fs.existsSync(d)) return;
|
||||||
fs.mkdirSync(d);
|
fs.mkdirSync(d);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Scandir
|
// Scandir
|
||||||
const buildSourceFiles = directory => {
|
const buildSourceFiles = directory => {
|
||||||
const sources = [];
|
const sources = [];
|
||||||
|
|
||||||
fs.readdirSync(directory).forEach(file => {
|
fs.readdirSync(directory).forEach(file => {
|
||||||
const fullPath = path.join(directory, file);
|
const fullPath = path.join(directory, file);
|
||||||
const stats = fs.statSync(fullPath);
|
const stats = fs.statSync(fullPath);
|
||||||
if(stats.isDirectory()) {
|
if(stats.isDirectory()) {
|
||||||
sources.push(...buildSourceFiles(fullPath));
|
sources.push(...buildSourceFiles(fullPath));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(file.endsWith('.c')) sources.push(fullPath);
|
if(file.endsWith('.c')) sources.push(fullPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
return sources;
|
return sources;
|
||||||
}
|
}
|
||||||
|
|
||||||
const logOut = (out, buffer) => {
|
const logOut = (out, buffer) => {
|
||||||
const str = [
|
const str = [
|
||||||
out.stderr, out.stdout
|
out.stderr, out.stdout
|
||||||
].filter(n => n)
|
].filter(n => n)
|
||||||
.map(n => n.toString())
|
.map(n => n.toString())
|
||||||
.filter(n => n)
|
.filter(n => n)
|
||||||
.join('')
|
.join('')
|
||||||
;
|
;
|
||||||
if(!str || !str.length) return;
|
if(!str || !str.length) return;
|
||||||
buffer(str);
|
buffer(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
const compileC = (cFile) => {
|
const compileC = (cFile) => {
|
||||||
const fileNameOut = path.basename(cFile, '.c') + '.o';
|
const fileNameOut = path.basename(cFile, '.c') + '.o';
|
||||||
const fileOut = path.join(DIR_OBJ, fileNameOut);
|
const fileOut = path.join(DIR_OBJ, fileNameOut);
|
||||||
|
|
||||||
compiledSources.push(path.join(fileNameOut));
|
compiledSources.push(path.join(fileNameOut));
|
||||||
|
|
||||||
if(fs.existsSync(fileOut)) return;
|
if(fs.existsSync(fileOut)) return;
|
||||||
|
|
||||||
let result;
|
let result;
|
||||||
try {
|
try {
|
||||||
result = execSync(`${LCC} ${LCCFLAGS} -c -o ${fileOut} ${cFile}`);
|
result = execSync(`${LCC} ${LCCFLAGS} -c -o ${fileOut} ${cFile}`);
|
||||||
logOut(result, console.log);
|
logOut(result, console.log);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
logOut(e, e => {
|
logOut(e, e => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate strings
|
// Generate strings
|
||||||
// let dataStringH = '#pragma once\n#include "libs.h"\n';
|
// let dataStringH = '#pragma once\n#include "libs.h"\n';
|
||||||
// let dataStringC = '#include "STRINGS.h"\n';
|
// let dataStringC = '#include "STRINGS.h"\n';
|
||||||
// Object.entries(GAME_STRINGS).forEach(entry => {
|
// Object.entries(GAME_STRINGS).forEach(entry => {
|
||||||
// const [ name, str ] = entry;
|
// const [ name, str ] = entry;
|
||||||
// const { dataH, dataC } = string2gb(str, name);
|
// const { dataH, dataC } = string2gb(str, name);
|
||||||
// dataStringH += dataH+'\n', dataStringC += dataC+'\n';
|
// dataStringH += dataH+'\n', dataStringC += dataC+'\n';
|
||||||
// });
|
// });
|
||||||
// fs.writeFileSync(path.join(DIR_GENERATED, 'STRINGS.h'), dataStringH);
|
// fs.writeFileSync(path.join(DIR_GENERATED, 'STRINGS.h'), dataStringH);
|
||||||
// fs.writeFileSync(path.join(DIR_GENERATED, 'STRINGS.c'), dataStringC);
|
// fs.writeFileSync(path.join(DIR_GENERATED, 'STRINGS.c'), dataStringC);
|
||||||
// compileC(path.join(DIR_GENERATED, 'STRINGS.c'));
|
// compileC(path.join(DIR_GENERATED, 'STRINGS.c'));
|
||||||
|
|
||||||
// Gen imagery
|
// Gen imagery
|
||||||
fs.readdirSync(DIR_IMAGES).forEach(img => {
|
fs.readdirSync(DIR_IMAGES).forEach(img => {
|
||||||
if(!img.endsWith(".png")) return;
|
if(!img.endsWith(".png")) return;
|
||||||
const { fileC, fileH } = png2gb(
|
const { fileC, fileH } = png2gb(
|
||||||
path.join(DIR_IMAGES, img), DIR_GENERATED,
|
path.join(DIR_IMAGES, img), DIR_GENERATED,
|
||||||
path.basename(img, '.png').toUpperCase()
|
path.basename(img, '.png').toUpperCase()
|
||||||
);
|
);
|
||||||
compileC(fileC);
|
compileC(fileC);
|
||||||
})
|
})
|
||||||
|
|
||||||
// Get a list of sources and build each of them prior to linking.
|
// Get a list of sources and build each of them prior to linking.
|
||||||
const allSources = buildSourceFiles(DIR_SRC);
|
const allSources = buildSourceFiles(DIR_SRC);
|
||||||
for(let i = 0; i < allSources.length; i++) {
|
for(let i = 0; i < allSources.length; i++) {
|
||||||
compileC(allSources[i]);
|
compileC(allSources[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a linkfile.
|
// Generate a linkfile.
|
||||||
fs.writeFileSync(FILE_LINKFILE, compiledSources.map(cs=>{
|
fs.writeFileSync(FILE_LINKFILE, compiledSources.map(cs=>{
|
||||||
return path.join(DIR_OBJ, cs);
|
return path.join(DIR_OBJ, cs);
|
||||||
}).join('\n'));
|
}).join('\n'));
|
||||||
|
|
||||||
// Compile BIN
|
// Compile BIN
|
||||||
let result;
|
let result;
|
||||||
try {
|
try {
|
||||||
result = execSync(`${LCC} ${LCCFLAGS} -o ${FILE_OUT} -Wl-f${FILE_LINKFILE}`);
|
result = execSync(`${LCC} ${LCCFLAGS} -o ${FILE_OUT} -Wl-f${FILE_LINKFILE}`);
|
||||||
logOut(result, console.log);
|
logOut(result, console.log);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
logOut(e, console.error);
|
logOut(e, console.error);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
const rimraf = require('rimraf');
|
const rimraf = require('rimraf');
|
||||||
|
|
||||||
console.log('🔥 Cleaning');
|
console.log('🔥 Cleaning');
|
||||||
rimraf.sync('build');
|
rimraf.sync('build');
|
@@ -1,7 +1,7 @@
|
|||||||
const TILE_WIDTH = 8;
|
const TILE_WIDTH = 8;
|
||||||
const TILE_HEIGHT = 8;
|
const TILE_HEIGHT = 8;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
TILE_WIDTH,
|
TILE_WIDTH,
|
||||||
TILE_HEIGHT
|
TILE_HEIGHT
|
||||||
}
|
}
|
@@ -1,88 +1,88 @@
|
|||||||
const PNG = require('pngjs').PNG;
|
const PNG = require('pngjs').PNG;
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const {
|
const {
|
||||||
TILE_WIDTH,
|
TILE_WIDTH,
|
||||||
TILE_HEIGHT
|
TILE_HEIGHT
|
||||||
} = require('./common');
|
} = require('./common');
|
||||||
|
|
||||||
const colorPixel = (id) => {
|
const colorPixel = (id) => {
|
||||||
if(id === undefined) id = 3;
|
if(id === undefined) id = 3;
|
||||||
if(id === 3) return { r: 8, g: 24, b: 32 };
|
if(id === 3) return { r: 8, g: 24, b: 32 };
|
||||||
if(id === 2) return { r: 52, g: 104, b: 86 };
|
if(id === 2) return { r: 52, g: 104, b: 86 };
|
||||||
if(id === 1) return { r: 136, g: 192, b: 112 };
|
if(id === 1) return { r: 136, g: 192, b: 112 };
|
||||||
if(id === 0) return { r: 224, g: 248, b: 208 };
|
if(id === 0) return { r: 224, g: 248, b: 208 };
|
||||||
throw new Error();
|
throw new Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
const gb2png = (DATA, fileOut) => {
|
const gb2png = (DATA, fileOut) => {
|
||||||
// Begin
|
// Begin
|
||||||
const PIXELS = DATA.length / 2 * TILE_WIDTH;
|
const PIXELS = DATA.length / 2 * TILE_WIDTH;
|
||||||
const DATA_WIDTH = TILE_WIDTH;
|
const DATA_WIDTH = TILE_WIDTH;
|
||||||
const DATA_HEIGHT = PIXELS / DATA_WIDTH;
|
const DATA_HEIGHT = PIXELS / DATA_WIDTH;
|
||||||
|
|
||||||
// Create output image
|
// Create output image
|
||||||
const imageData = new PNG({
|
const imageData = new PNG({
|
||||||
width: DATA_WIDTH,
|
width: DATA_WIDTH,
|
||||||
height: DATA_HEIGHT
|
height: DATA_HEIGHT
|
||||||
});
|
});
|
||||||
|
|
||||||
// Convert data into pixels
|
// Convert data into pixels
|
||||||
const pixelsOut = [];
|
const pixelsOut = [];
|
||||||
for(let i = 0; i < DATA.length; i += 2) {
|
for(let i = 0; i < DATA.length; i += 2) {
|
||||||
const low = DATA[i];
|
const low = DATA[i];
|
||||||
const high = DATA[i+1];
|
const high = DATA[i+1];
|
||||||
|
|
||||||
for(let j = 0; j < 8; j++) {
|
for(let j = 0; j < 8; j++) {
|
||||||
const mask = 0x80 >> j;
|
const mask = 0x80 >> j;
|
||||||
const pixel = (low & mask ? 1 : 0) + (high & mask ? 2 : 0);
|
const pixel = (low & mask ? 1 : 0) + (high & mask ? 2 : 0);
|
||||||
pixelsOut.push(pixel);
|
pixelsOut.push(pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer data output
|
// Buffer data output
|
||||||
for(let y = 0; y < DATA_HEIGHT; y++) {
|
for(let y = 0; y < DATA_HEIGHT; y++) {
|
||||||
for(let x = 0; x < DATA_WIDTH; x++) {
|
for(let x = 0; x < DATA_WIDTH; x++) {
|
||||||
const id = (DATA_WIDTH * y + x);
|
const id = (DATA_WIDTH * y + x);
|
||||||
const color = colorPixel(pixelsOut[id]);
|
const color = colorPixel(pixelsOut[id]);
|
||||||
const idx = id << 2;
|
const idx = id << 2;
|
||||||
|
|
||||||
imageData.data[idx] = color.r;
|
imageData.data[idx] = color.r;
|
||||||
imageData.data[idx+1] = color.g;
|
imageData.data[idx+1] = color.g;
|
||||||
imageData.data[idx+2] = color.b;
|
imageData.data[idx+2] = color.b;
|
||||||
imageData.data[idx+3] = 0xFF;
|
imageData.data[idx+3] = 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const buffer = PNG.sync.write(imageData, { });
|
const buffer = PNG.sync.write(imageData, { });
|
||||||
fs.writeFileSync(fileOut, buffer);
|
fs.writeFileSync(fileOut, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Now work out tile data
|
// // Now work out tile data
|
||||||
// if(TILEMAP.length) {
|
// if(TILEMAP.length) {
|
||||||
// for(let i = 0; i < TILEMAP.length; i++) {
|
// for(let i = 0; i < TILEMAP.length; i++) {
|
||||||
// const tileX = i % TILEMAP_WIDTH;
|
// const tileX = i % TILEMAP_WIDTH;
|
||||||
// const tileY = Math.floor(i / TILEMAP_WIDTH);
|
// const tileY = Math.floor(i / TILEMAP_WIDTH);
|
||||||
// const tile = TILEMAP[i];
|
// const tile = TILEMAP[i];
|
||||||
|
|
||||||
// for(let j = 0; j < TILE_WIDTH*TILE_HEIGHT; j++) {
|
// for(let j = 0; j < TILE_WIDTH*TILE_HEIGHT; j++) {
|
||||||
// const outI = (
|
// const outI = (
|
||||||
// (tileX * TILE_WIDTH) + (tileY * TILE_HEIGHT * TILEMAP_PIXEL_WIDTH) +
|
// (tileX * TILE_WIDTH) + (tileY * TILE_HEIGHT * TILEMAP_PIXEL_WIDTH) +
|
||||||
// ((j % TILE_WIDTH) + (Math.floor(j / TILE_WIDTH) * TILEMAP_PIXEL_WIDTH))
|
// ((j % TILE_WIDTH) + (Math.floor(j / TILE_WIDTH) * TILEMAP_PIXEL_WIDTH))
|
||||||
// );
|
// );
|
||||||
// const idx = outI << 2;
|
// const idx = outI << 2;
|
||||||
// const pixelI = (tile * TILE_WIDTH * TILE_HEIGHT) + j;
|
// const pixelI = (tile * TILE_WIDTH * TILE_HEIGHT) + j;
|
||||||
// const color = colorPixel(pixelsOut[pixelI]);
|
// const color = colorPixel(pixelsOut[pixelI]);
|
||||||
|
|
||||||
// tileData.data[idx] = color.r;
|
// tileData.data[idx] = color.r;
|
||||||
// tileData.data[idx+1] = color.g;
|
// tileData.data[idx+1] = color.g;
|
||||||
// tileData.data[idx+2] = color.b;
|
// tileData.data[idx+2] = color.b;
|
||||||
// tileData.data[idx+3] = 0xFF;
|
// tileData.data[idx+3] = 0xFF;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// const buffer2 = PNG.sync.write(tileData, { });
|
// const buffer2 = PNG.sync.write(tileData, { });
|
||||||
// fs.writeFileSync('out.png', buffer2);
|
// fs.writeFileSync('out.png', buffer2);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
gb2png
|
gb2png
|
||||||
};
|
};
|
@@ -1,247 +1,247 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { PNG } = require('pngjs');
|
const { PNG } = require('pngjs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const TRANSPARENT = { r: 0, g: 0, b: 0, a: 0 };
|
const TRANSPARENT = { r: 0, g: 0, b: 0, a: 0 };
|
||||||
const WHITE = { r: 255, g: 255, b : 255, a: 255 };
|
const WHITE = { r: 255, g: 255, b : 255, a: 255 };
|
||||||
const RED = { r: 255, g: 0, b: 0, a: 255 };
|
const RED = { r: 255, g: 0, b: 0, a: 255 };
|
||||||
|
|
||||||
const TILE_WIDTH = 8;
|
const TILE_WIDTH = 8;
|
||||||
const TILE_HEIGHT = 8;
|
const TILE_HEIGHT = 8;
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
const pixelIsSame = (left, right, alpha) => {
|
const pixelIsSame = (left, right, alpha) => {
|
||||||
if(left.r !== right.r) return false;
|
if(left.r !== right.r) return false;
|
||||||
if(left.g !== right.g) return false;
|
if(left.g !== right.g) return false;
|
||||||
if(left.b !== right.b) return false;
|
if(left.b !== right.b) return false;
|
||||||
if(!alpha) return true;
|
if(!alpha) return true;
|
||||||
return left.a === right.a;
|
return left.a === right.a;
|
||||||
}
|
}
|
||||||
|
|
||||||
const imageOut = (pixels, width, fileName) => {
|
const imageOut = (pixels, width, fileName) => {
|
||||||
const png = new PNG({
|
const png = new PNG({
|
||||||
width,
|
width,
|
||||||
height: pixels.length / width
|
height: pixels.length / width
|
||||||
});
|
});
|
||||||
|
|
||||||
pixels.forEach((pixel, i) => {
|
pixels.forEach((pixel, i) => {
|
||||||
const x = i % width;
|
const x = i % width;
|
||||||
const y = (i - x) / width;
|
const y = (i - x) / width;
|
||||||
const idx = (width * y + x) << 2;
|
const idx = (width * y + x) << 2;
|
||||||
png.data[idx] = pixel.r;
|
png.data[idx] = pixel.r;
|
||||||
png.data[idx+1] = pixel.g;
|
png.data[idx+1] = pixel.g;
|
||||||
png.data[idx+2] = pixel.b;
|
png.data[idx+2] = pixel.b;
|
||||||
png.data[idx+3] = pixel.a;
|
png.data[idx+3] = pixel.a;
|
||||||
});
|
});
|
||||||
|
|
||||||
if(!fs.existsSync('out')) fs.mkdirSync('out');
|
if(!fs.existsSync('out')) fs.mkdirSync('out');
|
||||||
|
|
||||||
const out = PNG.sync.write(png);
|
const out = PNG.sync.write(png);
|
||||||
fs.writeFileSync(path.join('out', fileName), out);
|
fs.writeFileSync(path.join('out', fileName), out);
|
||||||
}
|
}
|
||||||
|
|
||||||
const imageIn = fileName => {
|
const imageIn = fileName => {
|
||||||
const data = fs.readFileSync(fileName);
|
const data = fs.readFileSync(fileName);
|
||||||
const png = PNG.sync.read(data);
|
const png = PNG.sync.read(data);
|
||||||
const pixels = [];
|
const pixels = [];
|
||||||
|
|
||||||
for(let y = 0; y < png.height; y++) {
|
for(let y = 0; y < png.height; y++) {
|
||||||
for (let x = 0; x < png.width; x++) {
|
for (let x = 0; x < png.width; x++) {
|
||||||
let idx = (png.width * y + x) << 2;
|
let idx = (png.width * y + x) << 2;
|
||||||
const r = png.data[idx];
|
const r = png.data[idx];
|
||||||
const g = png.data[idx+1];
|
const g = png.data[idx+1];
|
||||||
const b = png.data[idx+2];
|
const b = png.data[idx+2];
|
||||||
const a = png.data[idx+3];
|
const a = png.data[idx+3];
|
||||||
|
|
||||||
let pixel = { r, g, b, a };
|
let pixel = { r, g, b, a };
|
||||||
if(a === 0) {
|
if(a === 0) {
|
||||||
pixel = { ...WHITE };
|
pixel = { ...WHITE };
|
||||||
} else {
|
} else {
|
||||||
pixel.a = 255;
|
pixel.a = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
pixels.push(pixel);
|
pixels.push(pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { pixels, width: png.width, height: png.height };
|
return { pixels, width: png.width, height: png.height };
|
||||||
}
|
}
|
||||||
|
|
||||||
const tileFromPixel = (x, y, original) => {
|
const tileFromPixel = (x, y, original) => {
|
||||||
const byEightX = Math.floor(x / 8);
|
const byEightX = Math.floor(x / 8);
|
||||||
const byEightY = Math.floor(y / 8);
|
const byEightY = Math.floor(y / 8);
|
||||||
const byEightWidth = Math.floor(original.width / 8);
|
const byEightWidth = Math.floor(original.width / 8);
|
||||||
const byEightId = byEightX + (byEightY * byEightWidth);
|
const byEightId = byEightX + (byEightY * byEightWidth);
|
||||||
|
|
||||||
return { x: byEightX, y: byEightY, columns: byEightWidth, id: byEightId };
|
return { x: byEightX, y: byEightY, columns: byEightWidth, id: byEightId };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read Input File
|
// Read Input File
|
||||||
const original = imageIn('bruh.png');
|
const original = imageIn('bruh.png');
|
||||||
|
|
||||||
const columns = (original.width / TILE_WIDTH);
|
const columns = (original.width / TILE_WIDTH);
|
||||||
const rows = (original.height / TILE_HEIGHT);
|
const rows = (original.height / TILE_HEIGHT);
|
||||||
|
|
||||||
// Foreach pixel
|
// Foreach pixel
|
||||||
const palette = [];
|
const palette = [];
|
||||||
const paletteByEight = [];
|
const paletteByEight = [];
|
||||||
const withPaletteOverflows = [];
|
const withPaletteOverflows = [];
|
||||||
|
|
||||||
for(let y = 0; y < original.height; y++) {
|
for(let y = 0; y < original.height; y++) {
|
||||||
for(let x = 0; x < original.width; x++) {
|
for(let x = 0; x < original.width; x++) {
|
||||||
const id = x + (y * original.width);
|
const id = x + (y * original.width);
|
||||||
const pixel = original.pixels[id];
|
const pixel = original.pixels[id];
|
||||||
let errorPixel = { ...pixel };
|
let errorPixel = { ...pixel };
|
||||||
const tile = tileFromPixel(x, y, original);
|
const tile = tileFromPixel(x, y, original);
|
||||||
|
|
||||||
// Handle palettes
|
// Handle palettes
|
||||||
if(pixel.a != 0) {
|
if(pixel.a != 0) {
|
||||||
const pb8 = (paletteByEight[tile.id] = paletteByEight[tile.id] || []);
|
const pb8 = (paletteByEight[tile.id] = paletteByEight[tile.id] || []);
|
||||||
|
|
||||||
if(!pb8.some(p => pixelIsSame(pixel, p))) {
|
if(!pb8.some(p => pixelIsSame(pixel, p))) {
|
||||||
pb8.push(pixel);
|
pb8.push(pixel);
|
||||||
}
|
}
|
||||||
// Handle palette overflow
|
// Handle palette overflow
|
||||||
if(pb8.length > 4) errorPixel = { ...RED };
|
if(pb8.length > 4) errorPixel = { ...RED };
|
||||||
|
|
||||||
// Append to palette
|
// Append to palette
|
||||||
if(!palette.some(p => pixelIsSame(pixel, p))) palette.push(pixel);
|
if(!palette.some(p => pixelIsSame(pixel, p))) palette.push(pixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
withPaletteOverflows.push(errorPixel);
|
withPaletteOverflows.push(errorPixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the palette set image
|
// Generate the palette set image
|
||||||
const outPaletteByEight = [];
|
const outPaletteByEight = [];
|
||||||
let outByEightWidth = 1;
|
let outByEightWidth = 1;
|
||||||
paletteByEight.forEach((pal,y) => {
|
paletteByEight.forEach((pal,y) => {
|
||||||
pal.forEach((p,x) => {
|
pal.forEach((p,x) => {
|
||||||
outByEightWidth = Math.max(outByEightWidth, x+1);
|
outByEightWidth = Math.max(outByEightWidth, x+1);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
paletteByEight.forEach((pal,y) => {
|
paletteByEight.forEach((pal,y) => {
|
||||||
for(let x = 0; x < outByEightWidth; x++) {
|
for(let x = 0; x < outByEightWidth; x++) {
|
||||||
outPaletteByEight.push(x >= pal.length ? TRANSPARENT : pal[x]);
|
outPaletteByEight.push(x >= pal.length ? TRANSPARENT : pal[x]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Now determine for each TILE what palette to use.
|
// Now determine for each TILE what palette to use.
|
||||||
const paletteGroups = [];
|
const paletteGroups = [];
|
||||||
const gbVersion = [];
|
const gbVersion = [];
|
||||||
const paletteImage = [];
|
const paletteImage = [];
|
||||||
|
|
||||||
for(let y = 0; y < original.height; y++) {
|
for(let y = 0; y < original.height; y++) {
|
||||||
for(let x = 0; x < original.width; x++) {
|
for(let x = 0; x < original.width; x++) {
|
||||||
const id = x + (y * original.width);
|
const id = x + (y * original.width);
|
||||||
const pixel = original.pixels[id];
|
const pixel = original.pixels[id];
|
||||||
const tile = tileFromPixel(x, y, original);
|
const tile = tileFromPixel(x, y, original);
|
||||||
|
|
||||||
// Get the palette
|
// Get the palette
|
||||||
const paletteSet = paletteByEight[tile.id];
|
const paletteSet = paletteByEight[tile.id];
|
||||||
|
|
||||||
// Check for matching
|
// Check for matching
|
||||||
let palId = paletteGroups.findIndex(pg => {
|
let palId = paletteGroups.findIndex(pg => {
|
||||||
// Check for cases where one of the pallet group palettes may have
|
// Check for cases where one of the pallet group palettes may have
|
||||||
// less pixels than the current set we're checking, e.g. we do a tile that
|
// less pixels than the current set we're checking, e.g. we do a tile that
|
||||||
// has only two colors, then we iterate over a tile with 4 colors that has
|
// has only two colors, then we iterate over a tile with 4 colors that has
|
||||||
// two colors shared with that other tile. In that case we just add our
|
// two colors shared with that other tile. In that case we just add our
|
||||||
// two extra colors.
|
// two extra colors.
|
||||||
if(paletteSet.length > pg.length) {
|
if(paletteSet.length > pg.length) {
|
||||||
return pg.every(p => paletteSet.some(pss => pixelIsSame(pss, p)));
|
return pg.every(p => paletteSet.some(pss => pixelIsSame(pss, p)));
|
||||||
} else {
|
} else {
|
||||||
return paletteSet.every(p => pg.some(pgs => pixelIsSame(pgs, p)));
|
return paletteSet.every(p => pg.some(pgs => pixelIsSame(pgs, p)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(palId === -1) {
|
if(palId === -1) {
|
||||||
palId = paletteGroups.length;
|
palId = paletteGroups.length;
|
||||||
paletteGroups.push(paletteSet);
|
paletteGroups.push(paletteSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
const paletteGroupSet = paletteGroups[palId];
|
const paletteGroupSet = paletteGroups[palId];
|
||||||
|
|
||||||
// This is where we correct the missing pixels if we share that tileset from
|
// This is where we correct the missing pixels if we share that tileset from
|
||||||
// earlier
|
// earlier
|
||||||
paletteSet.forEach(ps => {
|
paletteSet.forEach(ps => {
|
||||||
const existing = paletteGroupSet.some(pgs => pixelIsSame(pgs, ps));
|
const existing = paletteGroupSet.some(pgs => pixelIsSame(pgs, ps));
|
||||||
if(existing) return;
|
if(existing) return;
|
||||||
paletteGroupSet.push(ps);
|
paletteGroupSet.push(ps);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort the paletteGroupSet...
|
// Sort the paletteGroupSet...
|
||||||
const pgsGetWeight = thing => {
|
const pgsGetWeight = thing => {
|
||||||
return thing.r + thing.g + thing.b;
|
return thing.r + thing.g + thing.b;
|
||||||
}
|
}
|
||||||
paletteGroupSet.sort((l,r) => {
|
paletteGroupSet.sort((l,r) => {
|
||||||
return pgsGetWeight(l) - pgsGetWeight(r);
|
return pgsGetWeight(l) - pgsGetWeight(r);
|
||||||
});
|
});
|
||||||
|
|
||||||
const examples = [
|
const examples = [
|
||||||
/* 0 */{ r: 0, g: 0, b: 0, a: 255 },
|
/* 0 */{ r: 0, g: 0, b: 0, a: 255 },
|
||||||
/* 1 */{ r: 255, g: 0, b: 0, a: 255 },
|
/* 1 */{ r: 255, g: 0, b: 0, a: 255 },
|
||||||
/* 2 */{ r: 0, g: 255, b: 0, a: 255 },
|
/* 2 */{ r: 0, g: 255, b: 0, a: 255 },
|
||||||
/* 3 */{ r: 0, g: 0, b: 255, a: 255 },
|
/* 3 */{ r: 0, g: 0, b: 255, a: 255 },
|
||||||
/* 4 */{ r: 255, g: 255, b: 0, a: 255 },
|
/* 4 */{ r: 255, g: 255, b: 0, a: 255 },
|
||||||
/* 5 */{ r: 255, g: 0, b: 255, a: 255 },
|
/* 5 */{ r: 255, g: 0, b: 255, a: 255 },
|
||||||
/* 6 */{ r: 0, g: 255, b: 255, a: 255 },
|
/* 6 */{ r: 0, g: 255, b: 255, a: 255 },
|
||||||
/* 7 */{ r: 255, g: 255, b: 255, a: 255 },
|
/* 7 */{ r: 255, g: 255, b: 255, a: 255 },
|
||||||
|
|
||||||
/* S */{ r: 100, g: 0, b: 0, a: 255 },
|
/* S */{ r: 100, g: 0, b: 0, a: 255 },
|
||||||
/* S */{ r: 0, g: 100, b: 0, a: 255 },
|
/* S */{ r: 0, g: 100, b: 0, a: 255 },
|
||||||
/* S */{ r: 0, g: 0, b: 100, a: 255 },
|
/* S */{ r: 0, g: 0, b: 100, a: 255 },
|
||||||
/* S */{ r: 100, g: 100, b: 0, a: 255 },
|
/* S */{ r: 100, g: 100, b: 0, a: 255 },
|
||||||
/* S */{ r: 0, g: 100, b: 100, a: 255 },
|
/* S */{ r: 0, g: 100, b: 100, a: 255 },
|
||||||
/* S */{ r: 100, g: 0, b: 100, a: 255 },
|
/* S */{ r: 100, g: 0, b: 100, a: 255 },
|
||||||
/* S */{ r: 100, g: 100, b: 100, a: 255 },
|
/* S */{ r: 100, g: 100, b: 100, a: 255 },
|
||||||
];
|
];
|
||||||
paletteImage.push(examples[palId]);
|
paletteImage.push(examples[palId]);
|
||||||
|
|
||||||
const pixelIndex = paletteGroupSet.findIndex(ps => pixelIsSame(ps, pixel));
|
const pixelIndex = paletteGroupSet.findIndex(ps => pixelIsSame(ps, pixel));
|
||||||
const nonColor = [
|
const nonColor = [
|
||||||
{ r: 8, g: 24, b: 32, a: 255 },
|
{ r: 8, g: 24, b: 32, a: 255 },
|
||||||
{ r: 52, g: 104, b: 86, a: 255 },
|
{ r: 52, g: 104, b: 86, a: 255 },
|
||||||
{ r: 136, g: 192, b: 112, a: 255 },
|
{ r: 136, g: 192, b: 112, a: 255 },
|
||||||
{ r: 224, g: 248, b: 208, a: 255 }
|
{ r: 224, g: 248, b: 208, a: 255 }
|
||||||
];
|
];
|
||||||
gbVersion.push(nonColor[pixelIndex % nonColor.length]);
|
gbVersion.push(nonColor[pixelIndex % nonColor.length]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('Found', paletteGroups.length, 'palettes');
|
console.log('Found', paletteGroups.length, 'palettes');
|
||||||
|
|
||||||
imageOut(original.pixels, original.width, 'original.png');
|
imageOut(original.pixels, original.width, 'original.png');
|
||||||
imageOut(withPaletteOverflows, original.width, 'errors.png');
|
imageOut(withPaletteOverflows, original.width, 'errors.png');
|
||||||
imageOut(palette, palette.length, 'palette.png');
|
imageOut(palette, palette.length, 'palette.png');
|
||||||
imageOut(outPaletteByEight, outByEightWidth, 'paletteByEight.png');
|
imageOut(outPaletteByEight, outByEightWidth, 'paletteByEight.png');
|
||||||
imageOut(paletteImage, original.width, 'palettes.png');
|
imageOut(paletteImage, original.width, 'palettes.png');
|
||||||
imageOut(gbVersion, original.width, 'gameboy.png');
|
imageOut(gbVersion, original.width, 'gameboy.png');
|
||||||
|
|
||||||
// Now generate the GB files
|
// Now generate the GB files
|
||||||
// let rearranged = [];
|
// let rearranged = [];
|
||||||
// let n = 0;
|
// let n = 0;
|
||||||
// for(let i = 0; i < columns * rows; i++) {
|
// for(let i = 0; i < columns * rows; i++) {
|
||||||
// const tileX = i % columns;
|
// const tileX = i % columns;
|
||||||
// const tileY = Math.floor(i / columns) % rows;
|
// const tileY = Math.floor(i / columns) % rows;
|
||||||
|
|
||||||
// for(let y = 0; y < TILE_HEIGHT; y++) {
|
// for(let y = 0; y < TILE_HEIGHT; y++) {
|
||||||
// for(let x = 0; x < TILE_WIDTH; x++) {
|
// for(let x = 0; x < TILE_WIDTH; x++) {
|
||||||
// const px = (tileX * TILE_WIDTH) + x;
|
// const px = (tileX * TILE_WIDTH) + x;
|
||||||
// const py = (tileY * TILE_HEIGHT) + y;
|
// const py = (tileY * TILE_HEIGHT) + y;
|
||||||
// const pi = (py * png.width) + px;
|
// const pi = (py * png.width) + px;
|
||||||
// rearranged[n++] = original.pixels[pi];
|
// rearranged[n++] = original.pixels[pi];
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // Now turn into a tileset
|
// // Now turn into a tileset
|
||||||
// const bits = [];
|
// const bits = [];
|
||||||
// for(let i = 0; i < rearranged.length; i += TILE_WIDTH) {
|
// for(let i = 0; i < rearranged.length; i += TILE_WIDTH) {
|
||||||
// let lowBits = 0x00;
|
// let lowBits = 0x00;
|
||||||
// let highBits = 0x00;
|
// let highBits = 0x00;
|
||||||
// for(let j = 0; j < TILE_WIDTH; j++) {
|
// for(let j = 0; j < TILE_WIDTH; j++) {
|
||||||
// const pixel = rearranged[i + j];
|
// const pixel = rearranged[i + j];
|
||||||
// lowBits = lowBits | ((pixel & 0x01) << (7-j));
|
// lowBits = lowBits | ((pixel & 0x01) << (7-j));
|
||||||
// highBits = highBits | ((pixel & 0x02) >> 1 << (7-j));
|
// highBits = highBits | ((pixel & 0x02) >> 1 << (7-j));
|
||||||
// }
|
// }
|
||||||
// bits.push(lowBits, highBits);
|
// bits.push(lowBits, highBits);
|
||||||
// }
|
// }
|
@@ -1,93 +1,101 @@
|
|||||||
const PNG = require('pngjs').PNG;
|
const PNG = require('pngjs').PNG;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { arrayToString } = require('./util');
|
const { arrayToString } = require('./util');
|
||||||
const {
|
const {
|
||||||
TILE_WIDTH,
|
TILE_WIDTH,
|
||||||
TILE_HEIGHT
|
TILE_HEIGHT
|
||||||
} = require('./common');
|
} = require('./common');
|
||||||
|
|
||||||
|
|
||||||
const getPixelValue = (pixel) => {
|
const getPixelValue = (pixel) => {
|
||||||
if(pixel.g === 188) return 0;
|
if(pixel.g === 188) return 0;
|
||||||
if(pixel.g === 172) return 1;
|
if(pixel.g === 172) return 1;
|
||||||
if(pixel.g === 98) return 2;
|
if(pixel.g === 98 || pixel.g === 145) return 2;
|
||||||
if(pixel.g === 56) return 3;
|
if(pixel.g === 56) return 3;
|
||||||
throw new Error();
|
if(pixel.a === 0) return 0;
|
||||||
}
|
throw new Error();
|
||||||
|
}
|
||||||
const png2gb = (fileIn, dirOut, name) => {
|
|
||||||
const data = fs.readFileSync(fileIn);
|
const png2gb = (fileIn, dirOut, name) => {
|
||||||
const png = PNG.sync.read(data);
|
const data = fs.readFileSync(fileIn);
|
||||||
|
const png = PNG.sync.read(data);
|
||||||
// Convert PNG pixels into 0x00-0x03
|
|
||||||
const pixels = [];
|
// Convert PNG pixels into 0x00-0x03
|
||||||
for(let y = 0; y < png.height; y++) {
|
const pixels = [];
|
||||||
for(let x = 0; x < png.width; x++) {
|
for(let y = 0; y < png.height; y++) {
|
||||||
const id = x + (y * png.width);
|
for(let x = 0; x < png.width; x++) {
|
||||||
const idx = id << 2;
|
const id = x + (y * png.width);
|
||||||
const r = png.data[idx];
|
const idx = id << 2;
|
||||||
const g = png.data[idx+1];
|
const r = png.data[idx];
|
||||||
const b = png.data[idx+2];
|
const g = png.data[idx+1];
|
||||||
const value = getPixelValue({ r, g, b });
|
const b = png.data[idx+2];
|
||||||
pixels.push(value);
|
const a = png.data[idx+3];
|
||||||
}
|
const pixel = { r, g, b, a };
|
||||||
}
|
try {
|
||||||
|
const value = getPixelValue(pixel);
|
||||||
// Now take these raw pixels and extract the tiles themselves
|
pixels.push(value);
|
||||||
let rearranged = [];
|
} catch(e) {
|
||||||
const columns = (png.width / TILE_WIDTH);
|
console.error(`Failed to get color for `, x, y, idx, fileIn, pixel);
|
||||||
const rows = (png.height / TILE_HEIGHT);
|
throw e;
|
||||||
let n = 0;
|
}
|
||||||
for(let i = 0; i < columns * rows; i++) {
|
}
|
||||||
const tileX = i % columns;
|
}
|
||||||
const tileY = Math.floor(i / columns) % rows;
|
|
||||||
|
// Now take these raw pixels and extract the tiles themselves
|
||||||
for(let y = 0; y < TILE_HEIGHT; y++) {
|
let rearranged = [];
|
||||||
for(let x = 0; x < TILE_WIDTH; x++) {
|
const columns = (png.width / TILE_WIDTH);
|
||||||
const px = (tileX * TILE_WIDTH) + x;
|
const rows = (png.height / TILE_HEIGHT);
|
||||||
const py = (tileY * TILE_HEIGHT) + y;
|
let n = 0;
|
||||||
const pi = (py * png.width) + px;
|
for(let i = 0; i < columns * rows; i++) {
|
||||||
rearranged[n++] = pixels[pi];
|
const tileX = i % columns;
|
||||||
}
|
const tileY = Math.floor(i / columns) % rows;
|
||||||
}
|
|
||||||
}
|
for(let y = 0; y < TILE_HEIGHT; y++) {
|
||||||
|
for(let x = 0; x < TILE_WIDTH; x++) {
|
||||||
// Now turn into a tileset
|
const px = (tileX * TILE_WIDTH) + x;
|
||||||
const bits = [];
|
const py = (tileY * TILE_HEIGHT) + y;
|
||||||
for(let i = 0; i < rearranged.length; i += TILE_WIDTH) {
|
const pi = (py * png.width) + px;
|
||||||
let lowBits = 0x00;
|
rearranged[n++] = pixels[pi];
|
||||||
let highBits = 0x00;
|
}
|
||||||
for(let j = 0; j < TILE_WIDTH; j++) {
|
}
|
||||||
const pixel = rearranged[i + j];
|
}
|
||||||
lowBits = lowBits | ((pixel & 0x01) << (7-j));
|
|
||||||
highBits = highBits | ((pixel & 0x02) >> 1 << (7-j));
|
// Now turn into a tileset
|
||||||
}
|
const bits = [];
|
||||||
bits.push(lowBits, highBits);
|
for(let i = 0; i < rearranged.length; i += TILE_WIDTH) {
|
||||||
}
|
let lowBits = 0x00;
|
||||||
|
let highBits = 0x00;
|
||||||
let outH = '';
|
for(let j = 0; j < TILE_WIDTH; j++) {
|
||||||
outH += `#include "libs.h"\n\n`
|
const pixel = rearranged[i + j];
|
||||||
outH += `#define ${name}_IMAGE_WIDTH ${png.width}\n`;
|
lowBits = lowBits | ((pixel & 0x01) << (7-j));
|
||||||
outH += `#define ${name}_IMAGE_HEIGHT ${png.height}\n`;
|
highBits = highBits | ((pixel & 0x02) >> 1 << (7-j));
|
||||||
outH += `#define ${name}_IMAGE_COLUMNS ${png.width / TILE_WIDTH}\n`;
|
}
|
||||||
outH += `#define ${name}_IMAGE_ROWS ${png.height / TILE_HEIGHT}\n`;
|
bits.push(lowBits, highBits);
|
||||||
outH += `#define ${name}_IMAGE_TILES ${columns * rows}\n`;
|
}
|
||||||
outH += `extern const uint8_t ${name}_IMAGE[];`;
|
|
||||||
|
let outH = '';
|
||||||
let outC = `#include "${name}.h"\n`;
|
outH += `#include "libs.h"\n\n`
|
||||||
outC += `\nconst uint8_t ${name}_IMAGE[] = {\n${arrayToString(bits)}};`;
|
outH += `#define ${name}_IMAGE_WIDTH ${png.width}\n`;
|
||||||
|
outH += `#define ${name}_IMAGE_HEIGHT ${png.height}\n`;
|
||||||
const fileH = path.join(dirOut, name + '.h');
|
outH += `#define ${name}_IMAGE_COLUMNS ${png.width / TILE_WIDTH}\n`;
|
||||||
const fileC = path.join(dirOut, name + '.c');
|
outH += `#define ${name}_IMAGE_ROWS ${png.height / TILE_HEIGHT}\n`;
|
||||||
|
outH += `#define ${name}_IMAGE_TILES ${columns * rows}\n`;
|
||||||
fs.writeFileSync(fileH, outH);
|
outH += `extern const uint8_t ${name}_IMAGE[];`;
|
||||||
fs.writeFileSync(fileC, outC);
|
|
||||||
return { fileH, fileC };
|
let outC = `#include "${name}.h"\n`;
|
||||||
}
|
outC += `\nconst uint8_t ${name}_IMAGE[] = {\n${arrayToString(bits)}};`;
|
||||||
|
|
||||||
module.exports = {
|
const fileH = path.join(dirOut, name + '.h');
|
||||||
png2gb
|
const fileC = path.join(dirOut, name + '.c');
|
||||||
}
|
|
||||||
|
fs.writeFileSync(fileH, outH);
|
||||||
|
fs.writeFileSync(fileC, outC);
|
||||||
|
return { fileH, fileC };
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
png2gb
|
||||||
|
}
|
||||||
|
|
||||||
// convert('images/sm.png', 'out.c', 'PENNY');
|
// convert('images/sm.png', 'out.c', 'PENNY');
|
@@ -1,32 +1,32 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { arrayToString } = require('./util');
|
const { arrayToString } = require('./util');
|
||||||
|
|
||||||
const FONT_CHARACTER_FIRST = 33;
|
const FONT_CHARACTER_FIRST = 33;
|
||||||
const FONT_DATA_POSITION = 4;
|
const FONT_DATA_POSITION = 4;
|
||||||
|
|
||||||
const getCodeFrom = l => {
|
const getCodeFrom = l => {
|
||||||
const cc = l.charCodeAt(0)
|
const cc = l.charCodeAt(0)
|
||||||
if(l == '\n' || l == ' ') return cc;
|
if(l == '\n' || l == ' ') return cc;
|
||||||
return cc - FONT_CHARACTER_FIRST + FONT_DATA_POSITION
|
return cc - FONT_CHARACTER_FIRST + FONT_DATA_POSITION
|
||||||
}
|
}
|
||||||
|
|
||||||
const string2gb = (string, name) => {
|
const string2gb = (string, name) => {
|
||||||
const letters = [];
|
const letters = [];
|
||||||
for(let i = 0; i < string.length; i++) {
|
for(let i = 0; i < string.length; i++) {
|
||||||
letters.push(getCodeFrom(string[i]));
|
letters.push(getCodeFrom(string[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
let dataH = `#define STR_${name}_LENGTH ${string.length}\n`;
|
let dataH = `#define STR_${name}_LENGTH ${string.length}\n`;
|
||||||
dataH += `extern const uint8_t STR_${name}_DATA[];`;
|
dataH += `extern const uint8_t STR_${name}_DATA[];`;
|
||||||
|
|
||||||
let dataC = `const uint8_t STR_${name}_DATA[] = {\n`;
|
let dataC = `const uint8_t STR_${name}_DATA[] = {\n`;
|
||||||
dataC += arrayToString(letters);
|
dataC += arrayToString(letters);
|
||||||
dataC += `\n};`;
|
dataC += `\n};`;
|
||||||
|
|
||||||
return { dataH, dataC };
|
return { dataH, dataC };
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
string2gb
|
string2gb
|
||||||
};
|
};
|
@@ -1,21 +1,21 @@
|
|||||||
const arrayToString = arr => {
|
const arrayToString = arr => {
|
||||||
const b = arr.map(n => {
|
const b = arr.map(n => {
|
||||||
return '0x' + (n.toString(16).padStart(2, '0').toUpperCase());
|
return '0x' + (n.toString(16).padStart(2, '0').toUpperCase());
|
||||||
});
|
});
|
||||||
|
|
||||||
let str = '';
|
let str = '';
|
||||||
for(let i = 0; i < b.length; i += 16) {
|
for(let i = 0; i < b.length; i += 16) {
|
||||||
str += ' ';
|
str += ' ';
|
||||||
for(let x = i; x < Math.min(i+16, b.length); x++) {
|
for(let x = i; x < Math.min(i+16, b.length); x++) {
|
||||||
str += b[x];
|
str += b[x];
|
||||||
str += ',';
|
str += ',';
|
||||||
}
|
}
|
||||||
str += '\n';
|
str += '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
arrayToString
|
arrayToString
|
||||||
}
|
}
|
@@ -1,69 +1,69 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fade.h"
|
#include "fade.h"
|
||||||
|
|
||||||
inline void conversationFadeToBlack() {
|
inline void conversationFadeToBlack() {
|
||||||
TIME_FUTURE = TIME_CURRENT;
|
TIME_FUTURE = TIME_CURRENT;
|
||||||
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_FADE_TO_BLACK;
|
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_FADE_TO_BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void conversationFadeFromBlack() {
|
inline void conversationFadeFromBlack() {
|
||||||
TIME_FUTURE = TIME_CURRENT;
|
TIME_FUTURE = TIME_CURRENT;
|
||||||
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_FADE_FROM_BLACK;
|
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_FADE_FROM_BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void conversationFadeToWhite() {
|
inline void conversationFadeToWhite() {
|
||||||
TIME_FUTURE = TIME_CURRENT;
|
TIME_FUTURE = TIME_CURRENT;
|
||||||
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_FADE_TO_WHITE;
|
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_FADE_TO_WHITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void conversationFadeFromWhite() {
|
inline void conversationFadeFromWhite() {
|
||||||
TIME_FUTURE = TIME_CURRENT;
|
TIME_FUTURE = TIME_CURRENT;
|
||||||
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_FADE_FROM_WHITE;
|
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_FADE_FROM_WHITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void conversationFadeUpdate() {
|
void conversationFadeUpdate() {
|
||||||
uint16_t diff;
|
uint16_t diff;
|
||||||
|
|
||||||
if(
|
if(
|
||||||
TIME_FUTURE_TYPE < TIME_FUTURE_TYPE_FADE_TO_BLACK ||
|
TIME_FUTURE_TYPE < TIME_FUTURE_TYPE_FADE_TO_BLACK ||
|
||||||
TIME_FUTURE_TYPE > TIME_FUTURE_TYPE_FADE_FROM_WHITE
|
TIME_FUTURE_TYPE > TIME_FUTURE_TYPE_FADE_FROM_WHITE
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
diff = TIME_CURRENT - TIME_FUTURE;
|
diff = TIME_CURRENT - TIME_FUTURE;
|
||||||
|
|
||||||
// Now we work out the steps. Time is measured in steps which are made of
|
// Now we work out the steps. Time is measured in steps which are made of
|
||||||
// parts of a second. This code assumes that the screen STARTS at the correct
|
// parts of a second. This code assumes that the screen STARTS at the correct
|
||||||
// shade.
|
// shade.
|
||||||
if(diff == FADE_STEP) {
|
if(diff == FADE_STEP) {
|
||||||
// First step
|
// First step
|
||||||
BGP_REG = (
|
BGP_REG = (
|
||||||
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_BLACK ? COMMON_SHADE_DARK :
|
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_BLACK ? TILESET_SHADE_DARK :
|
||||||
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_WHITE ? COMMON_SHADE_BRIGHT :
|
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_WHITE ? TILESET_SHADE_BRIGHT :
|
||||||
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_FROM_BLACK ? COMMON_SHADE_DARKER :
|
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_FROM_BLACK ? TILESET_SHADE_DARKER :
|
||||||
COMMON_SHADE_BRIGHTER
|
TILESET_SHADE_BRIGHTER
|
||||||
);
|
);
|
||||||
} else if(diff == FADE_STEP * 2) {
|
} else if(diff == FADE_STEP * 2) {
|
||||||
// Second step
|
// Second step
|
||||||
BGP_REG = (
|
BGP_REG = (
|
||||||
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_BLACK ? COMMON_SHADE_DARKER :
|
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_BLACK ? TILESET_SHADE_DARKER :
|
||||||
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_WHITE ? COMMON_SHADE_BRIGHTER :
|
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_WHITE ? TILESET_SHADE_BRIGHTER :
|
||||||
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_FROM_BLACK ? COMMON_SHADE_DARK :
|
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_FROM_BLACK ? TILESET_SHADE_DARK :
|
||||||
COMMON_SHADE_BRIGHT
|
TILESET_SHADE_BRIGHT
|
||||||
);
|
);
|
||||||
} else if(diff == FADE_STEP * 3) {
|
} else if(diff == FADE_STEP * 3) {
|
||||||
// Third step
|
// Third step
|
||||||
BGP_REG = (
|
BGP_REG = (
|
||||||
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_BLACK ? COMMON_SHADE_BLACK :
|
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_BLACK ? TILESET_SHADE_BLACK :
|
||||||
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_WHITE ? COMMON_SHADE_WHITE :
|
TIME_FUTURE_TYPE == TIME_FUTURE_TYPE_FADE_TO_WHITE ? TILESET_SHADE_WHITE :
|
||||||
COMMON_SHADE_NORMAL
|
TILESET_SHADE_NORMAL
|
||||||
);
|
);
|
||||||
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_NULL;
|
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_NULL;
|
||||||
conversationQueueNext();
|
conversationQueueNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,21 +1,21 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../libs.h"
|
#include "../libs.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "pause.h"
|
#include "pause.h"
|
||||||
#include "../display/common.h"
|
#include "../sprites/spritetileset.h"
|
||||||
|
|
||||||
// This is how many frames it takes to change each shade.
|
// This is how many frames it takes to change each shade.
|
||||||
#define FADE_STEP 20
|
#define FADE_STEP 20
|
||||||
|
|
||||||
inline void conversationFadeToBlack();
|
inline void conversationFadeToBlack();
|
||||||
inline void conversationFadeFromBlack();
|
inline void conversationFadeFromBlack();
|
||||||
inline void conversationFadeToWhite();
|
inline void conversationFadeToWhite();
|
||||||
inline void conversationFadeFromWhite();
|
inline void conversationFadeFromWhite();
|
||||||
void conversationFadeUpdate();
|
void conversationFadeUpdate();
|
@@ -1,40 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2022 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "frame.h"
|
|
||||||
|
|
||||||
inline void frameBuffer(
|
|
||||||
uint8_t buffer[],
|
|
||||||
uint8_t bufferWidth, uint8_t bufferHeight,
|
|
||||||
uint8_t fill
|
|
||||||
) {
|
|
||||||
uint8_t i, j, max;
|
|
||||||
max = bufferWidth * bufferHeight;
|
|
||||||
|
|
||||||
// Corners
|
|
||||||
buffer[0] = BORDER_TILE_TOP_LEFT;
|
|
||||||
buffer[bufferWidth-1] = BORDER_TILE_TOP_RIGHT;
|
|
||||||
buffer[max-1] = BORDER_TILE_BOTTOM_RIGHT;
|
|
||||||
buffer[max-bufferWidth] = BORDER_TILE_BOTTOM_LEFT;
|
|
||||||
|
|
||||||
// Edges
|
|
||||||
for(i = 1; i < bufferWidth-1; i++) {
|
|
||||||
buffer[i] = BORDER_TILE_TOP_CENTER;
|
|
||||||
buffer[max - 1 - i] = BORDER_TILE_BOTTOM_CENTER;
|
|
||||||
}
|
|
||||||
for(i = 1; i < bufferHeight - 1; i++) {
|
|
||||||
buffer[bufferWidth * i] = BORDER_TILE_CENTER_LEFT;
|
|
||||||
buffer[bufferWidth * (i+1) - 1] = BORDER_TILE_CENTER_RIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inner
|
|
||||||
for(j = 1; j < bufferHeight-1; j++) {
|
|
||||||
for(i = 1; i < bufferWidth-1; i++) {
|
|
||||||
buffer[i + (j * bufferWidth)] = fill;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,28 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2022 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "../libs.h"
|
|
||||||
#include "../util.h"
|
|
||||||
#include "../display/common.h"
|
|
||||||
#include "../display/tilemap.h"
|
|
||||||
|
|
||||||
#define BORDER_TILE_TOP_LEFT BORDER_DATA_POSITION
|
|
||||||
#define BORDER_TILE_TOP_CENTER BORDER_TILE_TOP_LEFT + 1
|
|
||||||
#define BORDER_TILE_TOP_RIGHT BORDER_TILE_TOP_CENTER + 1
|
|
||||||
#define BORDER_TILE_CENTER_LEFT BORDER_TILE_TOP_RIGHT + 1
|
|
||||||
#define BORDER_TILE_CENTER BORDER_TILE_CENTER_LEFT + 1
|
|
||||||
#define BORDER_TILE_CENTER_RIGHT BORDER_TILE_CENTER + 1
|
|
||||||
#define BORDER_TILE_BOTTOM_LEFT BORDER_TILE_CENTER_RIGHT + 1
|
|
||||||
#define BORDER_TILE_BOTTOM_CENTER BORDER_TILE_BOTTOM_LEFT + 1
|
|
||||||
#define BORDER_TILE_BOTTOM_RIGHT BORDER_TILE_BOTTOM_CENTER + 1
|
|
||||||
|
|
||||||
inline void frameBuffer(
|
|
||||||
uint8_t buffer[],
|
|
||||||
uint8_t bufferWidth, uint8_t bufferHeight,
|
|
||||||
uint8_t fill
|
|
||||||
);
|
|
@@ -1,22 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pause.h"
|
#include "pause.h"
|
||||||
|
|
||||||
inline void conversationPause(uint16_t duration) {
|
inline void conversationPause(uint16_t duration) {
|
||||||
TIME_FUTURE = TIME_CURRENT + (duration * TIME_PER_SECOND);
|
TIME_FUTURE = TIME_CURRENT + (duration * TIME_PER_SECOND);
|
||||||
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_PAUSE;
|
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_PAUSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void conversationPauseUpdate() {
|
inline void conversationPauseUpdate() {
|
||||||
if(TIME_FUTURE_TYPE != TIME_FUTURE_TYPE_PAUSE || TIME_CURRENT != TIME_FUTURE) {
|
if(TIME_FUTURE_TYPE != TIME_FUTURE_TYPE_PAUSE || TIME_CURRENT != TIME_FUTURE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_NULL;
|
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_NULL;
|
||||||
conversationQueueNext();
|
conversationQueueNext();
|
||||||
}
|
}
|
@@ -1,14 +1,14 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../libs.h"
|
#include "../libs.h"
|
||||||
#include "../time.h"
|
#include "../time.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
inline void conversationPause(uint16_t duration);
|
inline void conversationPause(uint16_t duration);
|
||||||
inline void conversationPauseUpdate();
|
inline void conversationPauseUpdate();
|
@@ -1,87 +1,87 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "questionbox.h"
|
#include "questionbox.h"
|
||||||
|
|
||||||
uint8_t QUESTION_BOX_OPTION_COUNT;
|
uint8_t QUESTION_BOX_OPTION_COUNT;
|
||||||
uint8_t QUESTION_BOX_OPTION_CURRENT;
|
uint8_t QUESTION_BOX_OPTION_CURRENT;
|
||||||
|
|
||||||
void questionBoxSetOptions(char *title, char **options, uint8_t count) {
|
void questionBoxSetOptions(char *title, char **options, uint8_t count) {
|
||||||
uint8_t i, j;
|
uint8_t i, j;
|
||||||
char buffer[TEXTBOX_CHARS_MAX + 1];
|
char buffer[TEXTBOX_CHARS_MAX + 1];
|
||||||
char spaces[QUESTION_BOX_QUESTION_SPACES];
|
char spaces[QUESTION_BOX_QUESTION_SPACES];
|
||||||
sprintf(buffer, title);
|
sprintf(buffer, title);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
QUESTION_BOX_OPTION_CURRENT = 0;
|
QUESTION_BOX_OPTION_CURRENT = 0;
|
||||||
QUESTION_BOX_OPTION_COUNT = count;
|
QUESTION_BOX_OPTION_COUNT = count;
|
||||||
|
|
||||||
for(i = 0; i < QUESTION_BOX_QUESTION_SPACES; i++) {
|
for(i = 0; i < QUESTION_BOX_QUESTION_SPACES; i++) {
|
||||||
spaces[i] = ' ';
|
spaces[i] = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each row...
|
// For each row...
|
||||||
for(i = 0; i < count; i++) {
|
for(i = 0; i < count; i++) {
|
||||||
if((i & 1) == 0) {
|
if((i & 1) == 0) {
|
||||||
j = strlen(options[i]);
|
j = strlen(options[i]);
|
||||||
sprintf(buffer, "%s\n %s", buffer, options[i]);
|
sprintf(buffer, "%s\n %s", buffer, options[i]);
|
||||||
} else {
|
} else {
|
||||||
j = QUESTION_BOX_QUESTION_SPACES - j;
|
j = QUESTION_BOX_QUESTION_SPACES - j;
|
||||||
spaces[j + 1] = '\0';
|
spaces[j + 1] = '\0';
|
||||||
sprintf(buffer, "%s%s%s", buffer, spaces, options[i]);
|
sprintf(buffer, "%s%s%s", buffer, spaces, options[i]);
|
||||||
spaces[j + 1] = ' ';
|
spaces[j + 1] = ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
conversationTextboxSetText(buffer);
|
conversationTextboxSetText(buffer);
|
||||||
|
|
||||||
// Modify the textbox state
|
// Modify the textbox state
|
||||||
TEXTBOX_STATE |= TEXTBOX_STATE_IS_QUESTION;
|
TEXTBOX_STATE |= TEXTBOX_STATE_IS_QUESTION;
|
||||||
|
|
||||||
// Repurpose old array and draw arrow
|
// Repurpose old array and draw arrow
|
||||||
spaces[0] = QUESTION_BOX_CURSOR - TEXTBOX_FONT_START + FONT_DATA_POSITION;
|
spaces[0] = spriteFontTileFromChar(QUESTION_BOX_CURSOR);
|
||||||
set_bkg_tiles(0x01, TEXTBOX_WIN_Y + 0x02, 1, 1, spaces);
|
set_bkg_tiles(0x01, TEXTBOX_WIN_Y + 0x02, 1, 1, spaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void questionBoxUpdate() {
|
inline void questionBoxUpdate() {
|
||||||
uint8_t tiles[1];
|
uint8_t tiles[1];
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
if((TEXTBOX_STATE & (TEXTBOX_STATE_VISIBLE|TEXTBOX_STATE_IS_QUESTION)) == 0) return;
|
if((TEXTBOX_STATE & (TEXTBOX_STATE_VISIBLE|TEXTBOX_STATE_IS_QUESTION)) == 0) return;
|
||||||
|
|
||||||
// Detect input
|
// Detect input
|
||||||
if(INPUT_PRESSED & J_RIGHT) {
|
if(INPUT_PRESSED & J_RIGHT) {
|
||||||
QUESTION_BOX_OPTION_CURRENT++;
|
QUESTION_BOX_OPTION_CURRENT++;
|
||||||
} else if(INPUT_PRESSED & J_LEFT) {
|
} else if(INPUT_PRESSED & J_LEFT) {
|
||||||
QUESTION_BOX_OPTION_CURRENT--;
|
QUESTION_BOX_OPTION_CURRENT--;
|
||||||
} else if(INPUT_PRESSED & J_UP) {
|
} else if(INPUT_PRESSED & J_UP) {
|
||||||
QUESTION_BOX_OPTION_CURRENT -= 2;
|
QUESTION_BOX_OPTION_CURRENT -= 2;
|
||||||
} else if(INPUT_PRESSED & J_DOWN) {
|
} else if(INPUT_PRESSED & J_DOWN) {
|
||||||
QUESTION_BOX_OPTION_CURRENT += 2;
|
QUESTION_BOX_OPTION_CURRENT += 2;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bound.
|
// Bound.
|
||||||
QUESTION_BOX_OPTION_CURRENT = QUESTION_BOX_OPTION_CURRENT % QUESTION_BOX_OPTION_COUNT;
|
QUESTION_BOX_OPTION_CURRENT = QUESTION_BOX_OPTION_CURRENT % QUESTION_BOX_OPTION_COUNT;
|
||||||
|
|
||||||
// Decide where to render arrow
|
// Decide where to render arrow
|
||||||
for(i = 0; i < QUESTION_BOX_OPTION_COUNT; i++) {
|
for(i = 0; i < QUESTION_BOX_OPTION_COUNT; i++) {
|
||||||
if(i == QUESTION_BOX_OPTION_CURRENT) {
|
if(i == QUESTION_BOX_OPTION_CURRENT) {
|
||||||
tiles[0] = QUESTION_BOX_CURSOR - TEXTBOX_FONT_START + FONT_DATA_POSITION;
|
tiles[0] = spriteFontTileFromChar(QUESTION_BOX_CURSOR);
|
||||||
} else {
|
} else {
|
||||||
tiles[0] = ' ' - TEXTBOX_FONT_START + FONT_DATA_POSITION;
|
tiles[0] = spriteFontTileFromChar(' ');
|
||||||
}
|
}
|
||||||
set_bkg_tiles(
|
set_bkg_tiles(
|
||||||
0x01 + ((i % 0x02) * QUESTION_BOX_QUESTION_SPACES),
|
0x01 + ((i % 0x02) * QUESTION_BOX_QUESTION_SPACES),
|
||||||
TEXTBOX_WIN_Y + 0x02 + (i / 0x02),
|
TEXTBOX_WIN_Y + 0x02 + (i / 0x02),
|
||||||
1, 1,
|
1, 1,
|
||||||
tiles
|
tiles
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -1,26 +1,26 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../libs.h"
|
#include "../libs.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
#include "../input.h"
|
#include "../input.h"
|
||||||
#include "../display/common.h"
|
#include "../sprites/spritefont.h"
|
||||||
#include "../display/tilemap.h"
|
#include "../sprites/spriteborder.h"
|
||||||
#include "frame.h"
|
#include "../sprites/spritetileset.h"
|
||||||
#include "textbox.h"
|
#include "textbox.h"
|
||||||
|
|
||||||
#define QUESTION_BOX_OPTIONS_MAX ((TEXTBOX_CHAR_ROWS-1)*2)
|
#define QUESTION_BOX_OPTIONS_MAX ((TEXTBOX_CHAR_ROWS-1)*2)
|
||||||
#define QUESTION_BOX_CURSOR '>'
|
#define QUESTION_BOX_CURSOR '>'
|
||||||
#define QUESTION_BOX_QUESTION_SPACES 9
|
#define QUESTION_BOX_QUESTION_SPACES 9
|
||||||
|
|
||||||
extern uint8_t QUESTION_BOX_OPTION_COUNT;
|
extern uint8_t QUESTION_BOX_OPTION_COUNT;
|
||||||
extern uint8_t QUESTION_BOX_OPTION_CURRENT;
|
extern uint8_t QUESTION_BOX_OPTION_CURRENT;
|
||||||
|
|
||||||
void questionBoxSetOptions(char *title, char **options, uint8_t count);
|
void questionBoxSetOptions(char *title, char **options, uint8_t count);
|
||||||
|
|
||||||
inline void questionBoxUpdate();
|
inline void questionBoxUpdate();
|
@@ -1,315 +1,315 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "pause.h"
|
#include "pause.h"
|
||||||
#include "textbox.h"
|
#include "textbox.h"
|
||||||
#include "fade.h"
|
#include "fade.h"
|
||||||
#include "../poker/poker.h"
|
#include "../poker/poker.h"
|
||||||
|
|
||||||
uint16_t QUEUE_ITEM;
|
uint16_t QUEUE_ITEM;
|
||||||
|
|
||||||
void conversationQueueDebug() {
|
void conversationQueueDebug() {
|
||||||
conversationTextboxSetText(STR_ERROR);
|
conversationTextboxSetText(STR_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void conversationQueueBegin() {
|
void conversationQueueBegin() {
|
||||||
QUEUE_ITEM = QUEUE_TAKE_BLINDS;
|
QUEUE_ITEM = QUEUE_TAKE_BLINDS;
|
||||||
conversationTextboxSetText(STR_POKER_GAME_START);
|
conversationTextboxSetText(STR_POKER_GAME_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
void conversationQueueTakeBlinds() {
|
void conversationQueueTakeBlinds() {
|
||||||
QUEUE_ITEM = QUEUE_DEAL_CARDS;
|
QUEUE_ITEM = QUEUE_DEAL_CARDS;
|
||||||
conversationTextboxSetText(STR_POKER_GAME_TAKING_BLINDS);
|
conversationTextboxSetText(STR_POKER_GAME_TAKING_BLINDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void conversationQueueDealCards() {
|
void conversationQueueDealCards() {
|
||||||
QUEUE_ITEM = QUEUE_BEGIN_BETTING;
|
QUEUE_ITEM = QUEUE_BEGIN_BETTING;
|
||||||
conversationTextboxSetText(STR_POKER_GAME_CARDS_DEALT);
|
conversationTextboxSetText(STR_POKER_GAME_CARDS_DEALT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void conversationQueueBeginBetting() {
|
void conversationQueueBeginBetting() {
|
||||||
pokerturn_t turn;
|
pokerturn_t turn;
|
||||||
turn.chips = 0;
|
turn.chips = 0;
|
||||||
// Begin the betting process. First we need to decide if the player or the
|
// Begin the betting process. First we need to decide if the player or the
|
||||||
// AI is betting, then based on that we decide what to do next.
|
// AI is betting, then based on that we decide what to do next.
|
||||||
|
|
||||||
// TODO: Actually bet.
|
// TODO: Actually bet.
|
||||||
if(POKER_PLAYER_BETTER == POKER_HUMAN_INDEX) {
|
if(POKER_PLAYER_BETTER == POKER_HUMAN_INDEX) {
|
||||||
// This is the human player.
|
// This is the human player.
|
||||||
BGB_MESSAGE("Player folding.");
|
BGB_MESSAGE("Player folding.");
|
||||||
conversationTextboxSetText(STR_DEBUG_PLAYER);
|
conversationTextboxSetText(STR_DEBUG_PLAYER);
|
||||||
POKER_PLAYERS[POKER_PLAYER_BETTER].state |= POKER_PLAYER_STATE_FOLDED;
|
POKER_PLAYERS[POKER_PLAYER_BETTER].state |= POKER_PLAYER_STATE_FOLDED;
|
||||||
} else {
|
} else {
|
||||||
// This is an AI player, get their turn.
|
// This is an AI player, get their turn.
|
||||||
BGB_MESSAGE("AI turn to bet");
|
BGB_MESSAGE("AI turn to bet");
|
||||||
pokerAi(POKER_PLAYER_BETTER, &turn);
|
pokerAi(POKER_PLAYER_BETTER, &turn);
|
||||||
BGB_printf("AI Decided to %u, with %u chips and %u confidence, bluffin: %u", turn.type, turn.chips, turn.confidence, turn.bluff);
|
BGB_printf("AI Decided to %u, with %u chips and %u confidence, bluffin: %u", turn.type, turn.chips, turn.confidence, turn.bluff);
|
||||||
|
|
||||||
switch(turn.type) {
|
switch(turn.type) {
|
||||||
case POKER_TURN_TYPE_FOLD:
|
case POKER_TURN_TYPE_FOLD:
|
||||||
POKER_PLAYERS[POKER_PLAYER_BETTER].state |= POKER_PLAYER_STATE_FOLDED;
|
POKER_PLAYERS[POKER_PLAYER_BETTER].state |= POKER_PLAYER_STATE_FOLDED;
|
||||||
conversationTextboxSetText(STR_POKER_GAME_AI_FOLD);
|
conversationTextboxSetText(STR_POKER_GAME_AI_FOLD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POKER_TURN_TYPE_BET:
|
case POKER_TURN_TYPE_BET:
|
||||||
if(turn.bluff) {
|
if(turn.bluff) {
|
||||||
conversationTextboxSetText(STR_POKER_GAME_AI_RAISE_BLUFF);
|
conversationTextboxSetText(STR_POKER_GAME_AI_RAISE_BLUFF);
|
||||||
} else {
|
} else {
|
||||||
conversationTextboxSetText(STR_POKER_GAME_AI_RAISE);
|
conversationTextboxSetText(STR_POKER_GAME_AI_RAISE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POKER_TURN_TYPE_CALL:
|
case POKER_TURN_TYPE_CALL:
|
||||||
if(turn.bluff) {
|
if(turn.bluff) {
|
||||||
conversationTextboxSetText(STR_POKER_GAME_AI_CALL_BLUFF);
|
conversationTextboxSetText(STR_POKER_GAME_AI_CALL_BLUFF);
|
||||||
} else {
|
} else {
|
||||||
conversationTextboxSetText(STR_POKER_GAME_AI_CALL);
|
conversationTextboxSetText(STR_POKER_GAME_AI_CALL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POKER_TURN_TYPE_ALL_IN:
|
case POKER_TURN_TYPE_ALL_IN:
|
||||||
if(turn.bluff) {
|
if(turn.bluff) {
|
||||||
conversationTextboxSetText(STR_POKER_GAME_AI_ALL_IN_BLUFF);
|
conversationTextboxSetText(STR_POKER_GAME_AI_ALL_IN_BLUFF);
|
||||||
} else {
|
} else {
|
||||||
conversationTextboxSetText(STR_POKER_GAME_AI_ALL_IN);
|
conversationTextboxSetText(STR_POKER_GAME_AI_ALL_IN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POKER_TURN_TYPE_CHECK:
|
case POKER_TURN_TYPE_CHECK:
|
||||||
if(turn.bluff) {
|
if(turn.bluff) {
|
||||||
conversationTextboxSetText(STR_POKER_GAME_AI_CHECK_BLUFF);
|
conversationTextboxSetText(STR_POKER_GAME_AI_CHECK_BLUFF);
|
||||||
} else {
|
} else {
|
||||||
conversationTextboxSetText(STR_POKER_GAME_AI_CHECK);
|
conversationTextboxSetText(STR_POKER_GAME_AI_CHECK);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we have their turn, decide what to say based on that.
|
// Now we have their turn, decide what to say based on that.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update bet state
|
// Update bet state
|
||||||
POKER_PLAYERS[POKER_PLAYER_BETTER].state |= (
|
POKER_PLAYERS[POKER_PLAYER_BETTER].state |= (
|
||||||
POKER_PLAYER_STATE_HAS_BET_THIS_ROUND
|
POKER_PLAYER_STATE_HAS_BET_THIS_ROUND
|
||||||
);
|
);
|
||||||
|
|
||||||
if(turn.chips > 0) {
|
if(turn.chips > 0) {
|
||||||
pokerBet(POKER_PLAYER_BETTER, turn.chips);
|
pokerBet(POKER_PLAYER_BETTER, turn.chips);
|
||||||
}
|
}
|
||||||
|
|
||||||
QUEUE_ITEM = QUEUE_NEXT_BETTER;
|
QUEUE_ITEM = QUEUE_NEXT_BETTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void conversationQueueNextBetter() {
|
void conversationQueueNextBetter() {
|
||||||
uint8_t i, j, countStillInGame;
|
uint8_t i, j, countStillInGame;
|
||||||
|
|
||||||
// Now we decide the next better.
|
// Now we decide the next better.
|
||||||
countStillInGame = 0;
|
countStillInGame = 0;
|
||||||
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
|
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
|
||||||
//In theory I don't think the current better can ever be selected again.
|
//In theory I don't think the current better can ever be selected again.
|
||||||
// if(i == POKER_PLAYER_BETTER) continue; // Commented because we now count
|
// if(i == POKER_PLAYER_BETTER) continue; // Commented because we now count
|
||||||
|
|
||||||
// Next better is the better to the right of the current better.
|
// Next better is the better to the right of the current better.
|
||||||
j = (POKER_PLAYER_BETTER + i) % POKER_PLAYER_COUNT;
|
j = (POKER_PLAYER_BETTER + i) % POKER_PLAYER_COUNT;
|
||||||
if(!pokerDoesPlayerNeedToBet(j)) {
|
if(!pokerDoesPlayerNeedToBet(j)) {
|
||||||
if((POKER_PLAYERS[j].state & (POKER_PLAYER_STATE_FOLDED | POKER_PLAYER_STATE_OUT)) == 0) {
|
if((POKER_PLAYERS[j].state & (POKER_PLAYER_STATE_FOLDED | POKER_PLAYER_STATE_OUT)) == 0) {
|
||||||
countStillInGame++;
|
countStillInGame++;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// They haven't bet yet, make them the "next better"
|
// They haven't bet yet, make them the "next better"
|
||||||
POKER_PLAYER_BETTER = j;
|
POKER_PLAYER_BETTER = j;
|
||||||
|
|
||||||
QUEUE_ITEM = QUEUE_BEGIN_BETTING;
|
QUEUE_ITEM = QUEUE_BEGIN_BETTING;
|
||||||
conversationQueueNext();
|
conversationQueueNext();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we reach this point then we either need to begin the betting round, or
|
// If we reach this point then we either need to begin the betting round, or
|
||||||
// we are going to move to the winning decider.
|
// we are going to move to the winning decider.
|
||||||
if(POKER_COMMUNITY_SIZE_MAX == POKER_COMMUNITY_SIZE || countStillInGame == 1) {
|
if(POKER_COMMUNITY_SIZE_MAX == POKER_COMMUNITY_SIZE || countStillInGame == 1) {
|
||||||
QUEUE_ITEM = QUEUE_WINNER_DECIDE;
|
QUEUE_ITEM = QUEUE_WINNER_DECIDE;
|
||||||
conversationQueueNext();
|
conversationQueueNext();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUEUE_ITEM = QUEUE_FLOP;
|
QUEUE_ITEM = QUEUE_FLOP;
|
||||||
conversationQueueNext();
|
conversationQueueNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
void conversationQueueFlopTurnRiver() {
|
void conversationQueueFlopTurnRiver() {
|
||||||
uint8_t i, count;
|
uint8_t i, count;
|
||||||
pokerplayer_t *player;
|
pokerplayer_t *player;
|
||||||
|
|
||||||
|
|
||||||
switch(POKER_COMMUNITY_SIZE) {
|
switch(POKER_COMMUNITY_SIZE) {
|
||||||
case 0:
|
case 0:
|
||||||
count = POKER_COUNT_FLOP;
|
count = POKER_COUNT_FLOP;
|
||||||
conversationTextboxSetText(STR_POKER_GAME_CARDS_FLOPPED);
|
conversationTextboxSetText(STR_POKER_GAME_CARDS_FLOPPED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POKER_COUNT_FLOP:
|
case POKER_COUNT_FLOP:
|
||||||
count = POKER_COUNT_TURN;
|
count = POKER_COUNT_TURN;
|
||||||
conversationTextboxSetText(STR_POKER_GAME_CARDS_TURNED);
|
conversationTextboxSetText(STR_POKER_GAME_CARDS_TURNED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
count = POKER_COUNT_RIVER;
|
count = POKER_COUNT_RIVER;
|
||||||
conversationTextboxSetText(STR_POKER_GAME_CARDS_RIVERED);
|
conversationTextboxSetText(STR_POKER_GAME_CARDS_RIVERED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset each players required to bet state
|
// Reset each players required to bet state
|
||||||
do {
|
do {
|
||||||
player = POKER_PLAYERS + i;
|
player = POKER_PLAYERS + i;
|
||||||
player->state &= ~POKER_PLAYER_STATE_HAS_BET_THIS_ROUND;
|
player->state &= ~POKER_PLAYER_STATE_HAS_BET_THIS_ROUND;
|
||||||
player->timesRaised = 0;
|
player->timesRaised = 0;
|
||||||
} while(++i < POKER_PLAYER_COUNT);
|
} while(++i < POKER_PLAYER_COUNT);
|
||||||
|
|
||||||
// In reality we'd burn the top card but that would waste some CPU I need.
|
// In reality we'd burn the top card but that would waste some CPU I need.
|
||||||
// Deal the top cards.
|
// Deal the top cards.
|
||||||
for(i = 0; i < count; i++) {
|
for(i = 0; i < count; i++) {
|
||||||
POKER_COMMUNITY[POKER_COMMUNITY_SIZE++] = POKER_DECK[--POKER_DECK_SIZE];
|
POKER_COMMUNITY[POKER_COMMUNITY_SIZE++] = POKER_DECK[--POKER_DECK_SIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check how many players need to bet, if it's zero then all players are
|
// Check how many players need to bet, if it's zero then all players are
|
||||||
// either folded or all-in
|
// either folded or all-in
|
||||||
if(pokerGetRemainingBetterCount() == 0x00) {
|
if(pokerGetRemainingBetterCount() == 0x00) {
|
||||||
if(POKER_COMMUNITY_SIZE == POKER_COMMUNITY_SIZE_MAX) {
|
if(POKER_COMMUNITY_SIZE == POKER_COMMUNITY_SIZE_MAX) {
|
||||||
QUEUE_ITEM = QUEUE_WINNER_DECIDE;
|
QUEUE_ITEM = QUEUE_WINNER_DECIDE;
|
||||||
} else {
|
} else {
|
||||||
QUEUE_ITEM = QUEUE_FLOP;
|
QUEUE_ITEM = QUEUE_FLOP;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QUEUE_ITEM = QUEUE_BEGIN_BETTING;
|
QUEUE_ITEM = QUEUE_BEGIN_BETTING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void conversationQueueWinnerDecide() {
|
void conversationQueueWinnerDecide() {
|
||||||
pokerpot_t *pot;
|
pokerpot_t *pot;
|
||||||
uint8_t i, j, countOfPotsWithChips, chipsEach;
|
uint8_t i, j, countOfPotsWithChips, chipsEach;
|
||||||
|
|
||||||
QUEUE_ITEM = QUEUE_BEGIN;
|
QUEUE_ITEM = QUEUE_BEGIN;
|
||||||
|
|
||||||
countOfPotsWithChips = 0;
|
countOfPotsWithChips = 0;
|
||||||
for(i = 0; i < POKER_POT_COUNT; i++) {
|
for(i = 0; i < POKER_POT_COUNT; i++) {
|
||||||
pot = POKER_POTS + i;
|
pot = POKER_POTS + i;
|
||||||
if(pot->chips == 0) break;
|
if(pot->chips == 0) break;
|
||||||
countOfPotsWithChips++;
|
countOfPotsWithChips++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Messages
|
// TODO: Messages
|
||||||
if(countOfPotsWithChips == 1) {
|
if(countOfPotsWithChips == 1) {
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pots.
|
// Pots.
|
||||||
for(i = 0; i < countOfPotsWithChips; i++) {
|
for(i = 0; i < countOfPotsWithChips; i++) {
|
||||||
pot = POKER_POTS + i;
|
pot = POKER_POTS + i;
|
||||||
pokerWinnerDetermineForPot(
|
pokerWinnerDetermineForPot(
|
||||||
pot,
|
pot,
|
||||||
POKER_WINNERS,
|
POKER_WINNERS,
|
||||||
POKER_WINNER_PLAYERS,
|
POKER_WINNER_PLAYERS,
|
||||||
&POKER_WINNER_COUNT,
|
&POKER_WINNER_COUNT,
|
||||||
POKER_WINNER_PARTICIPANTS,
|
POKER_WINNER_PARTICIPANTS,
|
||||||
&POKER_WINNER_PARTICIPANT_COUNT
|
&POKER_WINNER_PARTICIPANT_COUNT
|
||||||
);
|
);
|
||||||
|
|
||||||
chipsEach = pot->chips / POKER_WINNER_COUNT;
|
chipsEach = pot->chips / POKER_WINNER_COUNT;
|
||||||
for(j = 0; j < POKER_WINNER_COUNT; j++) {
|
for(j = 0; j < POKER_WINNER_COUNT; j++) {
|
||||||
POKER_PLAYERS[POKER_WINNER_PLAYERS[j]].chips += chipsEach;
|
POKER_PLAYERS[POKER_WINNER_PLAYERS[j]].chips += chipsEach;
|
||||||
// TODO: I can determine rounding error here if I need to, just sub the
|
// TODO: I can determine rounding error here if I need to, just sub the
|
||||||
// taken chips for each player and when I get to chips remaining less than
|
// taken chips for each player and when I get to chips remaining less than
|
||||||
// the chipsEach, then reward the rounding offset.
|
// the chipsEach, then reward the rounding offset.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Decide on a winner for real.
|
// TODO: Decide on a winner for real.
|
||||||
conversationTextboxSetText(STR_DEBUG_WINNER_DECIDED);
|
conversationTextboxSetText(STR_DEBUG_WINNER_DECIDED);
|
||||||
|
|
||||||
// New Round
|
// New Round
|
||||||
pokerNewRound();
|
pokerNewRound();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
queuecallback_t *QUEUE_CALLBACKS[] = {
|
queuecallback_t *QUEUE_CALLBACKS[] = {
|
||||||
// 0
|
// 0
|
||||||
NULL,
|
NULL,
|
||||||
&conversationQueueDebug,
|
&conversationQueueDebug,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
||||||
// 5
|
// 5
|
||||||
&conversationQueueBegin,
|
&conversationQueueBegin,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
||||||
// 10
|
// 10
|
||||||
&conversationQueueTakeBlinds,
|
&conversationQueueTakeBlinds,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
||||||
// 15
|
// 15
|
||||||
&conversationQueueDealCards,
|
&conversationQueueDealCards,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
||||||
// 20
|
// 20
|
||||||
&conversationQueueBeginBetting,
|
&conversationQueueBeginBetting,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
||||||
// 25
|
// 25
|
||||||
&conversationQueueNextBetter,
|
&conversationQueueNextBetter,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
||||||
// 30
|
// 30
|
||||||
&conversationQueueFlopTurnRiver,
|
&conversationQueueFlopTurnRiver,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
||||||
// 35
|
// 35
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
||||||
// 40
|
// 40
|
||||||
&conversationQueueWinnerDecide,
|
&conversationQueueWinnerDecide,
|
||||||
// NULL,
|
// NULL,
|
||||||
// NULL,
|
// NULL,
|
||||||
// NULL,
|
// NULL,
|
||||||
// NULL,
|
// NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void conversationQueueInit() {
|
inline void conversationQueueInit() {
|
||||||
QUEUE_ITEM = QUEUE_BEGIN;
|
QUEUE_ITEM = QUEUE_BEGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void conversationQueueNext() {
|
inline void conversationQueueNext() {
|
||||||
BGB_printf("Doing %d", QUEUE_ITEM);
|
BGB_printf("Doing %d", QUEUE_ITEM);
|
||||||
if(QUEUE_ITEM > QUEUE_WINNER_DECIDE) return;
|
if(QUEUE_ITEM > QUEUE_WINNER_DECIDE) return;
|
||||||
if(QUEUE_CALLBACKS[QUEUE_ITEM] == NULL) return;
|
if(QUEUE_CALLBACKS[QUEUE_ITEM] == NULL) return;
|
||||||
QUEUE_CALLBACKS[QUEUE_ITEM]();
|
QUEUE_CALLBACKS[QUEUE_ITEM]();
|
||||||
}
|
}
|
@@ -1,27 +1,27 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../libs.h"
|
#include "../libs.h"
|
||||||
#include "../strings.h"
|
#include "../strings.h"
|
||||||
|
|
||||||
typedef void queuecallback_t();
|
typedef void queuecallback_t();
|
||||||
|
|
||||||
extern uint16_t QUEUE_ITEM;
|
extern uint16_t QUEUE_ITEM;
|
||||||
extern queuecallback_t *QUEUE_CALLBACKS[];
|
extern queuecallback_t *QUEUE_CALLBACKS[];
|
||||||
|
|
||||||
#define QUEUE_DEBUG 1
|
#define QUEUE_DEBUG 1
|
||||||
#define QUEUE_BEGIN 5
|
#define QUEUE_BEGIN 5
|
||||||
#define QUEUE_TAKE_BLINDS 10
|
#define QUEUE_TAKE_BLINDS 10
|
||||||
#define QUEUE_DEAL_CARDS 15
|
#define QUEUE_DEAL_CARDS 15
|
||||||
#define QUEUE_BEGIN_BETTING 20
|
#define QUEUE_BEGIN_BETTING 20
|
||||||
#define QUEUE_NEXT_BETTER 25
|
#define QUEUE_NEXT_BETTER 25
|
||||||
#define QUEUE_FLOP 30
|
#define QUEUE_FLOP 30
|
||||||
#define QUEUE_WINNER_DECIDE 40
|
#define QUEUE_WINNER_DECIDE 40
|
||||||
|
|
||||||
inline void conversationQueueInit();
|
inline void conversationQueueInit();
|
||||||
inline void conversationQueueNext();
|
inline void conversationQueueNext();
|
@@ -1,150 +1,144 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "textbox.h"
|
#include "textbox.h"
|
||||||
|
|
||||||
char TEXTBOX_TEXTS[TEXTBOX_SCROLL_ROWS_MAX * TEXTBOX_CHARS_PER_ROW];
|
char TEXTBOX_TEXTS[TEXTBOX_SCROLL_ROWS_MAX * TEXTBOX_CHARS_PER_ROW];
|
||||||
uint8_t TEXTBOX_ROW_COUNT;
|
uint8_t TEXTBOX_ROW_COUNT;
|
||||||
uint8_t TEXTBOX_ROW_TILE_LAST;
|
uint8_t TEXTBOX_ROW_TILE_LAST;
|
||||||
uint8_t TEXTBOX_ROW_CURRENT;
|
uint8_t TEXTBOX_ROW_CURRENT;
|
||||||
uint8_t TEXTBOX_STATE;
|
uint8_t TEXTBOX_STATE;
|
||||||
uint8_t TEXTBOX_SCROLL;
|
uint8_t TEXTBOX_SCROLL;
|
||||||
|
|
||||||
inline void conversationTextboxInit() {
|
inline void conversationTextboxInit() {
|
||||||
uint8_t i;
|
// Reset textbox state
|
||||||
uint8_t TEXTBOX_TILES[TEXTBOX_TILES_MAX];
|
TEXTBOX_STATE = 0;
|
||||||
|
}
|
||||||
// Reset textbox state
|
|
||||||
TEXTBOX_STATE = 0;
|
void conversationTextboxSetText(char *text) {
|
||||||
|
uint8_t i, j, k, rowStart, stateFlags;
|
||||||
// Setup window data
|
char c, c2;
|
||||||
set_win_data(FONT_DATA_POSITION, FONT_IMAGE_TILES, FONT_IMAGE);
|
|
||||||
set_win_data(BORDER_DATA_POSITION, BORDER_IMAGE_TILES, BORDER_IMAGE);
|
// Begin by filling the textbox text chars with whitespace to begin.
|
||||||
}
|
// TODO: I'm pretty sure I can move this lower and optimize.
|
||||||
|
for(i = 0; i < TEXTBOX_SCROLL_ROWS_MAX * TEXTBOX_CHARS_PER_ROW; i++) {
|
||||||
void conversationTextboxSetText(char *text) {
|
TEXTBOX_TEXTS[i] = ' ';
|
||||||
uint8_t i, j, k, rowStart, stateFlags;
|
}
|
||||||
char c, c2;
|
|
||||||
|
// Reset textbox state
|
||||||
// Begin by filling the textbox text chars with whitespace to begin.
|
TEXTBOX_STATE = TEXTBOX_STATE_VISIBLE;
|
||||||
// TODO: I'm pretty sure I can move this lower and optimize.
|
TEXTBOX_SCROLL = 0;
|
||||||
for(i = 0; i < TEXTBOX_SCROLL_ROWS_MAX * TEXTBOX_CHARS_PER_ROW; i++) {
|
TEXTBOX_ROW_COUNT = 0;
|
||||||
TEXTBOX_TEXTS[i] = ' ';
|
TEXTBOX_ROW_COUNT = 1;
|
||||||
}
|
|
||||||
|
// Copy source text to buffer, also determine wordwrapping here.
|
||||||
// Reset textbox state
|
i = 0, j = 0, rowStart = 0, stateFlags = 0;
|
||||||
TEXTBOX_STATE = TEXTBOX_STATE_VISIBLE;
|
while((c = text[i]) != '\0') {// "For each char in string"
|
||||||
TEXTBOX_SCROLL = 0;
|
if(c == ' ') {
|
||||||
TEXTBOX_ROW_COUNT = 0;
|
// Scan ahead and look at how many chars remain to the next space.
|
||||||
TEXTBOX_ROW_COUNT = 1;
|
k = i + 1;
|
||||||
|
while(
|
||||||
// Copy source text to buffer, also determine wordwrapping here.
|
(c2 = text[k]) != '\0' &&
|
||||||
i = 0, j = 0, rowStart = 0, stateFlags = 0;
|
c2 != '\n' &&
|
||||||
while((c = text[i]) != '\0') {// "For each char in string"
|
c2 != ' ' &&
|
||||||
if(c == ' ') {
|
(k - rowStart) < TEXTBOX_CHARS_PER_ROW
|
||||||
// Scan ahead and look at how many chars remain to the next space.
|
) k++;
|
||||||
k = i + 1;
|
|
||||||
while(
|
// IF that number is less than the remaining chars on the current row,
|
||||||
(c2 = text[k]) != '\0' &&
|
// then treat this space like a newline.
|
||||||
c2 != '\n' &&
|
if(k >= (rowStart + TEXTBOX_CHARS_PER_ROW + 1)) {
|
||||||
c2 != ' ' &&
|
stateFlags |= 1 << 0;
|
||||||
(k - rowStart) < TEXTBOX_CHARS_PER_ROW
|
}
|
||||||
) k++;
|
} else if(c == '\n') {
|
||||||
|
stateFlags |= 1 << 0;
|
||||||
// IF that number is less than the remaining chars on the current row,
|
}
|
||||||
// then treat this space like a newline.
|
|
||||||
if(k >= (rowStart + TEXTBOX_CHARS_PER_ROW + 1)) {
|
// Do we need to insert newline where we are currently?
|
||||||
stateFlags |= 1 << 0;
|
if((stateFlags & (1 << 0)) != 0) {
|
||||||
}
|
stateFlags &= ~(1 << 0);// Remove newline flag
|
||||||
} else if(c == '\n') {
|
i++;
|
||||||
stateFlags |= 1 << 0;
|
rowStart = i;// Update the row start (Should this be i+1?)
|
||||||
}
|
//TODO: can I optimize the next line by using rowStart somehow?
|
||||||
|
j = ((j / TEXTBOX_CHARS_PER_ROW)+1) * TEXTBOX_CHARS_PER_ROW;// Update destination character position.
|
||||||
// Do we need to insert newline where we are currently?
|
TEXTBOX_ROW_COUNT++;
|
||||||
if((stateFlags & (1 << 0)) != 0) {
|
continue;
|
||||||
stateFlags &= ~(1 << 0);// Remove newline flag
|
}
|
||||||
i++;
|
|
||||||
rowStart = i;// Update the row start (Should this be i+1?)
|
// Insert the character
|
||||||
//TODO: can I optimize the next line by using rowStart somehow?
|
TEXTBOX_TEXTS[j] = c;
|
||||||
j = ((j / TEXTBOX_CHARS_PER_ROW)+1) * TEXTBOX_CHARS_PER_ROW;// Update destination character position.
|
i++;
|
||||||
TEXTBOX_ROW_COUNT++;
|
j++;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
// Now we have organized the string nicely we can prep for rendering. Fill the
|
||||||
// Insert the character
|
// tiles with blank chars.
|
||||||
TEXTBOX_TEXTS[j] = c;
|
textboxFillBlank();
|
||||||
i++;
|
}
|
||||||
j++;
|
|
||||||
}
|
inline void textboxFillBlank() {
|
||||||
|
uint8_t tiles[TEXTBOX_WIDTH_IN_TILES * TEXTBOX_HEIGHT_IN_TILES];
|
||||||
// Now we have organized the string nicely we can prep for rendering. Fill the
|
|
||||||
// tiles with blank chars.
|
spriteBorderBufferEdges(
|
||||||
textboxFillBlank();
|
tiles, TEXTBOX_WIDTH_IN_TILES, TEXTBOX_HEIGHT_IN_TILES, SPRITE_TILESET_WHITE
|
||||||
}
|
);
|
||||||
|
|
||||||
inline void textboxFillBlank() {
|
set_bkg_tiles(
|
||||||
uint8_t TEXTBOX_TILES[TEXTBOX_WIDTH_IN_TILES * TEXTBOX_HEIGHT_IN_TILES];
|
0x00, TEXTBOX_WIN_Y,
|
||||||
|
TEXTBOX_WIDTH_IN_TILES, TEXTBOX_HEIGHT_IN_TILES,
|
||||||
frameBuffer(TEXTBOX_TILES, TEXTBOX_WIDTH_IN_TILES, TEXTBOX_HEIGHT_IN_TILES, TEXTBOX_TILE_BLANK);
|
tiles
|
||||||
|
);
|
||||||
set_bkg_tiles(
|
}
|
||||||
0x00, TEXTBOX_WIN_Y,
|
|
||||||
TEXTBOX_WIDTH_IN_TILES, TEXTBOX_HEIGHT_IN_TILES,
|
inline void conversationTextboxUpdate() {
|
||||||
TEXTBOX_TILES
|
uint8_t i, tile;
|
||||||
);
|
char c;
|
||||||
}
|
|
||||||
|
// Is the textbox visible?
|
||||||
inline void conversationTextboxUpdate() {
|
if((TEXTBOX_STATE & TEXTBOX_STATE_VISIBLE) == 0) return;
|
||||||
uint8_t i;
|
|
||||||
char c;
|
// Have we finished scrolling?
|
||||||
uint8_t tiles[1];
|
if(TEXTBOX_STATE & TEXTBOX_STATE_SCROLLED) {
|
||||||
|
// Is the user trying to go to the next line?
|
||||||
// Is the textbox visible?
|
if(INPUT_PRESSED & J_A) {
|
||||||
if((TEXTBOX_STATE & TEXTBOX_STATE_VISIBLE) == 0) return;
|
// First, lets figure out if there's any more text to reveal or not.
|
||||||
|
if((TEXTBOX_ROW_COUNT - TEXTBOX_ROW_CURRENT) < TEXTBOX_TILES_ROWS) {
|
||||||
// Have we finished scrolling?
|
TEXTBOX_STATE &= ~TEXTBOX_STATE_VISIBLE;
|
||||||
if(TEXTBOX_STATE & TEXTBOX_STATE_SCROLLED) {
|
HIDE_WIN;
|
||||||
// Is the user trying to go to the next line?
|
conversationQueueNext();
|
||||||
if(INPUT_PRESSED & J_A) {
|
return;
|
||||||
// First, lets figure out if there's any more text to reveal or not.
|
}
|
||||||
if((TEXTBOX_ROW_COUNT - TEXTBOX_ROW_CURRENT) < TEXTBOX_TILES_ROWS) {
|
|
||||||
TEXTBOX_STATE &= ~TEXTBOX_STATE_VISIBLE;
|
TEXTBOX_STATE &= ~TEXTBOX_STATE_SCROLLED;
|
||||||
HIDE_WIN;
|
TEXTBOX_SCROLL = 0;
|
||||||
conversationQueueNext();
|
TEXTBOX_ROW_CURRENT += TEXTBOX_TILES_ROWS;
|
||||||
return;
|
textboxFillBlank();
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
TEXTBOX_STATE &= ~TEXTBOX_STATE_SCROLLED;
|
}
|
||||||
TEXTBOX_SCROLL = 0;
|
|
||||||
TEXTBOX_ROW_CURRENT += TEXTBOX_TILES_ROWS;
|
// Move to the next character.
|
||||||
textboxFillBlank();
|
i = TEXTBOX_ROW_CURRENT * TEXTBOX_CHARS_PER_ROW;
|
||||||
}
|
c = TEXTBOX_TEXTS[i+TEXTBOX_SCROLL];
|
||||||
return;
|
|
||||||
}
|
if(TEXTBOX_SCROLL == TEXTBOX_CHARS_MAX) {
|
||||||
|
TEXTBOX_STATE |= TEXTBOX_STATE_SCROLLED;
|
||||||
// Move to the next character.
|
} else {
|
||||||
i = TEXTBOX_ROW_CURRENT * TEXTBOX_CHARS_PER_ROW;
|
tile = spriteFontTileFromChar(c);
|
||||||
c = TEXTBOX_TEXTS[i+TEXTBOX_SCROLL];
|
|
||||||
|
set_bkg_tiles(
|
||||||
if(TEXTBOX_SCROLL == TEXTBOX_CHARS_MAX) {
|
0x01 + (TEXTBOX_SCROLL % TEXTBOX_CHARS_PER_ROW),
|
||||||
TEXTBOX_STATE |= TEXTBOX_STATE_SCROLLED;
|
TEXTBOX_WIN_Y + 0x01 + (TEXTBOX_SCROLL / TEXTBOX_CHARS_PER_ROW),
|
||||||
} else {
|
1, 1,
|
||||||
tiles[0] = c - TEXTBOX_FONT_START + FONT_DATA_POSITION;
|
&tile
|
||||||
|
);
|
||||||
set_bkg_tiles(
|
|
||||||
0x01 + (TEXTBOX_SCROLL % TEXTBOX_CHARS_PER_ROW),
|
TEXTBOX_SCROLL++;
|
||||||
TEXTBOX_WIN_Y + 0x01 + (TEXTBOX_SCROLL / TEXTBOX_CHARS_PER_ROW),
|
|
||||||
1, 1,
|
// Skip spaces
|
||||||
tiles
|
while(TEXTBOX_SCROLL < TEXTBOX_CHARS_MAX && TEXTBOX_TEXTS[i+TEXTBOX_SCROLL] == ' ') TEXTBOX_SCROLL++;
|
||||||
);
|
}
|
||||||
|
|
||||||
TEXTBOX_SCROLL++;
|
|
||||||
|
|
||||||
// Skip spaces
|
|
||||||
while(TEXTBOX_SCROLL < TEXTBOX_CHARS_MAX && TEXTBOX_TEXTS[i+TEXTBOX_SCROLL] == ' ') TEXTBOX_SCROLL++;
|
|
||||||
}
|
|
||||||
}
|
}
|
@@ -1,49 +1,46 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../libs.h"
|
#include "../libs.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
#include "../input.h"
|
#include "../input.h"
|
||||||
#include "../display/common.h"
|
#include "../sprites/spriteborder.h"
|
||||||
#include "../display/tilemap.h"
|
#include "../sprites/spritefont.h"
|
||||||
#include "queue.h"
|
#include "../sprites/spritetileset.h"
|
||||||
#include "frame.h"
|
#include "queue.h"
|
||||||
|
|
||||||
#define TEXTBOX_STATE_VISIBLE (1 << 0)
|
#define TEXTBOX_STATE_VISIBLE (1 << 0)
|
||||||
#define TEXTBOX_STATE_SCROLLED (1 << 1)
|
#define TEXTBOX_STATE_SCROLLED (1 << 1)
|
||||||
#define TEXTBOX_STATE_IS_QUESTION (1 << 2)
|
#define TEXTBOX_STATE_IS_QUESTION (1 << 2)
|
||||||
|
|
||||||
#define TEXTBOX_WIDTH_IN_TILES 20
|
#define TEXTBOX_WIDTH_IN_TILES 20
|
||||||
#define TEXTBOX_HEIGHT_IN_TILES 5
|
#define TEXTBOX_HEIGHT_IN_TILES 5
|
||||||
#define TEXTBOX_TILES_MAX (TEXTBOX_WIDTH_IN_TILES * TEXTBOX_HEIGHT_IN_TILES)
|
#define TEXTBOX_TILES_MAX (TEXTBOX_WIDTH_IN_TILES * TEXTBOX_HEIGHT_IN_TILES)
|
||||||
|
|
||||||
#define TEXTBOX_CHARS_PER_ROW (TEXTBOX_WIDTH_IN_TILES - 2)
|
#define TEXTBOX_CHARS_PER_ROW (TEXTBOX_WIDTH_IN_TILES - 2)
|
||||||
#define TEXTBOX_CHAR_ROWS (TEXTBOX_HEIGHT_IN_TILES - 2)
|
#define TEXTBOX_CHAR_ROWS (TEXTBOX_HEIGHT_IN_TILES - 2)
|
||||||
#define TEXTBOX_CHARS_MAX (TEXTBOX_CHAR_ROWS * TEXTBOX_CHARS_PER_ROW)
|
#define TEXTBOX_CHARS_MAX (TEXTBOX_CHAR_ROWS * TEXTBOX_CHARS_PER_ROW)
|
||||||
#define TEXTBOX_BUFFER_MAX (TEXTBOX_CHARS_MAX * 3)
|
#define TEXTBOX_BUFFER_MAX (TEXTBOX_CHARS_MAX * 3)
|
||||||
|
|
||||||
#define TEXTBOX_TILES_PER_ROW TEXTBOX_WIDTH_IN_TILES
|
#define TEXTBOX_TILES_PER_ROW TEXTBOX_WIDTH_IN_TILES
|
||||||
#define TEXTBOX_TILES_ROWS 3
|
#define TEXTBOX_TILES_ROWS 3
|
||||||
#define TEXTBOX_TILE_BLANK COMMON_TILE_3
|
|
||||||
|
#define TEXTBOX_SCROLL_ROWS_MAX 14
|
||||||
#define TEXTBOX_SCROLL_ROWS_MAX 14
|
|
||||||
|
#define TEXTBOX_WIN_Y (18 - TEXTBOX_HEIGHT_IN_TILES)
|
||||||
#define TEXTBOX_FONT_START 33
|
|
||||||
|
extern char TEXTBOX_TEXTS[TEXTBOX_SCROLL_ROWS_MAX * TEXTBOX_CHARS_PER_ROW];
|
||||||
#define TEXTBOX_WIN_Y (18 - TEXTBOX_HEIGHT_IN_TILES)
|
extern uint8_t TEXTBOX_ROW_COUNT;
|
||||||
|
extern uint8_t TEXTBOX_ROW_CURRENT;
|
||||||
extern char TEXTBOX_TEXTS[TEXTBOX_SCROLL_ROWS_MAX * TEXTBOX_CHARS_PER_ROW];
|
extern uint8_t TEXTBOX_STATE;
|
||||||
extern uint8_t TEXTBOX_ROW_COUNT;
|
extern uint8_t TEXTBOX_SCROLL;
|
||||||
extern uint8_t TEXTBOX_ROW_CURRENT;
|
|
||||||
extern uint8_t TEXTBOX_STATE;
|
inline void conversationTextboxInit();
|
||||||
extern uint8_t TEXTBOX_SCROLL;
|
void conversationTextboxSetText(char *text);
|
||||||
|
inline void textboxFillBlank();
|
||||||
inline void conversationTextboxInit();
|
|
||||||
void conversationTextboxSetText(char *text);
|
|
||||||
inline void textboxFillBlank();
|
|
||||||
inline void conversationTextboxUpdate();
|
inline void conversationTextboxUpdate();
|
@@ -1,19 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2022 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
const uint8_t COMMON_TILES[] = {
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void commonTilesInit() {
|
|
||||||
set_bkg_data(0x00, COMMON_TILE_COUNT, COMMON_TILES);
|
|
||||||
}
|
|
@@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2022 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "../libs.h"
|
|
||||||
|
|
||||||
#define COMMON_TILE_COUNT 0x04
|
|
||||||
|
|
||||||
#define COMMON_TILE_0 0x00
|
|
||||||
#define COMMON_TILE_1 0x01
|
|
||||||
#define COMMON_TILE_2 0x02
|
|
||||||
#define COMMON_TILE_3 0x03
|
|
||||||
|
|
||||||
// Shades are mapped where each set of 4 colors is mapped to two bits that will
|
|
||||||
// specify its darkness. Higher = Darker, Lower = Brighter
|
|
||||||
// 11 11 11 11
|
|
||||||
#define COMMON_SHADE_BLACK 0xFF
|
|
||||||
// 11 11 11 10
|
|
||||||
#define COMMON_SHADE_DARKER 0xFE
|
|
||||||
// 11 11 10 01
|
|
||||||
#define COMMON_SHADE_DARK 0xF9
|
|
||||||
// 11 10 01 00
|
|
||||||
#define COMMON_SHADE_NORMAL 0xE4
|
|
||||||
// 10 01 00 00
|
|
||||||
#define COMMON_SHADE_BRIGHT 0x90
|
|
||||||
// 01 00 00 00
|
|
||||||
#define COMMON_SHADE_BRIGHTER 0x40
|
|
||||||
// 00 00 00 00
|
|
||||||
#define COMMON_SHADE_WHITE 0x00
|
|
||||||
|
|
||||||
extern const uint8_t COMMON_TILES[];
|
|
||||||
|
|
||||||
inline void commonTilesInit();
|
|
@@ -1,15 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2022 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "FONT.h"
|
|
||||||
#include "BORDER.h"
|
|
||||||
// #include "SM.h"
|
|
||||||
|
|
||||||
#define FONT_DATA_POSITION 0x80
|
|
||||||
#define BORDER_DATA_POSITION FONT_DATA_POSITION+FONT_IMAGE_TILES
|
|
||||||
// #define SM_DATA_POSITION BORDER_DATA_POSITION+BORDER_IMAGE_TILES
|
|
22
src/input.c
@@ -1,12 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
uint8_t INPUT_STATE = 0x00;
|
uint8_t INPUT_STATE = 0x00;
|
||||||
uint8_t INPUT_PRESSED = 0x00;
|
uint8_t INPUT_PRESSED = 0x00;
|
||||||
uint8_t INPUT_LAST = 0x00;
|
uint8_t INPUT_LAST = 0x00;
|
24
src/input.h
@@ -1,13 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "libs.h"
|
#include "libs.h"
|
||||||
|
|
||||||
extern uint8_t INPUT_STATE;
|
extern uint8_t INPUT_STATE;
|
||||||
extern uint8_t INPUT_PRESSED;
|
extern uint8_t INPUT_PRESSED;
|
||||||
extern uint8_t INPUT_LAST;
|
extern uint8_t INPUT_LAST;
|
28
src/libs.h
@@ -1,15 +1,15 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2021 Dominic Masters
|
* Copyright (c) 2021 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <gb/gb.h>
|
#include <gb/gb.h>
|
||||||
#include <gb/bgb_emu.h>
|
#include <gb/bgb_emu.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <rand.h>
|
#include <rand.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
296
src/main.c
@@ -1,218 +1,80 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2021 Dominic Masters
|
* Copyright (c) 2021 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
inline uint8_t mainGetChar(char c) {
|
void main() {
|
||||||
return c - TEXTBOX_FONT_START + FONT_DATA_POSITION;
|
int16_t j;
|
||||||
}
|
uint8_t filled[GB_BACKGROUND_COLUMNS*GB_BACKGROUND_ROWS];
|
||||||
|
|
||||||
inline void mainBufferCard(uint8_t card, uint8_t *tiles) {
|
// Set up the GAMEBOY's registers.
|
||||||
uint8_t suit, number;
|
disable_interrupts();
|
||||||
|
DISPLAY_OFF;
|
||||||
if(card >= CARD_DECK_SIZE) {
|
LCDC_REG = LCDCF_OFF | LCDCF_BG8000 | LCDCF_BG9800 | LCDCF_BGON;
|
||||||
tiles[0] = mainGetChar('N');
|
|
||||||
tiles[1] = mainGetChar('A');
|
// Set the background color palette register
|
||||||
return;
|
BGP_REG = OBP0_REG = OBP1_REG = 0xE4U;
|
||||||
}
|
|
||||||
|
// Init the random seed
|
||||||
suit = cardGetSuit(card);
|
initarand(DIV_REG);
|
||||||
number = cardGetNumber(card);
|
|
||||||
|
// Init things
|
||||||
switch(suit) {
|
spriteTilesetBuffer();
|
||||||
case CARD_SUIT_CLUBS:
|
spriteFontBuffer();
|
||||||
tiles[0] = mainGetChar('C');
|
spriteBorderBuffer();
|
||||||
break;
|
spriteCardsBuffer();
|
||||||
case CARD_SUIT_DIAMONDS:
|
|
||||||
tiles[0] = mainGetChar('D');
|
conversationTextboxInit();
|
||||||
break;
|
conversationQueueInit();
|
||||||
case CARD_SUIT_HEARTS:
|
pokerInit();
|
||||||
tiles[0] = mainGetChar('H');
|
|
||||||
break;
|
// Fill screen white
|
||||||
case CARD_SUIT_SPADES:
|
for(j = 0; j < GB_BACKGROUND_COLUMNS * GB_BACKGROUND_ROWS; j++) {
|
||||||
tiles[0] = mainGetChar('S');
|
filled[j] = SPRITE_TILESET_WHITE;
|
||||||
break;
|
}
|
||||||
}
|
set_bkg_tiles(0x00, 0x00, GB_BACKGROUND_COLUMNS, GB_BACKGROUND_ROWS, filled);
|
||||||
|
SCX_REG = 0x00;
|
||||||
switch(number) {
|
SCY_REG = 0x00;
|
||||||
case CARD_TWO:
|
|
||||||
tiles[1] = mainGetChar('2');
|
// Card Test
|
||||||
break;
|
uint8_t cardTiles[SPRITE_CARD_TILE_COUNT];
|
||||||
case CARD_THREE:
|
spriteCardBufferTiles(cardTiles, CARD_HEARTS_TWO);
|
||||||
tiles[1] = mainGetChar('3');
|
set_bkg_tiles(0x00, 0x00, SPRITE_CARD_WIDTH, SPRITE_CARD_HEIGHT, cardTiles);
|
||||||
break;
|
|
||||||
case CARD_FOUR:
|
// Now turn the screen on
|
||||||
tiles[1] = mainGetChar('4');
|
DISPLAY_ON;
|
||||||
break;
|
enable_interrupts();
|
||||||
case CARD_FIVE:
|
wait_vbl_done();
|
||||||
tiles[1] = mainGetChar('5');
|
|
||||||
break;
|
// Begin game
|
||||||
case CARD_SIX:
|
conversationQueueNext();
|
||||||
tiles[1] = mainGetChar('6');
|
|
||||||
break;
|
// Begin the loop
|
||||||
case CARD_SEVEN:
|
while(1) {
|
||||||
tiles[1] = mainGetChar('7');
|
// Perform non-graphical code updates
|
||||||
break;
|
wait_vbl_done();
|
||||||
case CARD_EIGHT:
|
|
||||||
tiles[1] = mainGetChar('8');
|
// Update the input state
|
||||||
break;
|
INPUT_LAST = INPUT_STATE;
|
||||||
case CARD_NINE:
|
INPUT_STATE = joypad();
|
||||||
tiles[1] = mainGetChar('9');
|
INPUT_PRESSED = (~INPUT_LAST) & INPUT_STATE;
|
||||||
break;
|
|
||||||
case CARD_TEN:
|
// Tick time.
|
||||||
tiles[1] = mainGetChar('T');
|
timeUpdate();
|
||||||
break;
|
|
||||||
case CARD_JACK:
|
// Update conversation pause effect
|
||||||
tiles[1] = mainGetChar('J');
|
conversationPauseUpdate();
|
||||||
break;
|
|
||||||
case CARD_QUEEN:
|
// Update question box and textbox
|
||||||
tiles[1] = mainGetChar('Q');
|
questionBoxUpdate();
|
||||||
break;
|
conversationTextboxUpdate();
|
||||||
case CARD_KING:
|
|
||||||
tiles[1] = mainGetChar('K');
|
// Update conversation fade effect
|
||||||
break;
|
conversationFadeUpdate();
|
||||||
case CARD_ACE:
|
// mainDebugDraw();
|
||||||
tiles[1] = mainGetChar('A');
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void mainDebugDraw() {
|
|
||||||
uint8_t j, i, n;
|
|
||||||
|
|
||||||
// DEBUG DRAW
|
|
||||||
uint8_t tiles[15];
|
|
||||||
char buffer[6];
|
|
||||||
buffer[0] = '\0';
|
|
||||||
|
|
||||||
for(j = 0; j < POKER_PLAYER_COUNT; j++) {
|
|
||||||
n = 0;
|
|
||||||
|
|
||||||
if(j == POKER_PLAYER_BETTER) {
|
|
||||||
tiles[n++] = mainGetChar('>');
|
|
||||||
} else {
|
|
||||||
tiles[n++] = COMMON_TILE_3;
|
|
||||||
}
|
|
||||||
|
|
||||||
mainBufferCard(POKER_PLAYERS[j].hand[0], tiles+n);
|
|
||||||
n+=2;
|
|
||||||
mainBufferCard(POKER_PLAYERS[j].hand[1], tiles+n);
|
|
||||||
n+=2;
|
|
||||||
|
|
||||||
tiles[n++] = COMMON_TILE_3;
|
|
||||||
|
|
||||||
if((POKER_PLAYERS[j].state & POKER_PLAYER_STATE_FOLDED) == 0) {
|
|
||||||
tiles[n++] = COMMON_TILE_3;
|
|
||||||
} else {
|
|
||||||
tiles[n++] = mainGetChar('F');
|
|
||||||
}
|
|
||||||
|
|
||||||
if((POKER_PLAYERS[j].state & POKER_PLAYER_STATE_HAS_BET_THIS_ROUND) == 0) {
|
|
||||||
tiles[n++] = COMMON_TILE_3;
|
|
||||||
} else {
|
|
||||||
tiles[n++] = mainGetChar('H');
|
|
||||||
}
|
|
||||||
|
|
||||||
if((POKER_PLAYERS[j].state & POKER_PLAYER_STATE_OUT) == 0) {
|
|
||||||
tiles[n++] = COMMON_TILE_3;
|
|
||||||
} else {
|
|
||||||
tiles[n++] = mainGetChar('O');
|
|
||||||
}
|
|
||||||
|
|
||||||
tiles[n++] = COMMON_TILE_3;
|
|
||||||
|
|
||||||
// Print chips
|
|
||||||
sprintf(buffer, "%u", (uint16_t)POKER_PLAYERS[j].chips);
|
|
||||||
for(i = 0; i < strlen(buffer); i++) {
|
|
||||||
tiles[n++] = mainGetChar(buffer[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(n < 15) tiles[n++] = COMMON_TILE_3;
|
|
||||||
set_bkg_tiles(0x00, j, n - 1, 1, tiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(j = 0; j < POKER_COMMUNITY_SIZE_MAX; j++) {
|
|
||||||
if(j >= POKER_COMMUNITY_SIZE) {
|
|
||||||
tiles[j*2] = COMMON_TILE_3;
|
|
||||||
tiles[(j*2) + 1] = COMMON_TILE_3;
|
|
||||||
} else {
|
|
||||||
mainBufferCard(POKER_COMMUNITY[j], tiles + (j * 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set_bkg_tiles(0x00, POKER_PLAYER_COUNT + 1, POKER_COMMUNITY_SIZE_MAX * 2, 1, tiles);
|
|
||||||
|
|
||||||
|
|
||||||
// Print Pot
|
|
||||||
n = 0;
|
|
||||||
sprintf(buffer, "%u", (uint16_t)POKER_POTS[POKER_POT_CURRENT].chips);
|
|
||||||
for(i = 0; i < strlen(buffer); i++) {
|
|
||||||
tiles[n++] = mainGetChar(buffer[i]);
|
|
||||||
}
|
|
||||||
while(n < 5) tiles[n++] = COMMON_TILE_3;
|
|
||||||
set_bkg_tiles(0x00, POKER_PLAYER_COUNT + 2, n, 1, tiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
int16_t j;
|
|
||||||
uint8_t filled[GB_BACKGROUND_COLUMNS*GB_BACKGROUND_ROWS];
|
|
||||||
|
|
||||||
// Set up the GAMEBOY's registers.
|
|
||||||
disable_interrupts();
|
|
||||||
DISPLAY_OFF;
|
|
||||||
LCDC_REG = LCDCF_OFF | LCDCF_WIN9C00 | LCDCF_BG8800 | LCDCF_BG9800 | LCDCF_BGON;
|
|
||||||
// Set the background color palette register
|
|
||||||
BGP_REG = OBP0_REG = OBP1_REG = 0xE4U;
|
|
||||||
|
|
||||||
// Init the random seed
|
|
||||||
initarand(DIV_REG);
|
|
||||||
|
|
||||||
// Init things
|
|
||||||
commonTilesInit();
|
|
||||||
conversationTextboxInit();
|
|
||||||
conversationQueueInit();
|
|
||||||
pokerInit();
|
|
||||||
|
|
||||||
// Fill screen white
|
|
||||||
for(j = 0; j < GB_BACKGROUND_COLUMNS * GB_BACKGROUND_ROWS; j++) filled[j] = COMMON_TILE_3;
|
|
||||||
set_bkg_tiles(0x00, 0x00, GB_BACKGROUND_COLUMNS, GB_BACKGROUND_ROWS, filled);
|
|
||||||
SCX_REG = 0x00;
|
|
||||||
SCY_REG = 0x00;
|
|
||||||
|
|
||||||
// Now turn the screen on
|
|
||||||
DISPLAY_ON;
|
|
||||||
enable_interrupts();
|
|
||||||
wait_vbl_done();
|
|
||||||
|
|
||||||
// Begin game
|
|
||||||
conversationQueueNext();
|
|
||||||
|
|
||||||
// Begin the loop
|
|
||||||
while(1) {
|
|
||||||
// Perform non-graphical code updates
|
|
||||||
wait_vbl_done();
|
|
||||||
|
|
||||||
// Update the input state
|
|
||||||
INPUT_LAST = INPUT_STATE;
|
|
||||||
INPUT_STATE = joypad();
|
|
||||||
INPUT_PRESSED = (~INPUT_LAST) & INPUT_STATE;
|
|
||||||
|
|
||||||
// Tick time.
|
|
||||||
timeUpdate();
|
|
||||||
|
|
||||||
// Update conversation pause effect
|
|
||||||
conversationPauseUpdate();
|
|
||||||
|
|
||||||
// Update question box and textbox
|
|
||||||
questionBoxUpdate();
|
|
||||||
conversationTextboxUpdate();
|
|
||||||
|
|
||||||
// Update conversation fade effect
|
|
||||||
conversationFadeUpdate();
|
|
||||||
mainDebugDraw();
|
|
||||||
}
|
|
||||||
}
|
}
|
54
src/main.h
@@ -1,28 +1,28 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "libs.h"
|
#include "libs.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
|
||||||
#include "SM.h"
|
#include "SM.h"
|
||||||
|
|
||||||
#include "display/common.h"
|
#include "poker/poker.h"
|
||||||
#include "display/tilemap.h"
|
#include "poker/card.h"
|
||||||
#include "poker/poker.h"
|
#include "conversation/fade.h"
|
||||||
#include "poker/card.h"
|
#include "conversation/pause.h"
|
||||||
#include "conversation/fade.h"
|
#include "conversation/queue.h"
|
||||||
#include "conversation/pause.h"
|
#include "conversation/textbox.h"
|
||||||
#include "conversation/queue.h"
|
#include "conversation/questionbox.h"
|
||||||
#include "conversation/textbox.h"
|
|
||||||
#include "conversation/questionbox.h"
|
#include "sprites/spritecards.h"
|
||||||
|
|
||||||
#define GB_BACKGROUND_COLUMNS 0x20
|
#define GB_BACKGROUND_COLUMNS 0x20
|
||||||
#define GB_BACKGROUND_ROWS 0x20
|
#define GB_BACKGROUND_ROWS 0x20
|
||||||
|
|
||||||
void main();
|
void main();
|
@@ -1,50 +1,50 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "card.h"
|
#include "card.h"
|
||||||
|
|
||||||
inline uint8_t cardGetNumber(uint8_t card) {
|
inline uint8_t cardGetNumber(uint8_t card) {
|
||||||
return card % CARD_COUNT_PER_SUIT;
|
return card % CARD_COUNT_PER_SUIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t cardGetSuit(uint8_t card) {
|
inline uint8_t cardGetSuit(uint8_t card) {
|
||||||
return card / CARD_COUNT_PER_SUIT;
|
return card / CARD_COUNT_PER_SUIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t cardGet(uint8_t number, uint8_t suit) {
|
inline uint8_t cardGet(uint8_t number, uint8_t suit) {
|
||||||
return (suit * CARD_COUNT_PER_SUIT) + number;
|
return (suit * CARD_COUNT_PER_SUIT) + number;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t cardContains(uint8_t *hand, uint8_t length, uint8_t card) {
|
inline uint8_t cardContains(uint8_t *hand, uint8_t length, uint8_t card) {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for(i = 0; i < length; i++) {
|
for(i = 0; i < length; i++) {
|
||||||
if(hand[i] == card) return i;
|
if(hand[i] == card) return i;
|
||||||
}
|
}
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t cardContainsNumber(uint8_t *hand,uint8_t length,uint8_t number) {
|
inline uint8_t cardContainsNumber(uint8_t *hand,uint8_t length,uint8_t number) {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for(i = 0; i < length; i++) {
|
for(i = 0; i < length; i++) {
|
||||||
if(cardGetNumber(hand[i]) == number) return i;
|
if(cardGetNumber(hand[i]) == number) return i;
|
||||||
}
|
}
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t cardCountPairs(
|
inline uint8_t cardCountPairs(
|
||||||
uint8_t *in, uint8_t inCount, uint8_t number, uint8_t out[CARD_SUIT_COUNT]
|
uint8_t *in, uint8_t inCount, uint8_t number, uint8_t out[CARD_SUIT_COUNT]
|
||||||
) {
|
) {
|
||||||
uint8_t i, count;
|
uint8_t i, count;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
for(i = 0; i < inCount; i++) {// "For each suit"
|
for(i = 0; i < inCount; i++) {// "For each suit"
|
||||||
if(cardGetNumber(in[i]) != number) continue;
|
if(cardGetNumber(in[i]) != number) continue;
|
||||||
out[count++] = i;
|
out[count++] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
232
src/poker/card.h
@@ -1,117 +1,117 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../libs.h"
|
#include "../libs.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Cards
|
// Cards
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Aces
|
// Aces
|
||||||
#define CARD_CLUBS_TWO 0x00
|
#define CARD_CLUBS_TWO 0x00
|
||||||
#define CARD_CLUBS_THREE 0x01
|
#define CARD_CLUBS_THREE 0x01
|
||||||
#define CARD_CLUBS_FOUR 0x02
|
#define CARD_CLUBS_FOUR 0x02
|
||||||
#define CARD_CLUBS_FIVE 0x03
|
#define CARD_CLUBS_FIVE 0x03
|
||||||
#define CARD_CLUBS_SIX 0x04
|
#define CARD_CLUBS_SIX 0x04
|
||||||
#define CARD_CLUBS_SEVEN 0x05
|
#define CARD_CLUBS_SEVEN 0x05
|
||||||
#define CARD_CLUBS_EIGHT 0x06
|
#define CARD_CLUBS_EIGHT 0x06
|
||||||
#define CARD_CLUBS_NINE 0x07
|
#define CARD_CLUBS_NINE 0x07
|
||||||
#define CARD_CLUBS_TEN 0x08
|
#define CARD_CLUBS_TEN 0x08
|
||||||
#define CARD_CLUBS_JACK 0x09
|
#define CARD_CLUBS_JACK 0x09
|
||||||
#define CARD_CLUBS_QUEEN 0x0A
|
#define CARD_CLUBS_QUEEN 0x0A
|
||||||
#define CARD_CLUBS_KING 0x0B
|
#define CARD_CLUBS_KING 0x0B
|
||||||
#define CARD_CLUBS_ACE 0x0C
|
#define CARD_CLUBS_ACE 0x0C
|
||||||
|
|
||||||
// Diamonds
|
// Diamonds
|
||||||
#define CARD_DIAMONDS_TWO 0x0D
|
#define CARD_DIAMONDS_TWO 0x0D
|
||||||
#define CARD_DIAMONDS_THREE 0x0E
|
#define CARD_DIAMONDS_THREE 0x0E
|
||||||
#define CARD_DIAMONDS_FOUR 0x0F
|
#define CARD_DIAMONDS_FOUR 0x0F
|
||||||
#define CARD_DIAMONDS_FIVE 0x10
|
#define CARD_DIAMONDS_FIVE 0x10
|
||||||
#define CARD_DIAMONDS_SIX 0x11
|
#define CARD_DIAMONDS_SIX 0x11
|
||||||
#define CARD_DIAMONDS_SEVEN 0x12
|
#define CARD_DIAMONDS_SEVEN 0x12
|
||||||
#define CARD_DIAMONDS_EIGHT 0x13
|
#define CARD_DIAMONDS_EIGHT 0x13
|
||||||
#define CARD_DIAMONDS_NINE 0x14
|
#define CARD_DIAMONDS_NINE 0x14
|
||||||
#define CARD_DIAMONDS_TEN 0x15
|
#define CARD_DIAMONDS_TEN 0x15
|
||||||
#define CARD_DIAMONDS_JACK 0x16
|
#define CARD_DIAMONDS_JACK 0x16
|
||||||
#define CARD_DIAMONDS_QUEEN 0x17
|
#define CARD_DIAMONDS_QUEEN 0x17
|
||||||
#define CARD_DIAMONDS_KING 0x18
|
#define CARD_DIAMONDS_KING 0x18
|
||||||
#define CARD_DIAMONDS_ACE 0x19
|
#define CARD_DIAMONDS_ACE 0x19
|
||||||
|
|
||||||
// Hearts
|
// Hearts
|
||||||
#define CARD_HEARTS_TWO 0x1A
|
#define CARD_HEARTS_TWO 0x1A
|
||||||
#define CARD_HEARTS_THREE 0x1B
|
#define CARD_HEARTS_THREE 0x1B
|
||||||
#define CARD_HEARTS_FOUR 0x1C
|
#define CARD_HEARTS_FOUR 0x1C
|
||||||
#define CARD_HEARTS_FIVE 0x1D
|
#define CARD_HEARTS_FIVE 0x1D
|
||||||
#define CARD_HEARTS_SIX 0x1E
|
#define CARD_HEARTS_SIX 0x1E
|
||||||
#define CARD_HEARTS_SEVEN 0x1F
|
#define CARD_HEARTS_SEVEN 0x1F
|
||||||
#define CARD_HEARTS_EIGHT 0x20
|
#define CARD_HEARTS_EIGHT 0x20
|
||||||
#define CARD_HEARTS_NINE 0x21
|
#define CARD_HEARTS_NINE 0x21
|
||||||
#define CARD_HEARTS_TEN 0x22
|
#define CARD_HEARTS_TEN 0x22
|
||||||
#define CARD_HEARTS_JACK 0x23
|
#define CARD_HEARTS_JACK 0x23
|
||||||
#define CARD_HEARTS_QUEEN 0x24
|
#define CARD_HEARTS_QUEEN 0x24
|
||||||
#define CARD_HEARTS_KING 0x25
|
#define CARD_HEARTS_KING 0x25
|
||||||
#define CARD_HEARTS_ACE 0x26
|
#define CARD_HEARTS_ACE 0x26
|
||||||
|
|
||||||
// Spades
|
// Spades
|
||||||
#define CARD_SPADES_TWO 0x27
|
#define CARD_SPADES_TWO 0x27
|
||||||
#define CARD_SPADES_THREE 0x28
|
#define CARD_SPADES_THREE 0x28
|
||||||
#define CARD_SPADES_FOUR 0x29
|
#define CARD_SPADES_FOUR 0x29
|
||||||
#define CARD_SPADES_FIVE 0x2A
|
#define CARD_SPADES_FIVE 0x2A
|
||||||
#define CARD_SPADES_SIX 0x2B
|
#define CARD_SPADES_SIX 0x2B
|
||||||
#define CARD_SPADES_SEVEN 0x2C
|
#define CARD_SPADES_SEVEN 0x2C
|
||||||
#define CARD_SPADES_EIGHT 0x2D
|
#define CARD_SPADES_EIGHT 0x2D
|
||||||
#define CARD_SPADES_NINE 0x2E
|
#define CARD_SPADES_NINE 0x2E
|
||||||
#define CARD_SPADES_TEN 0x2F
|
#define CARD_SPADES_TEN 0x2F
|
||||||
#define CARD_SPADES_JACK 0x30
|
#define CARD_SPADES_JACK 0x30
|
||||||
#define CARD_SPADES_QUEEN 0x31
|
#define CARD_SPADES_QUEEN 0x31
|
||||||
#define CARD_SPADES_KING 0x32
|
#define CARD_SPADES_KING 0x32
|
||||||
#define CARD_SPADES_ACE 0x33
|
#define CARD_SPADES_ACE 0x33
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Suits
|
// Suits
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#define CARD_SUIT_CLUBS 0x00
|
#define CARD_SUIT_CLUBS 0x00
|
||||||
#define CARD_SUIT_DIAMONDS 0x01
|
#define CARD_SUIT_DIAMONDS 0x01
|
||||||
#define CARD_SUIT_HEARTS 0x02
|
#define CARD_SUIT_HEARTS 0x02
|
||||||
#define CARD_SUIT_SPADES 0x03
|
#define CARD_SUIT_SPADES 0x03
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Card numbers
|
// Card numbers
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#define CARD_TWO 0x00
|
#define CARD_TWO 0x00
|
||||||
#define CARD_THREE 0x01
|
#define CARD_THREE 0x01
|
||||||
#define CARD_FOUR 0x02
|
#define CARD_FOUR 0x02
|
||||||
#define CARD_FIVE 0x03
|
#define CARD_FIVE 0x03
|
||||||
#define CARD_SIX 0x04
|
#define CARD_SIX 0x04
|
||||||
#define CARD_SEVEN 0x05
|
#define CARD_SEVEN 0x05
|
||||||
#define CARD_EIGHT 0x06
|
#define CARD_EIGHT 0x06
|
||||||
#define CARD_NINE 0x07
|
#define CARD_NINE 0x07
|
||||||
#define CARD_TEN 0x08
|
#define CARD_TEN 0x08
|
||||||
#define CARD_JACK 0x09
|
#define CARD_JACK 0x09
|
||||||
#define CARD_QUEEN 0x0A
|
#define CARD_QUEEN 0x0A
|
||||||
#define CARD_KING 0x0B
|
#define CARD_KING 0x0B
|
||||||
#define CARD_ACE 0x0C
|
#define CARD_ACE 0x0C
|
||||||
|
|
||||||
/** Count of cards in each suit */
|
/** Count of cards in each suit */
|
||||||
#define CARD_COUNT_PER_SUIT 13
|
#define CARD_COUNT_PER_SUIT 13
|
||||||
|
|
||||||
/** Count of suits */
|
/** Count of suits */
|
||||||
#define CARD_SUIT_COUNT 4
|
#define CARD_SUIT_COUNT 4
|
||||||
|
|
||||||
/** Standard Card Deck Size */
|
/** Standard Card Deck Size */
|
||||||
#define CARD_DECK_SIZE 52
|
#define CARD_DECK_SIZE 52
|
||||||
|
|
||||||
inline uint8_t cardGetNumber(uint8_t card);
|
inline uint8_t cardGetNumber(uint8_t card);
|
||||||
inline uint8_t cardGetSuit(uint8_t card);
|
inline uint8_t cardGetSuit(uint8_t card);
|
||||||
inline uint8_t cardGet(uint8_t card, uint8_t suit);
|
inline uint8_t cardGet(uint8_t card, uint8_t suit);
|
||||||
inline uint8_t cardContains(uint8_t *hand, uint8_t length, uint8_t card);
|
inline uint8_t cardContains(uint8_t *hand, uint8_t length, uint8_t card);
|
||||||
inline uint8_t cardContainsNumber(uint8_t *hand,uint8_t length,uint8_t number);
|
inline uint8_t cardContainsNumber(uint8_t *hand,uint8_t length,uint8_t number);
|
||||||
inline uint8_t cardCountPairs(
|
inline uint8_t cardCountPairs(
|
||||||
uint8_t *in, uint8_t inCount, uint8_t number, uint8_t out[CARD_SUIT_COUNT]
|
uint8_t *in, uint8_t inCount, uint8_t number, uint8_t out[CARD_SUIT_COUNT]
|
||||||
);
|
);
|
@@ -1,28 +1,28 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../libs.h"
|
#include "../libs.h"
|
||||||
#include "card.h"
|
#include "card.h"
|
||||||
|
|
||||||
#define POKER_PLAYER_COUNT_MAX 5
|
#define POKER_PLAYER_COUNT_MAX 5
|
||||||
#define POKER_PLAYER_HAND_SIZE_MAX 2
|
#define POKER_PLAYER_HAND_SIZE_MAX 2
|
||||||
|
|
||||||
#define POKER_PLAYER_STATE_FOLDED (1 << 0)
|
#define POKER_PLAYER_STATE_FOLDED (1 << 0)
|
||||||
#define POKER_PLAYER_STATE_OUT (1 << 1)
|
#define POKER_PLAYER_STATE_OUT (1 << 1)
|
||||||
#define POKER_PLAYER_STATE_HAS_BET_THIS_ROUND (1 << 2)
|
#define POKER_PLAYER_STATE_HAS_BET_THIS_ROUND (1 << 2)
|
||||||
// #define POKER_PLAYER_STATE_SHOWING 1 << 3
|
// #define POKER_PLAYER_STATE_SHOWING 1 << 3
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t chips;
|
uint16_t chips;
|
||||||
uint8_t hand[POKER_PLAYER_HAND_SIZE_MAX];
|
uint8_t hand[POKER_PLAYER_HAND_SIZE_MAX];
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
uint8_t timesRaised;
|
uint8_t timesRaised;
|
||||||
} pokerplayer_t;
|
} pokerplayer_t;
|
||||||
|
|
||||||
extern pokerplayer_t POKER_PLAYERS[];
|
extern pokerplayer_t POKER_PLAYERS[];
|
||||||
extern uint8_t POKER_PLAYER_COUNT;
|
extern uint8_t POKER_PLAYER_COUNT;
|
1576
src/poker/poker.c
@@ -1,57 +1,57 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../libs.h"
|
#include "../libs.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
#include "card.h"
|
#include "card.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "pot.h"
|
#include "pot.h"
|
||||||
#include "turn.h"
|
#include "turn.h"
|
||||||
#include "winner.h"
|
#include "winner.h"
|
||||||
|
|
||||||
#define POKER_COMMUNITY_SIZE_MAX 5
|
#define POKER_COMMUNITY_SIZE_MAX 5
|
||||||
#define POKER_HUMAN_INDEX 0x00
|
#define POKER_HUMAN_INDEX 0x00
|
||||||
|
|
||||||
#define POKER_COUNT_FLOP 0x03
|
#define POKER_COUNT_FLOP 0x03
|
||||||
#define POKER_COUNT_TURN 0x01
|
#define POKER_COUNT_TURN 0x01
|
||||||
#define POKER_COUNT_RIVER 0x01
|
#define POKER_COUNT_RIVER 0x01
|
||||||
|
|
||||||
extern uint8_t POKER_DECK[];
|
extern uint8_t POKER_DECK[];
|
||||||
extern uint8_t POKER_DECK_SIZE;
|
extern uint8_t POKER_DECK_SIZE;
|
||||||
extern uint8_t POKER_COMMUNITY[];
|
extern uint8_t POKER_COMMUNITY[];
|
||||||
extern uint8_t POKER_COMMUNITY_SIZE;
|
extern uint8_t POKER_COMMUNITY_SIZE;
|
||||||
|
|
||||||
extern uint8_t POKER_PLAYER_DEALER;
|
extern uint8_t POKER_PLAYER_DEALER;
|
||||||
extern uint8_t POKER_PLAYER_SMALL_BLIND;
|
extern uint8_t POKER_PLAYER_SMALL_BLIND;
|
||||||
extern uint8_t POKER_PLAYER_BIG_BLIND;
|
extern uint8_t POKER_PLAYER_BIG_BLIND;
|
||||||
extern uint8_t POKER_PLAYER_BETTER;
|
extern uint8_t POKER_PLAYER_BETTER;
|
||||||
|
|
||||||
extern uint16_t POKER_GAME_BLINDS_CURRENT;
|
extern uint16_t POKER_GAME_BLINDS_CURRENT;
|
||||||
|
|
||||||
void pokerInit();
|
void pokerInit();
|
||||||
void pokerNewRound();
|
void pokerNewRound();
|
||||||
inline void pokerBet(uint8_t player, uint16_t amount);
|
inline void pokerBet(uint8_t player, uint16_t amount);
|
||||||
inline uint8_t pokerGetCallBet(uint8_t player);
|
inline uint8_t pokerGetCallBet(uint8_t player);
|
||||||
void pokerAi(uint8_t player, pokerturn_t *turn);
|
void pokerAi(uint8_t player, pokerturn_t *turn);
|
||||||
inline bool pokerCanPlayerCheck(uint8_t player);
|
inline bool pokerCanPlayerCheck(uint8_t player);
|
||||||
inline bool pokerDoesPlayerNeedToBet(uint8_t playerIndex);
|
inline bool pokerDoesPlayerNeedToBet(uint8_t playerIndex);
|
||||||
inline uint8_t pokerGetRemainingBetterCount();
|
inline uint8_t pokerGetRemainingBetterCount();
|
||||||
void pokerWinnerFillRemaining(pokerplayerwinning_t *winning);
|
void pokerWinnerFillRemaining(pokerplayerwinning_t *winning);
|
||||||
void pokerWinnerGetForPlayer(uint8_t playerIndex,pokerplayerwinning_t *winning);
|
void pokerWinnerGetForPlayer(uint8_t playerIndex,pokerplayerwinning_t *winning);
|
||||||
inline uint16_t pokerWinnerGetTypeConfidence(uint8_t type);
|
inline uint16_t pokerWinnerGetTypeConfidence(uint8_t type);
|
||||||
uint8_t pokerWinnerCompare(
|
uint8_t pokerWinnerCompare(
|
||||||
pokerplayerwinning_t *left, pokerplayerwinning_t *right
|
pokerplayerwinning_t *left, pokerplayerwinning_t *right
|
||||||
);
|
);
|
||||||
void pokerWinnerDetermineForPot(
|
void pokerWinnerDetermineForPot(
|
||||||
pokerpot_t *pot,
|
pokerpot_t *pot,
|
||||||
pokerplayerwinning_t *winners,
|
pokerplayerwinning_t *winners,
|
||||||
uint8_t *winnerPlayers,
|
uint8_t *winnerPlayers,
|
||||||
uint8_t *winnerCount,
|
uint8_t *winnerCount,
|
||||||
uint8_t *participants,
|
uint8_t *participants,
|
||||||
uint8_t *participantCount
|
uint8_t *participantCount
|
||||||
);
|
);
|
@@ -1,27 +1,27 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../libs.h"
|
#include "../libs.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
|
||||||
#define POKER_POT_COUNT_MAX POKER_PLAYER_COUNT_MAX
|
#define POKER_POT_COUNT_MAX POKER_PLAYER_COUNT_MAX
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** Current pot of chips */
|
/** Current pot of chips */
|
||||||
uint16_t chips;
|
uint16_t chips;
|
||||||
|
|
||||||
/** Current call value for this pot */
|
/** Current call value for this pot */
|
||||||
uint16_t call;
|
uint16_t call;
|
||||||
|
|
||||||
/** Players who are participating in the pots current bet (in the pot) */
|
/** Players who are participating in the pots current bet (in the pot) */
|
||||||
uint16_t players[POKER_PLAYER_COUNT_MAX];
|
uint16_t players[POKER_PLAYER_COUNT_MAX];
|
||||||
} pokerpot_t;
|
} pokerpot_t;
|
||||||
|
|
||||||
extern pokerpot_t POKER_POTS[];
|
extern pokerpot_t POKER_POTS[];
|
||||||
extern uint8_t POKER_POT_CURRENT;
|
extern uint8_t POKER_POT_CURRENT;
|
||||||
extern uint8_t POKER_POT_COUNT;
|
extern uint8_t POKER_POT_COUNT;
|
@@ -1,30 +1,30 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../libs.h"
|
#include "../libs.h"
|
||||||
|
|
||||||
#define POKER_TURN_MAX_RAISES 0x02
|
#define POKER_TURN_MAX_RAISES 0x02
|
||||||
|
|
||||||
/** Turn Types */
|
/** Turn Types */
|
||||||
#define POKER_TURN_TYPE_OUT 0x00
|
#define POKER_TURN_TYPE_OUT 0x00
|
||||||
#define POKER_TURN_TYPE_FOLD 0x01
|
#define POKER_TURN_TYPE_FOLD 0x01
|
||||||
#define POKER_TURN_TYPE_BET 0x02
|
#define POKER_TURN_TYPE_BET 0x02
|
||||||
#define POKER_TURN_TYPE_CALL 0x03
|
#define POKER_TURN_TYPE_CALL 0x03
|
||||||
#define POKER_TURN_TYPE_ALL_IN 0x04
|
#define POKER_TURN_TYPE_ALL_IN 0x04
|
||||||
#define POKER_TURN_TYPE_CHECK 0x05
|
#define POKER_TURN_TYPE_CHECK 0x05
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** What type of action the turn is */
|
/** What type of action the turn is */
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
/** How many chips they did in their turn (if applicable) */
|
/** How many chips they did in their turn (if applicable) */
|
||||||
uint16_t chips;
|
uint16_t chips;
|
||||||
/** How confident the AI is about their turn. 0 = none, 1000 = full */
|
/** How confident the AI is about their turn. 0 = none, 1000 = full */
|
||||||
uint16_t confidence;
|
uint16_t confidence;
|
||||||
/** Is this turn a bluff? */
|
/** Is this turn a bluff? */
|
||||||
bool bluff;
|
bool bluff;
|
||||||
} pokerturn_t;
|
} pokerturn_t;
|
@@ -1,64 +1,64 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../libs.h"
|
#include "../libs.h"
|
||||||
#include "card.h"
|
#include "card.h"
|
||||||
|
|
||||||
/** Maximum number of cards a winning state can hold. */
|
/** Maximum number of cards a winning state can hold. */
|
||||||
#define POKER_WINNING_FULL_SIZE 0x07
|
#define POKER_WINNING_FULL_SIZE 0x07
|
||||||
|
|
||||||
/** How many cards in the winning set */
|
/** How many cards in the winning set */
|
||||||
#define POKER_WINNING_SET_SIZE 0x05
|
#define POKER_WINNING_SET_SIZE 0x05
|
||||||
|
|
||||||
/** Winning Types */
|
/** Winning Types */
|
||||||
#define POKER_WINNING_TYPE_NULL 0x00
|
#define POKER_WINNING_TYPE_NULL 0x00
|
||||||
#define POKER_WINNING_TYPE_ROYAL_FLUSH 0x01
|
#define POKER_WINNING_TYPE_ROYAL_FLUSH 0x01
|
||||||
#define POKER_WINNING_TYPE_STRAIGHT_FLUSH 0x02
|
#define POKER_WINNING_TYPE_STRAIGHT_FLUSH 0x02
|
||||||
#define POKER_WINNING_TYPE_FOUR_OF_A_KIND 0x03
|
#define POKER_WINNING_TYPE_FOUR_OF_A_KIND 0x03
|
||||||
#define POKER_WINNING_TYPE_FULL_HOUSE 0x04
|
#define POKER_WINNING_TYPE_FULL_HOUSE 0x04
|
||||||
#define POKER_WINNING_TYPE_FLUSH 0x05
|
#define POKER_WINNING_TYPE_FLUSH 0x05
|
||||||
#define POKER_WINNING_TYPE_STRAIGHT 0x06
|
#define POKER_WINNING_TYPE_STRAIGHT 0x06
|
||||||
#define POKER_WINNING_TYPE_THREE_OF_A_KIND 0x07
|
#define POKER_WINNING_TYPE_THREE_OF_A_KIND 0x07
|
||||||
#define POKER_WINNING_TYPE_TWO_PAIR 0x08
|
#define POKER_WINNING_TYPE_TWO_PAIR 0x08
|
||||||
#define POKER_WINNING_TYPE_PAIR 0x09
|
#define POKER_WINNING_TYPE_PAIR 0x09
|
||||||
#define POKER_WINNING_TYPE_HIGH_CARD 0x0A
|
#define POKER_WINNING_TYPE_HIGH_CARD 0x0A
|
||||||
|
|
||||||
/** Confidences of winning based on the current hand type */
|
/** Confidences of winning based on the current hand type */
|
||||||
#define POKER_WINNING_CONFIDENCE_ROYAL_FLUSH 1000
|
#define POKER_WINNING_CONFIDENCE_ROYAL_FLUSH 1000
|
||||||
#define POKER_WINNING_CONFIDENCE_STRAIGHT_FLUSH 990
|
#define POKER_WINNING_CONFIDENCE_STRAIGHT_FLUSH 990
|
||||||
#define POKER_WINNING_CONFIDENCE_FOUR_OF_A_KIND 900
|
#define POKER_WINNING_CONFIDENCE_FOUR_OF_A_KIND 900
|
||||||
#define POKER_WINNING_CONFIDENCE_FULL_HOUSE 850
|
#define POKER_WINNING_CONFIDENCE_FULL_HOUSE 850
|
||||||
#define POKER_WINNING_CONFIDENCE_FLUSH 800
|
#define POKER_WINNING_CONFIDENCE_FLUSH 800
|
||||||
#define POKER_WINNING_CONFIDENCE_STRAIGHT 700
|
#define POKER_WINNING_CONFIDENCE_STRAIGHT 700
|
||||||
#define POKER_WINNING_CONFIDENCE_THREE_OF_A_KIND 500
|
#define POKER_WINNING_CONFIDENCE_THREE_OF_A_KIND 500
|
||||||
#define POKER_WINNING_CONFIDENCE_TWO_PAIR 400
|
#define POKER_WINNING_CONFIDENCE_TWO_PAIR 400
|
||||||
#define POKER_WINNING_CONFIDENCE_PAIR 200
|
#define POKER_WINNING_CONFIDENCE_PAIR 200
|
||||||
#define POKER_WINNING_CONFIDENCE_HIGH_CARD 100
|
#define POKER_WINNING_CONFIDENCE_HIGH_CARD 100
|
||||||
|
|
||||||
/** Holds information about a player's winning state */
|
/** Holds information about a player's winning state */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** The full set of both the dealer and player's hand */
|
/** The full set of both the dealer and player's hand */
|
||||||
uint8_t full[POKER_WINNING_FULL_SIZE];
|
uint8_t full[POKER_WINNING_FULL_SIZE];
|
||||||
uint8_t fullSize;
|
uint8_t fullSize;
|
||||||
|
|
||||||
/** Holds the winning set */
|
/** Holds the winning set */
|
||||||
uint8_t set[POKER_WINNING_SET_SIZE];
|
uint8_t set[POKER_WINNING_SET_SIZE];
|
||||||
uint8_t setSize;
|
uint8_t setSize;
|
||||||
|
|
||||||
/** Winning Type */
|
/** Winning Type */
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
|
||||||
/** If there was a kicker card it will be here, otherwise -1 for no kicker */
|
/** If there was a kicker card it will be here, otherwise -1 for no kicker */
|
||||||
uint8_t kicker;
|
uint8_t kicker;
|
||||||
} pokerplayerwinning_t;
|
} pokerplayerwinning_t;
|
||||||
|
|
||||||
extern pokerplayerwinning_t POKER_WINNERS[POKER_PLAYER_COUNT_MAX];
|
extern pokerplayerwinning_t POKER_WINNERS[POKER_PLAYER_COUNT_MAX];
|
||||||
extern uint8_t POKER_WINNER_PLAYERS[POKER_PLAYER_COUNT_MAX];
|
extern uint8_t POKER_WINNER_PLAYERS[POKER_PLAYER_COUNT_MAX];
|
||||||
extern uint8_t POKER_WINNER_PARTICIPANTS[POKER_PLAYER_COUNT_MAX];
|
extern uint8_t POKER_WINNER_PARTICIPANTS[POKER_PLAYER_COUNT_MAX];
|
||||||
extern uint8_t POKER_WINNER_COUNT;
|
extern uint8_t POKER_WINNER_COUNT;
|
||||||
extern uint8_t POKER_WINNER_PARTICIPANT_COUNT;
|
extern uint8_t POKER_WINNER_PARTICIPANT_COUNT;
|
44
src/sprites/spriteborder.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "spriteborder.h"
|
||||||
|
|
||||||
|
inline void spriteBorderBuffer() {
|
||||||
|
spriteBuffer(SPRITE_BORDER_VRAM_START, BORDER_IMAGE_TILES, BORDER_IMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void spriteBorderBufferEdges(
|
||||||
|
uint8_t *buffer, uint8_t bufferWidth, uint8_t bufferHeight, uint8_t fill
|
||||||
|
) {
|
||||||
|
uint8_t i, j, max;
|
||||||
|
max = bufferWidth * bufferHeight;
|
||||||
|
|
||||||
|
// Corners
|
||||||
|
buffer[0] = SPRITE_BORDER_VRAM_START + SPRITE_BORDER_TOP_LEFT;
|
||||||
|
buffer[bufferWidth-1] = SPRITE_BORDER_VRAM_START + SPRITE_BORDER_TOP_RIGHT;
|
||||||
|
buffer[max-1] = SPRITE_BORDER_VRAM_START + SPRITE_BORDER_BOTTOM_RIGHT;
|
||||||
|
buffer[max-bufferWidth] = SPRITE_BORDER_VRAM_START + SPRITE_BORDER_BOTTOM_LEFT;
|
||||||
|
|
||||||
|
// Edges
|
||||||
|
for(i = 1; i < bufferWidth-1; i++) {
|
||||||
|
buffer[i] = SPRITE_BORDER_VRAM_START + SPRITE_BORDER_BOTTOM_TOP;
|
||||||
|
buffer[max - 1 - i] = SPRITE_BORDER_VRAM_START + SPRITE_BORDER_BOTTOM_TOP;
|
||||||
|
}
|
||||||
|
for(i = 1; i < bufferHeight - 1; i++) {
|
||||||
|
buffer[bufferWidth * i] = SPRITE_BORDER_VRAM_START + SPRITE_BORDER_LEFT_RIGHT;
|
||||||
|
buffer[bufferWidth * (i+1) - 1] = SPRITE_BORDER_VRAM_START + SPRITE_BORDER_LEFT_RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inner
|
||||||
|
if(fill != 0xFF) {
|
||||||
|
for(j = 1; j < bufferHeight-1; j++) {
|
||||||
|
for(i = 1; i < bufferWidth-1; i++) {
|
||||||
|
buffer[i + (j * bufferWidth)] = fill;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
src/sprites/spriteborder.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "../libs.h"
|
||||||
|
#include "sprites.h"
|
||||||
|
#include "BORDER.h"
|
||||||
|
#include "spritefont.h"
|
||||||
|
|
||||||
|
#define SPRITE_BORDER_VRAM_START SPRITE_FONT_VRAM_END
|
||||||
|
#define SPRITE_BORDER_VRAM_END SPRITE_BORDER_VRAM_START + BORDER_IMAGE_TILES
|
||||||
|
|
||||||
|
#define SPRITE_BORDER_TOP_LEFT 0x00
|
||||||
|
#define SPRITE_BORDER_TOP_RIGHT 0x01
|
||||||
|
#define SPRITE_BORDER_LEFT_RIGHT 0x02
|
||||||
|
#define SPRITE_BORDER_BOTTOM_LEFT 0x03
|
||||||
|
#define SPRITE_BORDER_BOTTOM_RIGHT 0x04
|
||||||
|
#define SPRITE_BORDER_BOTTOM_TOP 0x05
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer the border sprite into VRAM.
|
||||||
|
*/
|
||||||
|
inline void spriteBorderBuffer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer the edges of a border to a tile buffer.
|
||||||
|
*
|
||||||
|
* @param buffer Buffer to write the tiles in to.
|
||||||
|
* @param bufferWidth Width of the buffer that you want to write.
|
||||||
|
* @param bufferHeight Height of the buffer that you want to write.
|
||||||
|
* @param fill NULL for no fill, otherwise TILE INDEX of fill within border.
|
||||||
|
*/
|
||||||
|
inline void spriteBorderBufferEdges(
|
||||||
|
uint8_t *buffer, uint8_t bufferWidth, uint8_t bufferHeight, uint8_t fill
|
||||||
|
);
|
38
src/sprites/spritecards.c
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "spritecards.h"
|
||||||
|
|
||||||
|
const uint8_t SPRITE_HEARTS_ACE[SPRITE_CARD_TILE_COUNT] = {
|
||||||
|
SPRITE_CARD_ACE_TOP, SPRITE_CARD_TOP, SPRITE_CARD_TOP, SPRITE_CARD_TOP_RIGHT,
|
||||||
|
SPRITE_CARD_LEFT, SPRITE_CARD_BLANK, SPRITE_CARD_BLANK, SPRITE_CARD_RIGHT,
|
||||||
|
SPRITE_CARD_LEFT, SPRITE_CARD_HEART_BIG_TOP_LEFT, SPRITE_CARD_HEART_BIG_TOP_RIGHT, SPRITE_CARD_RIGHT,
|
||||||
|
SPRITE_CARD_LEFT, SPRITE_CARD_HEART_BIG_BOTTOM_LEFT, SPRITE_CARD_HEART_BIG_BOTTOM_RIGHT, SPRITE_CARD_RIGHT,
|
||||||
|
SPRITE_CARD_LEFT, SPRITE_CARD_BLANK, SPRITE_CARD_BLANK, SPRITE_CARD_RIGHT,
|
||||||
|
SPRITE_CARD_BOTTOM_LEFT, SPRITE_CARD_BOTTOM, SPRITE_CARD_BOTTOM, SPRITE_CARD_BOTTOM_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
// const uint8_t *SPRITE_CARD_LIST[] = {
|
||||||
|
// SPRITE_HEARTS_ACE
|
||||||
|
// };
|
||||||
|
|
||||||
|
inline void spriteCardsBuffer() {
|
||||||
|
spriteBuffer(SPRITE_CARD_VRAM_START, CARDS_TILES_IMAGE_TILES, CARDS_TILES_IMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint8_t * spriteCardsForCard(uint8_t card) {
|
||||||
|
return SPRITE_HEARTS_ACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void spriteCardBufferTiles(uint8_t *buffer, uint8_t card) {
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t *spriteTiles = spriteCardsForCard(card);
|
||||||
|
while(i != SPRITE_CARD_TILE_COUNT) {
|
||||||
|
buffer[i] = spriteTiles[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
68
src/sprites/spritecards.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "../libs.h"
|
||||||
|
#include "CARDS_TILES.h"
|
||||||
|
#include "../poker/card.h"
|
||||||
|
#include "spritetileset.h"
|
||||||
|
#include "sprites.h"
|
||||||
|
#include "spriteborder.h"
|
||||||
|
|
||||||
|
#define SPRITE_CARD_VRAM_START SPRITE_BORDER_VRAM_END
|
||||||
|
|
||||||
|
#define SPRITE_CARD_BLANK SPRITE_TILESET_WHITE
|
||||||
|
|
||||||
|
#define SPRITE_CARD_ACE_TOP SPRITE_CARD_VRAM_START + 0
|
||||||
|
#define SPRITE_CARD_ACE_BOTTOM SPRITE_CARD_ACE_TOP/* ref */
|
||||||
|
#define SPRITE_CARD_TWO_TOP SPRITE_CARD_VRAM_START + 1
|
||||||
|
#define SPRITE_CARD_TWO_BOTTOM SPRITE_CARD_TWO_TOP/* ref */
|
||||||
|
#define SPRITE_CARD_THREE_TOP SPRITE_CARD_VRAM_START + 2
|
||||||
|
#define SPRITE_CARD_THREE_BOTTOM SPRITE_CARD_THREE_TOP/* ref */
|
||||||
|
#define SPRITE_CARD_FOUR_TOP SPRITE_CARD_VRAM_START + 3
|
||||||
|
#define SPRITE_CARD_FOUR_BOTTOM SPRITE_CARD_THREE_TOP/* ref */
|
||||||
|
#define SPRITE_CARD_FIVE_TOP SPRITE_CARD_VRAM_START + 4
|
||||||
|
#define SPRITE_CARD_FIVE_BOTTOM SPRITE_CARD_FIVE_TOP/* ref */
|
||||||
|
#define SPRITE_CARD_SIX_TOP SPRITE_CARD_VRAM_START + 5
|
||||||
|
#define SPRITE_CARD_SIX_BOTTOM SPRITE_CARD_SIX_TOP/* ref */
|
||||||
|
#define SPRITE_CARD_SEVEN_TOP SPRITE_CARD_VRAM_START + 6
|
||||||
|
#define SPRITE_CARD_SEVEN_BOTTOM SPRITE_CARD_SEVEN_TOP/* ref */
|
||||||
|
#define SPRITE_CARD_EIGHT_TOP SPRITE_CARD_VRAM_START + 7
|
||||||
|
#define SPRITE_CARD_EIGHT_BOTTOM SPRITE_CARD_EIGHT_TOP/* ref */
|
||||||
|
#define SPRITE_CARD_NINE_TOP SPRITE_CARD_VRAM_START + 8
|
||||||
|
#define SPRITE_CARD_NINE_BOTTOM SPRITE_CARD_NINE_TOP/* ref */
|
||||||
|
#define SPRITE_CARD_TEN_TOP SPRITE_CARD_VRAM_START + 9
|
||||||
|
#define SPRITE_CARD_TEN_BOTTOM/* ref */
|
||||||
|
|
||||||
|
#define SPRITE_CARD_TOP SPRITE_CARD_VRAM_START + 11
|
||||||
|
#define SPRITE_CARD_TOP_RIGHT SPRITE_CARD_VRAM_START + 10
|
||||||
|
#define SPRITE_CARD_LEFT SPRITE_CARD_TOP/* ref */
|
||||||
|
#define SPRITE_CARD_RIGHT SPRITE_CARD_TOP/* ref */
|
||||||
|
#define SPRITE_CARD_BOTTOM_LEFT SPRITE_CARD_TOP_RIGHT/* ref */
|
||||||
|
#define SPRITE_CARD_BOTTOM_RIGHT SPRITE_CARD_TOP_RIGHT/* ref */
|
||||||
|
#define SPRITE_CARD_BOTTOM SPRITE_CARD_TOP/* ref */
|
||||||
|
|
||||||
|
#define SPRITE_CARD_DIAMOND_BIG_TOP_LEFT SPRITE_CARD_VRAM_START + 12
|
||||||
|
#define SPRITE_CARD_DIAMOND_BIG_TOP_RIGHT SPRITE_CARD_DIAMOND_BIG_TOP_LEFT/* ref */
|
||||||
|
#define SPRITE_CARD_DIAMOND_BIG_BOTTOM_LEFT SPRITE_CARD_DIAMOND_BIG_TOP_LEFT/* ref */
|
||||||
|
#define SPRITE_CARD_DIAMOND_BIG_BOTTOM_RIGHT SPRITE_CARD_DIAMOND_BIG_TOP_LEFT/* ref */
|
||||||
|
#define SPRITE_CARD_HEART_BIG_TOP_LEFT SPRITE_CARD_VRAM_START + 13
|
||||||
|
#define SPRITE_CARD_HEART_BIG_TOP_RIGHT SPRITE_CARD_HEART_BIG_TOP_LEFT/* ref */
|
||||||
|
#define SPRITE_CARD_HEART_BIG_BOTTOM_LEFT SPRITE_CARD_DIAMOND_BIG_BOTTOM_LEFT
|
||||||
|
#define SPRITE_CARD_HEART_BIG_BOTTOM_RIGHT SPRITE_CARD_DIAMOND_BIG_BOTTOM_RIGHT
|
||||||
|
|
||||||
|
#define SPRITE_CARD_WIDTH 4
|
||||||
|
#define SPRITE_CARD_HEIGHT 6
|
||||||
|
#define SPRITE_CARD_TILE_COUNT (SPRITE_CARD_WIDTH * SPRITE_CARD_HEIGHT)
|
||||||
|
|
||||||
|
extern const uint8_t SPRITE_HEARTS_ACE[];
|
||||||
|
|
||||||
|
inline void spriteCardsBuffer();
|
||||||
|
|
||||||
|
inline uint8_t * spriteCardsForCard(uint8_t card);
|
||||||
|
|
||||||
|
inline void spriteCardBufferTiles(uint8_t *buffer, uint8_t card);
|
16
src/sprites/spritefont.c
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "spritefont.h"
|
||||||
|
|
||||||
|
inline void spriteFontBuffer() {
|
||||||
|
spriteBuffer(SPRITE_FONT_VRAM_START, FONT_IMAGE_TILES, FONT_IMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint8_t spriteFontTileFromChar(char character) {
|
||||||
|
return character - SPRITE_FONT_FIRST_CHARACTER + SPRITE_FONT_VRAM_START;
|
||||||
|
}
|
30
src/sprites/spritefont.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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"
|
||||||
|
#include "sprites.h"
|
||||||
|
#include "spritetileset.h"
|
||||||
|
|
||||||
|
#define SPRITE_FONT_FIRST_CHARACTER 33
|
||||||
|
|
||||||
|
#define SPRITE_FONT_VRAM_START SPRITE_TILESET_VRAM_END
|
||||||
|
#define SPRITE_FONT_VRAM_END SPRITE_FONT_VRAM_START + FONT_IMAGE_TILES
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer the font tiles to VRAM.
|
||||||
|
*/
|
||||||
|
inline void spriteFontBuffer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the tile index for a given character (ASCII).
|
||||||
|
*
|
||||||
|
* @param character Character to get the tile index from.
|
||||||
|
* @return The tile index for the given character.
|
||||||
|
*/
|
||||||
|
inline uint8_t spriteFontTileFromChar(char character);
|
12
src/sprites/sprites.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sprites.h"
|
||||||
|
|
||||||
|
inline void spriteBuffer(uint8_t position, uint8_t length, uint8_t *tiles) {
|
||||||
|
set_bkg_data(position, length, tiles);
|
||||||
|
}
|
18
src/sprites/sprites.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "../libs.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer tiles data into VRAM
|
||||||
|
*
|
||||||
|
* @param position Position in VRAM to buffer in to.
|
||||||
|
* @param length Length of the data being buffered (count of tiles).
|
||||||
|
* @param tiles Pointer to array of tiles to be bufffered.
|
||||||
|
*/
|
||||||
|
inline void spriteBuffer(uint8_t position, uint8_t length, uint8_t *tiles);
|
12
src/sprites/spritetileset.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "spritetileset.h"
|
||||||
|
|
||||||
|
void spriteTilesetBuffer() {
|
||||||
|
spriteBuffer(SPRITE_TILESET_VRAM_START, TILESET_IMAGE_TILES, TILESET_IMAGE);
|
||||||
|
}
|
50
src/sprites/spritetileset.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "../libs.h"
|
||||||
|
#include "TILESET.h"
|
||||||
|
#include "sprites.h"
|
||||||
|
|
||||||
|
#define SPRITE_TILESET_VRAM_START 0x00
|
||||||
|
#define SPRITE_TILESET_VRAM_END SPRITE_TILESET_VRAM_START + TILESET_IMAGE_TILES
|
||||||
|
|
||||||
|
#define SPRITE_TILESET_TILE_0 SPRITE_TILESET_VRAM_START + 0x00
|
||||||
|
#define SPRITE_TILESET_TILE_1 SPRITE_TILESET_VRAM_START + 0x01
|
||||||
|
#define SPRITE_TILESET_TILE_2 SPRITE_TILESET_VRAM_START + 0x02
|
||||||
|
#define SPRITE_TILESET_TILE_3 SPRITE_TILESET_VRAM_START + 0x03
|
||||||
|
|
||||||
|
#define SPRITE_TILESET_WHITE SPRITE_TILESET_TILE_0
|
||||||
|
#define SPRITE_TILESET_BLACK SPRITE_TILESET_TILE_3
|
||||||
|
#define SPRITE_TILESET_LIGHT SPRITE_TILESET_TILE_1
|
||||||
|
#define SPRITE_TILESET_DARK SPRITE_TILESET_TILE_2
|
||||||
|
|
||||||
|
|
||||||
|
// Shades are mapped where each set of 4 colors is mapped to two bits that will
|
||||||
|
// specify its darkness. Higher = Darker, Lower = Brighter
|
||||||
|
// 11 11 11 11
|
||||||
|
#define TILESET_SHADE_BLACK 0xFF
|
||||||
|
// 11 11 11 10
|
||||||
|
#define TILESET_SHADE_DARKER 0xFE
|
||||||
|
// 11 11 10 01
|
||||||
|
#define TILESET_SHADE_DARK 0xF9
|
||||||
|
// 11 10 01 00
|
||||||
|
#define TILESET_SHADE_NORMAL 0xE4
|
||||||
|
// 10 01 00 00
|
||||||
|
#define TILESET_SHADE_BRIGHT 0x90
|
||||||
|
// 01 00 00 00
|
||||||
|
#define TILESET_SHADE_BRIGHTER 0x40
|
||||||
|
// 00 00 00 00
|
||||||
|
#define TILESET_SHADE_WHITE 0x00
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer the TILESET tileset sprites onto VRAM.
|
||||||
|
*
|
||||||
|
* @param position Position in VRAM to buuffer on to.
|
||||||
|
*/
|
||||||
|
void spriteTilesetBuffer();
|
@@ -1,33 +1,33 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
|
|
||||||
const char STR_ERROR[] = "An error\nhas occured";
|
const char STR_ERROR[] = "An error\nhas occured";
|
||||||
const char STR_HELLO[] = "Hello World, How are you today?\nGood thanks. Thank god!";
|
const char STR_HELLO[] = "Hello World, How are you today?\nGood thanks. Thank god!";
|
||||||
|
|
||||||
const char STR_POKER_GAME_START[] = "Poker game started";
|
const char STR_POKER_GAME_START[] = "Poker game started";
|
||||||
const char STR_POKER_GAME_TAKING_BLINDS[] = "Blinds taken.";
|
const char STR_POKER_GAME_TAKING_BLINDS[] = "Blinds taken.";
|
||||||
const char STR_POKER_GAME_CARDS_DEALT[] = "Cards dealt.";
|
const char STR_POKER_GAME_CARDS_DEALT[] = "Cards dealt.";
|
||||||
|
|
||||||
const char STR_POKER_GAME_CARDS_FLOPPED[] = "Cards flopped";
|
const char STR_POKER_GAME_CARDS_FLOPPED[] = "Cards flopped";
|
||||||
const char STR_POKER_GAME_CARDS_TURNED[] = "Cards turned";
|
const char STR_POKER_GAME_CARDS_TURNED[] = "Cards turned";
|
||||||
const char STR_POKER_GAME_CARDS_RIVERED[] = "Cards river";
|
const char STR_POKER_GAME_CARDS_RIVERED[] = "Cards river";
|
||||||
|
|
||||||
const char STR_DEBUG_WINNER_DECIDED[] = "DEBUG WINNER";
|
const char STR_DEBUG_WINNER_DECIDED[] = "DEBUG WINNER";
|
||||||
const char STR_DEBUG_PLAYER[] = "DEBUG PLAYER";
|
const char STR_DEBUG_PLAYER[] = "DEBUG PLAYER";
|
||||||
|
|
||||||
const char STR_POKER_GAME_AI_FOLD[] = "AI Folding";
|
const char STR_POKER_GAME_AI_FOLD[] = "AI Folding";
|
||||||
const char STR_POKER_GAME_AI_RAISE[] = "AI Raise";
|
const char STR_POKER_GAME_AI_RAISE[] = "AI Raise";
|
||||||
const char STR_POKER_GAME_AI_RAISE_BLUFF[] = "AI Raise\nBut Bluffing";
|
const char STR_POKER_GAME_AI_RAISE_BLUFF[] = "AI Raise\nBut Bluffing";
|
||||||
const char STR_POKER_GAME_AI_CALL[] = "AI Calling";
|
const char STR_POKER_GAME_AI_CALL[] = "AI Calling";
|
||||||
const char STR_POKER_GAME_AI_CALL_BLUFF[] = "AI Calling\nBut Bluffing";
|
const char STR_POKER_GAME_AI_CALL_BLUFF[] = "AI Calling\nBut Bluffing";
|
||||||
const char STR_POKER_GAME_AI_ALL_IN[] = "AI All In";
|
const char STR_POKER_GAME_AI_ALL_IN[] = "AI All In";
|
||||||
const char STR_POKER_GAME_AI_ALL_IN_BLUFF[] = "AI All In\nBut Bluffing";
|
const char STR_POKER_GAME_AI_ALL_IN_BLUFF[] = "AI All In\nBut Bluffing";
|
||||||
const char STR_POKER_GAME_AI_CHECK[] = "AI Checking";
|
const char STR_POKER_GAME_AI_CHECK[] = "AI Checking";
|
||||||
const char STR_POKER_GAME_AI_CHECK_BLUFF[] = "AI Checking\nBut Bluffing";
|
const char STR_POKER_GAME_AI_CHECK_BLUFF[] = "AI Checking\nBut Bluffing";
|
||||||
const char STR_FOX[] = "The quick brown fox jumps over the lazy dog.";
|
const char STR_FOX[] = "The quick brown fox jumps over the lazy dog.";
|
@@ -1,34 +1,34 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "libs.h"
|
#include "libs.h"
|
||||||
|
|
||||||
extern const char STR_ERROR[];
|
extern const char STR_ERROR[];
|
||||||
extern const char STR_HELLO[];
|
extern const char STR_HELLO[];
|
||||||
|
|
||||||
extern const char STR_POKER_GAME_START[];
|
extern const char STR_POKER_GAME_START[];
|
||||||
extern const char STR_POKER_GAME_TAKING_BLINDS[];
|
extern const char STR_POKER_GAME_TAKING_BLINDS[];
|
||||||
extern const char STR_POKER_GAME_CARDS_DEALT[];
|
extern const char STR_POKER_GAME_CARDS_DEALT[];
|
||||||
|
|
||||||
extern const char STR_POKER_GAME_CARDS_FLOPPED[];
|
extern const char STR_POKER_GAME_CARDS_FLOPPED[];
|
||||||
extern const char STR_POKER_GAME_CARDS_TURNED[];
|
extern const char STR_POKER_GAME_CARDS_TURNED[];
|
||||||
extern const char STR_POKER_GAME_CARDS_RIVERED[];
|
extern const char STR_POKER_GAME_CARDS_RIVERED[];
|
||||||
|
|
||||||
extern const char STR_DEBUG_WINNER_DECIDED[];
|
extern const char STR_DEBUG_WINNER_DECIDED[];
|
||||||
extern const char STR_DEBUG_PLAYER[];
|
extern const char STR_DEBUG_PLAYER[];
|
||||||
|
|
||||||
extern const char STR_POKER_GAME_AI_FOLD[];
|
extern const char STR_POKER_GAME_AI_FOLD[];
|
||||||
extern const char STR_POKER_GAME_AI_RAISE[];
|
extern const char STR_POKER_GAME_AI_RAISE[];
|
||||||
extern const char STR_POKER_GAME_AI_RAISE_BLUFF[];
|
extern const char STR_POKER_GAME_AI_RAISE_BLUFF[];
|
||||||
extern const char STR_POKER_GAME_AI_CALL[];
|
extern const char STR_POKER_GAME_AI_CALL[];
|
||||||
extern const char STR_POKER_GAME_AI_CALL_BLUFF[];
|
extern const char STR_POKER_GAME_AI_CALL_BLUFF[];
|
||||||
extern const char STR_POKER_GAME_AI_ALL_IN[];
|
extern const char STR_POKER_GAME_AI_ALL_IN[];
|
||||||
extern const char STR_POKER_GAME_AI_ALL_IN_BLUFF[];
|
extern const char STR_POKER_GAME_AI_ALL_IN_BLUFF[];
|
||||||
extern const char STR_POKER_GAME_AI_CHECK[];
|
extern const char STR_POKER_GAME_AI_CHECK[];
|
||||||
extern const char STR_POKER_GAME_AI_CHECK_BLUFF[];
|
extern const char STR_POKER_GAME_AI_CHECK_BLUFF[];
|
||||||
extern const char STR_FOX[];
|
extern const char STR_FOX[];
|
42
src/time.c
@@ -1,22 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
|
||||||
uint16_t TIME_CURRENT;
|
uint16_t TIME_CURRENT;
|
||||||
uint16_t TIME_FUTURE;
|
uint16_t TIME_FUTURE;
|
||||||
uint8_t TIME_FUTURE_TYPE;
|
uint8_t TIME_FUTURE_TYPE;
|
||||||
|
|
||||||
inline void timeInit() {
|
inline void timeInit() {
|
||||||
TIME_CURRENT = 0;
|
TIME_CURRENT = 0;
|
||||||
TIME_FUTURE = 0;
|
TIME_FUTURE = 0;
|
||||||
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_NULL;
|
TIME_FUTURE_TYPE = TIME_FUTURE_TYPE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void timeUpdate() {
|
inline void timeUpdate() {
|
||||||
TIME_CURRENT++;
|
TIME_CURRENT++;
|
||||||
}
|
}
|
48
src/time.h
@@ -1,25 +1,25 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "libs.h"
|
#include "libs.h"
|
||||||
|
|
||||||
#define TIME_PER_SECOND 60
|
#define TIME_PER_SECOND 60
|
||||||
|
|
||||||
#define TIME_FUTURE_TYPE_NULL 0x00
|
#define TIME_FUTURE_TYPE_NULL 0x00
|
||||||
#define TIME_FUTURE_TYPE_PAUSE 0x01
|
#define TIME_FUTURE_TYPE_PAUSE 0x01
|
||||||
#define TIME_FUTURE_TYPE_FADE_TO_BLACK 0x02
|
#define TIME_FUTURE_TYPE_FADE_TO_BLACK 0x02
|
||||||
#define TIME_FUTURE_TYPE_FADE_FROM_BLACK 0x03
|
#define TIME_FUTURE_TYPE_FADE_FROM_BLACK 0x03
|
||||||
#define TIME_FUTURE_TYPE_FADE_TO_WHITE 0x04
|
#define TIME_FUTURE_TYPE_FADE_TO_WHITE 0x04
|
||||||
#define TIME_FUTURE_TYPE_FADE_FROM_WHITE 0x05
|
#define TIME_FUTURE_TYPE_FADE_FROM_WHITE 0x05
|
||||||
|
|
||||||
extern uint16_t TIME_CURRENT;
|
extern uint16_t TIME_CURRENT;
|
||||||
extern uint16_t TIME_FUTURE;
|
extern uint16_t TIME_FUTURE;
|
||||||
extern uint8_t TIME_FUTURE_TYPE;
|
extern uint8_t TIME_FUTURE_TYPE;
|
||||||
|
|
||||||
inline void timeInit();
|
inline void timeInit();
|
||||||
inline void timeUpdate();
|
inline void timeUpdate();
|
24
src/util.h
@@ -1,13 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2022 Dominic Masters
|
* Copyright (c) 2022 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "libs.h"
|
#include "libs.h"
|
||||||
|
|
||||||
#define MATH_MIN(a, b) a > b ? b : a
|
#define MATH_MIN(a, b) a > b ? b : a
|
||||||
#define MATH_MAX(a, b) a < b ? b : a
|
#define MATH_MAX(a, b) a < b ? b : a
|
||||||
#define MATH_ABS(n) (n < 0 ? -n : n)
|
#define MATH_ABS(n) (n < 0 ? -n : n)
|
14
test.sh
@@ -1,8 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Send over latest build
|
# Send over latest build
|
||||||
scp ./build/Penny.gb root@ywbud3:/storage/roms/gb/Penny.gb
|
scp ./build/Penny.gb root@ywbud3:/storage/roms/gb/Penny.gb
|
||||||
|
|
||||||
systemctl stop emustation.service
|
systemctl stop emustation.service
|
||||||
killall emulationstation
|
killall emulationstation
|
||||||
retroarch -L /lib/libretro/gambatte_libretro.so "/storage/roms/gb/Penny.gb"
|
retroarch -L /lib/libretro/gambatte_libretro.so "/storage/roms/gb/Penny.gb"
|
||||||
systemctl start emustation.service
|
systemctl start emustation.service
|