Added JS engine.
This commit is contained in:
@ -11,7 +11,7 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
#Include
|
||||
include(FetchContent)
|
||||
|
||||
################################ Setting Degs ##################################
|
||||
################################ Setting Defs ##################################
|
||||
set(SETTING_PLATFORM_GLFW 1)
|
||||
set(SETTING_PLATFORM_SDL 2)
|
||||
|
||||
@ -130,6 +130,10 @@ if(NOT cglm_FOUND)
|
||||
endif()
|
||||
target_link_libraries(${PROJECT_NAME} cglm)
|
||||
|
||||
# Duktape
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/lib/duktape)
|
||||
target_link_libraries(${PROJECT_NAME} duktape)
|
||||
|
||||
# OpenGL
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
|
@ -69,6 +69,9 @@
|
||||
#include "poker/turn.h"
|
||||
#include "poker/winner.h"
|
||||
|
||||
// Script engine
|
||||
#include "script/scripter.h"
|
||||
|
||||
// User Interface Objects
|
||||
#include "ui/align.h"
|
||||
#include "ui/breakpoint.h"
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "pokerworld.h"
|
||||
#include "pokergameaction.h"
|
||||
#include "ui/pokerui.h"
|
||||
#include "../../engine/engine.h"
|
||||
#include "../../poker/poker.h"
|
||||
#include "../../poker/player.h"
|
||||
#include "../../poker/dealer.h"
|
||||
@ -58,4 +59,7 @@ typedef struct {
|
||||
|
||||
/** Data for the actions */
|
||||
pokergameactiondata_t actionData[ANIMATION_QUEUE_ITEM_MAX];
|
||||
|
||||
/** Pointer back to the game engine */
|
||||
engine_t *engine;
|
||||
} pokergame_t;
|
@ -17,6 +17,7 @@ typedef struct {
|
||||
|
||||
texture_t testTexture;
|
||||
texture_t roomTexture;
|
||||
texture_t cardTexture;
|
||||
|
||||
texture_t pennyTexture;
|
||||
} pokergameassets_t;
|
@ -17,6 +17,9 @@
|
||||
#include "../../../ui/align.h"
|
||||
|
||||
#define POKER_PLAYER_UI_IMAGE_SIZE 64
|
||||
#define POKER_PLAYER_UI_WIDTH 300
|
||||
#define POKER_PLAYER_UI_HEIGHT POKER_PLAYER_UI_IMAGE_SIZE
|
||||
|
||||
#define POKER_PLAYER_UI_IMAGE_RESOLUTION POKER_PLAYER_UI_IMAGE_SIZE * 2
|
||||
#define POKER_PLAYER_UI_IMAGE_DIST 0.8f
|
||||
#define POKER_PLAYER_UI_IMAGE_Y 0.1f
|
||||
|
@ -9,7 +9,9 @@
|
||||
#include "../../../libs.h"
|
||||
#include "../../../poker/player.h"
|
||||
#include "pokerplayerui.h"
|
||||
#include "../../../ui/image.h"
|
||||
|
||||
typedef struct {
|
||||
pokerplayerui_t player[POKER_PLAYER_COUNT];
|
||||
image_t card;
|
||||
} pokerui_t;
|
@ -10,6 +10,7 @@
|
||||
|
||||
// Static Libs
|
||||
#include <cglm/cglm.h>
|
||||
#include <duktape.h>
|
||||
|
||||
#if SETTING_PLATFORM_USE_GLAD == 1
|
||||
#include <glad/glad.h>
|
||||
|
@ -21,6 +21,16 @@
|
||||
#define POKER_TURN_CARD_COUNT 1
|
||||
#define POKER_RIVER_CARD_COUNT 1
|
||||
|
||||
|
||||
#define POKER_STATE_NULL 0x00
|
||||
#define POKER_STATE_STARTING_MATCH 0x01
|
||||
#define POKER_STATE_STARTING_ROUND 0x02
|
||||
#define POKER_STATE_TAKING_BLINDS 0x03
|
||||
#define POKER_STATE_DEALING 0x04
|
||||
#define POKER_STATE_CARDS_FLOPPING 0x05
|
||||
#define POKER_STATE_BETTING 0x06
|
||||
#define POKER_STATE_DECIDING_WINNER 0x07
|
||||
|
||||
typedef struct {
|
||||
/** Poker betting state */
|
||||
pokerbet_t bet;
|
||||
@ -40,4 +50,6 @@ typedef struct {
|
||||
|
||||
/** Which player is the big blind for this round */
|
||||
uint8_t roundBigBlind;
|
||||
|
||||
uint8_t state;
|
||||
} poker_t;
|
24
include/dawn/script/scripter.h
Normal file
24
include/dawn/script/scripter.h
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "../libs.h"
|
||||
|
||||
/** Implies that the arguments the function will take is variable */
|
||||
#define SCRIPTER_VARIABLE_ARGUMENT_COUNT DUK_VARARGS
|
||||
|
||||
/** Global context defintion of the pointer referring back to the scripter */
|
||||
#define SCRIPTER_SELF_NAME "__scripter"
|
||||
|
||||
/** Type forwarders */
|
||||
typedef duk_context scriptercontext_t;
|
||||
typedef duk_ret_t scripterreturn_t;
|
||||
|
||||
typedef struct {
|
||||
duk_context *context;
|
||||
engine_t *engine;
|
||||
void *user;
|
||||
} scripter_t;
|
||||
|
||||
typedef scripterreturn_t scriptermethod_t(scriptercontext_t *context);
|
@ -12,7 +12,5 @@
|
||||
typedef struct {
|
||||
texture_t *texture;
|
||||
primitive_t quad;
|
||||
float u0, v0;
|
||||
float u1, v1;
|
||||
float width, height;
|
||||
} image_t;
|
@ -5,7 +5,11 @@
|
||||
"author": "Dominic Masters <dominic@domsplace.com>",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "tsc -p ."
|
||||
},
|
||||
"dependencies": {
|
||||
"pngjs": "^6.0.0"
|
||||
"tsc": "^2.0.3",
|
||||
"typescript": "^4.4.3"
|
||||
}
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
const path = require('path');
|
||||
const { imageCreate, imageWrite, imageLoad, imageCopy } = require('./../../utils/image');
|
||||
const fs =require('fs');
|
||||
|
||||
// Where to crop
|
||||
const FACE_AREA = { x: 367, y: 256, width: 280, height: 280 };
|
||||
|
||||
// Where the images are stored
|
||||
const IMAGES_ROOT = path.join(...[
|
||||
'.',
|
||||
'assets',
|
||||
'characters',
|
||||
'penny',
|
||||
'sprites'
|
||||
]);
|
||||
|
||||
// Which image directories to crop
|
||||
const IMAGES_DIRECTORIES = [ 'eyebrows', 'eyes', 'mouths' ];
|
||||
|
||||
(async () => {
|
||||
// Load the base
|
||||
const base = await imageLoad(path.join(IMAGES_ROOT, 'dealer.png'));
|
||||
|
||||
let columnsMax = 0;
|
||||
for(let row = 0; row < IMAGES_DIRECTORIES.length; row++) {
|
||||
const dir = path.join(IMAGES_ROOT, IMAGES_DIRECTORIES[row]);
|
||||
const scan = fs.readdirSync(dir);
|
||||
columnsMax = Math.max(scan.length, columnsMax);
|
||||
}
|
||||
|
||||
// Create the output buffer
|
||||
const out = imageCreate(base.width+(columnsMax*FACE_AREA.width), base.height);
|
||||
|
||||
// Copy the base
|
||||
imageCopy(out, base, 0, 0);
|
||||
|
||||
// Now begin copying the children, row is defined by the directory
|
||||
for(let row = 0; row < IMAGES_DIRECTORIES.length; row++) {
|
||||
const dir = path.join(IMAGES_ROOT, IMAGES_DIRECTORIES[row]);
|
||||
const scan = fs.readdirSync(dir);
|
||||
|
||||
// Column defined by the file index
|
||||
for(let col = 0; col < scan.length; col++) {
|
||||
const img = await imageLoad(path.join(dir, scan[col]));
|
||||
console.log('Copying', scan[col]);
|
||||
|
||||
imageCopy(out, img,
|
||||
base.width+(col*FACE_AREA.width), FACE_AREA.height*row,
|
||||
FACE_AREA
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
await imageWrite(out, path.join(IMAGES_ROOT, 'sheet.png'));
|
||||
})().catch(console.error);
|
@ -1,56 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Constants
|
||||
const WORLD_LOAD_TOKEN = ";";
|
||||
const TILE_FLAG_DYNAMIC = 1;
|
||||
|
||||
// Method.
|
||||
const saveWorld = (world) => {
|
||||
const pathWorld = path.join(__dirname, '..', '..', 'assets', world.name);
|
||||
if(!fs.existsSync(pathWorld)) fs.mkdirSync(pathWorld);
|
||||
|
||||
// World string buffer (file data).
|
||||
let strBuffer = "";
|
||||
|
||||
// Header
|
||||
strBuffer += [
|
||||
world.version,
|
||||
world.tileset,
|
||||
""// Seal
|
||||
].join(WORLD_LOAD_TOKEN);
|
||||
|
||||
// Tilemap Definition
|
||||
let buffer = [];
|
||||
for(let i = 0; i < world.tilemap.length; i++) {
|
||||
let tileDef = world.tilemap[i];
|
||||
buffer.push(tileDef.verticeCount+'');
|
||||
buffer.push(tileDef.indiceCount+'');
|
||||
buffer.push(tileDef.flags+'');
|
||||
}
|
||||
strBuffer += buffer.join(WORLD_LOAD_TOKEN);
|
||||
|
||||
fs.writeFileSync(path.join(pathWorld, 'world.txt'), strBuffer);
|
||||
}
|
||||
|
||||
// Worlds.
|
||||
const TILEMAP_WIDTH = 8;
|
||||
const TILEMAP_HEIGHT = 298;
|
||||
|
||||
let world = {
|
||||
version: '1.00',
|
||||
tileset: 'tileset.png',
|
||||
name: 'testworld',
|
||||
tilemap: [ ]
|
||||
};
|
||||
|
||||
for(let i = 0; i < TILEMAP_WIDTH * TILEMAP_HEIGHT; i++) {
|
||||
world.tilemap[i] = {
|
||||
indiceCount: 6,
|
||||
verticeCount: 4,
|
||||
flags: 0
|
||||
};
|
||||
}
|
||||
|
||||
console.log('bruh', world);
|
||||
saveWorld(world);
|
File diff suppressed because it is too large
Load Diff
@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "../primitive.h"
|
||||
|
||||
#define POKER_CHIP_NAME "Poker Chip"
|
||||
#define POKER_CHIP_VERTICE_COUNT 5249
|
||||
#define POKER_CHIP_INDICE_COUNT 29874
|
||||
#define POKER_CHIP_TRIANGLE_COUNT 9958
|
||||
|
||||
/**
|
||||
* Generated Model Poker Chip
|
||||
* Generated at Sun, 30 May 2021 01:23:51 GMT
|
||||
* @returns Poker Chip as a primitive.
|
||||
*/
|
||||
primitive_t * pokerChipCreate();
|
@ -1,143 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const MODEL_NAME = 'Poker Chip';
|
||||
const FLIP_TEXTURE_Y = true;
|
||||
|
||||
let rawVertices = [];
|
||||
let faces = [];
|
||||
let coordinates = [];
|
||||
const filePath = path.join(__dirname, '..', '..', 'assets', 'models', 'poker table_del', 'poker_table.obj');
|
||||
const data = fs.readFileSync(filePath, 'utf-8');
|
||||
|
||||
const scale = 0.1;
|
||||
|
||||
data.split('\n').forEach(line => {
|
||||
const bits = line.trim().split(' ');
|
||||
if(!bits.length || bits.every(n => !n || !bits.length)) return;
|
||||
const lineType = bits.shift();
|
||||
|
||||
if(lineType === 'v') {
|
||||
const [ x, y, z ] = bits.map(n => {
|
||||
const val = parseFloat(n) * scale;
|
||||
return val;
|
||||
});
|
||||
rawVertices.push({ x, y, z });
|
||||
} else if(lineType === 'vt') {
|
||||
let [ u, v ] = bits.map(n => parseFloat(n));
|
||||
if(FLIP_TEXTURE_Y) v = 1 - v;
|
||||
coordinates.push({ u, v });
|
||||
} else if(lineType === 'f') {
|
||||
faces.push(bits.map(n => {
|
||||
const [ vertice, coordinate ] = n.split('/').map(n => parseInt(n));
|
||||
return { vertice, coordinate };
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
const verticeCompare = (vl, vr) => (
|
||||
vl.x === vr.x &&
|
||||
vl.y === vr.y &&
|
||||
vl.z === vr.z &&
|
||||
vl.u === vr.u &&
|
||||
vl.v === vr.v
|
||||
);
|
||||
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
|
||||
faces.forEach(face => {
|
||||
face.forEach(faceIndice => {
|
||||
const rawVert = rawVertices[faceIndice.vertice-1];
|
||||
const rawCoord = coordinates[faceIndice.coordinate-1];
|
||||
const vertice = { ...rawVert, ...rawCoord };
|
||||
|
||||
const indice = vertices.findIndex(vert => {
|
||||
return verticeCompare(vert, vertice);
|
||||
});
|
||||
|
||||
if(indice === -1) {
|
||||
indices.push(vertices.length);
|
||||
vertices.push(vertice);
|
||||
} else {
|
||||
indices.push(indice);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
const MODEL_NAME_CAPS = MODEL_NAME.replace(/\s/g, '_').toUpperCase();
|
||||
const MODEL_NAME_CAMEL = [
|
||||
MODEL_NAME[0].toLowerCase(),
|
||||
MODEL_NAME.split(' ').join('').substr(1)
|
||||
].join('')
|
||||
// const fn = MODEL_NAME.toLowerCase().split(' ').join('');
|
||||
const fn = 'model';
|
||||
|
||||
const license = `/**
|
||||
* Copyright (c) ${new Date().getFullYear()} Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
`;
|
||||
|
||||
// Write header file
|
||||
const header = `${license}
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "../primitive.h"
|
||||
|
||||
#define ${MODEL_NAME_CAPS}_NAME "${MODEL_NAME}"
|
||||
#define ${MODEL_NAME_CAPS}_VERTICE_COUNT ${vertices.length}
|
||||
#define ${MODEL_NAME_CAPS}_INDICE_COUNT ${indices.length}
|
||||
#define ${MODEL_NAME_CAPS}_TRIANGLE_COUNT ${indices.length/3}
|
||||
|
||||
/**
|
||||
* Generated Model ${MODEL_NAME}
|
||||
* Generated at ${new Date().toUTCString()}
|
||||
* @returns ${MODEL_NAME} as a primitive.
|
||||
*/
|
||||
void ${MODEL_NAME_CAMEL}Init(primitive_t *primitive);
|
||||
`;
|
||||
|
||||
// Write Source file
|
||||
const strVertices = vertices.map((v,i) => {
|
||||
return `{ .x = ${v.x}, .y = ${v.y}, .z = ${v.z}, .u = ${v.u}, .v = ${v.v} }`;
|
||||
}).join(',\n ');
|
||||
|
||||
const strIndices = indices.map(i => {
|
||||
return `${i}`;
|
||||
}).join(',\n ');
|
||||
|
||||
const source = `${license}
|
||||
#include "${fn}.h"
|
||||
|
||||
primitive_t * ${MODEL_NAME_CAMEL}Create(primitive_t *primitive) {
|
||||
vertice_t vertices[${MODEL_NAME_CAPS}_VERTICE_COUNT] = {
|
||||
${strVertices}
|
||||
};
|
||||
|
||||
indice_t indices[${MODEL_NAME_CAPS}_INDICE_COUNT] = {
|
||||
${strIndices}
|
||||
};
|
||||
|
||||
primitiveInit(
|
||||
${MODEL_NAME_CAPS}_VERTICE_COUNT,
|
||||
${MODEL_NAME_CAPS}_INDICE_COUNT
|
||||
);
|
||||
|
||||
primitiveBufferVertices(primitive, 0, ${MODEL_NAME_CAPS}_VERTICE_COUNT, vertices);
|
||||
primitiveBufferIndices(primitive, 0, ${MODEL_NAME_CAPS}_INDICE_COUNT, indices);
|
||||
return primitive;
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
fs.writeFileSync(path.join(__dirname, fn+'.h'), header);
|
||||
fs.writeFileSync(path.join(__dirname, fn+'.c'), source);
|
@ -1,96 +0,0 @@
|
||||
const fs = require("fs");
|
||||
const path = require('path');
|
||||
const { PNG } = require("pngjs");
|
||||
|
||||
// Constants
|
||||
const IMAGES_ROOT = path.join(...[
|
||||
'.',
|
||||
'assets',
|
||||
'characters',
|
||||
'penny',
|
||||
'Sample sets',
|
||||
'Mouth'
|
||||
]);
|
||||
|
||||
const FILE_OUT = path.join(...[
|
||||
'.',
|
||||
'assets',
|
||||
'characters',
|
||||
'penny',
|
||||
'textures',
|
||||
'mouth.png'
|
||||
])
|
||||
|
||||
|
||||
// Code
|
||||
const imageLoad = (image) => new Promise(resolve => {
|
||||
fs.createReadStream(image)
|
||||
.pipe(new PNG({ filterType: 4 }))
|
||||
.on("parsed", function () {
|
||||
// Normalize
|
||||
const pixels = [];
|
||||
for(let y = 0; y < this.height; y++) {
|
||||
for(let x = 0; x < this.width; x++) {
|
||||
const idx = (this.width * y + x) << 2;
|
||||
const r = this.data[idx];
|
||||
const g = this.data[idx + 1];
|
||||
const b = this.data[idx + 2];
|
||||
const a = this.data[idx + 3];
|
||||
|
||||
pixels.push({ r, g, b, a });
|
||||
}
|
||||
}
|
||||
resolve({ pixels, width: this.width, height: this.height });
|
||||
})
|
||||
;
|
||||
});
|
||||
|
||||
const imageWrite = (image, file) => new Promise(resolve => {
|
||||
const png = new PNG({ width: image.width, height: image.height });
|
||||
png.width = image.width;
|
||||
png.height = image.height;
|
||||
|
||||
for(let y = 0; y < image.height; y++) {
|
||||
for(let x = 0; x < image.width; x++) {
|
||||
const i = (image.width * y + x);
|
||||
const idx = i << 2;
|
||||
|
||||
const pixel = image.pixels[i];
|
||||
png.data[idx] = pixel.r;
|
||||
png.data[idx + 1] = pixel.g;
|
||||
png.data[idx + 2] = pixel.b;
|
||||
png.data[idx + 3] = pixel.a;
|
||||
}
|
||||
}
|
||||
|
||||
png.pack().pipe(fs.createWriteStream(file))
|
||||
.on('close', () => resolve(true))
|
||||
;
|
||||
});
|
||||
|
||||
(async () => {
|
||||
const files = fs.readdirSync(IMAGES_ROOT);
|
||||
|
||||
let stitched = null;
|
||||
let k = 0;
|
||||
|
||||
for(let i = 0; i < files.length; i++) {
|
||||
const filePath = path.join(IMAGES_ROOT, files[i]);
|
||||
const image = await imageLoad(filePath);
|
||||
|
||||
if(!stitched) {
|
||||
stitched = {
|
||||
width: image.width,
|
||||
height: image.height * files.length,
|
||||
pixels: Array(image.width*image.height*files.length)
|
||||
}
|
||||
}
|
||||
|
||||
for(let j = 0; j < image.pixels.length; j++) {
|
||||
stitched.pixels[j + (i * image.width * image.height)] = { ...image.pixels[j] };
|
||||
}
|
||||
};
|
||||
|
||||
console.log('Writing');
|
||||
await imageWrite(stitched, FILE_OUT);
|
||||
})().catch(console.error);
|
@ -1,103 +0,0 @@
|
||||
const { PNG } = require("pngjs");
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
/**
|
||||
* Loads an image into memory.
|
||||
* @param image Image to load
|
||||
* @returns A promise that resolves to the loaded image.
|
||||
*/
|
||||
const imageLoad = (image) => new Promise(resolve => {
|
||||
fs.createReadStream(image)
|
||||
.pipe(new PNG({ filterType: 4 }))
|
||||
.on("parsed", function () {
|
||||
// Normalize
|
||||
const pixels = [];
|
||||
for(let y = 0; y < this.height; y++) {
|
||||
for(let x = 0; x < this.width; x++) {
|
||||
const idx = (this.width * y + x) << 2;
|
||||
const r = this.data[idx];
|
||||
const g = this.data[idx + 1];
|
||||
const b = this.data[idx + 2];
|
||||
const a = this.data[idx + 3];
|
||||
|
||||
pixels.push({ r, g, b, a });
|
||||
}
|
||||
}
|
||||
resolve({ pixels, width: this.width, height: this.height });
|
||||
})
|
||||
;
|
||||
});
|
||||
|
||||
/**
|
||||
* Writes an image to an output file.
|
||||
* @param image Image to write.
|
||||
* @param file File to write to.
|
||||
* @returns A promise that, when resolved, has saved the image.
|
||||
*/
|
||||
const imageWrite = (image, file) => new Promise(resolve => {
|
||||
const png = new PNG({ width: image.width, height: image.height });
|
||||
png.width = image.width;
|
||||
png.height = image.height;
|
||||
|
||||
for(let y = 0; y < image.height; y++) {
|
||||
for(let x = 0; x < image.width; x++) {
|
||||
const i = (image.width * y + x);
|
||||
const idx = i << 2;
|
||||
|
||||
const pixel = image.pixels[i];
|
||||
png.data[idx] = pixel.r;
|
||||
png.data[idx + 1] = pixel.g;
|
||||
png.data[idx + 2] = pixel.b;
|
||||
png.data[idx + 3] = pixel.a;
|
||||
}
|
||||
}
|
||||
|
||||
png.pack().pipe(fs.createWriteStream(file))
|
||||
.on('close', () => resolve(true))
|
||||
;
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates a blank image
|
||||
* @param width Width of the image.
|
||||
* @param height Height of the image.
|
||||
* @param fill Optional pixel to fill with, defaults to 0,0,0,0
|
||||
* @returns The newly created image.
|
||||
*/
|
||||
const imageCreate = (width, height, pixel) => {
|
||||
if(!pixel || !pixel.r) pixel = { r:0, g:0, b:0, a:0 };
|
||||
const pixels = [];
|
||||
for(let i = 0; i < width * height; i++) pixels.push({ ...pixel });
|
||||
return { pixels, width, height };
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies an area of a source image into a target image.
|
||||
* @param target Target image to copy into.
|
||||
* @param source Source image to copy from.
|
||||
* @param tx Target X position to copy into
|
||||
* @param ty Target Y position to copy into
|
||||
* @param sub Optional source area to use, defined as { x, y, width, height }.
|
||||
*/
|
||||
const imageCopy = (target, source, tx, ty, sub) => {
|
||||
if(!sub) sub = { x: 0, y: 0, width: source.width, height: source.height };
|
||||
|
||||
for(let x = sub.x; x < sub.x+sub.width; x++) {
|
||||
for(let y = sub.y; y < sub.y+sub.height; y++) {
|
||||
let absX = x - sub.x + tx;
|
||||
let absY = y - sub.y + ty;
|
||||
if(absX > target.width || absY > target.height) continue;
|
||||
let ti = absY * target.width + absX;
|
||||
let si = y * source.width + x;
|
||||
target.pixels[ti] = { ...source.pixels[si] };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
imageWrite,
|
||||
imageCreate,
|
||||
imageLoad,
|
||||
imageCopy
|
||||
}
|
@ -136,4 +136,19 @@ void assetXmlLoad(xml_t *xml, char *assetName) {
|
||||
char *data = assetStringLoad(assetName);
|
||||
xmlLoad(xml, data);
|
||||
free(data);
|
||||
}
|
||||
|
||||
void assetScripterAppend(scripter_t *scripter, char *fileName) {
|
||||
assetbuffer_t *asset = assetBufferOpen(fileName);
|
||||
int32_t read;
|
||||
char buffer[2048];
|
||||
|
||||
duk_push_global_object(scripter->context);
|
||||
|
||||
while(read = assetBufferRead(asset, buffer, 2048)) {
|
||||
duk_push_lstring(scripter->context, buffer, (duk_size_t)read);
|
||||
}
|
||||
|
||||
duk_peval(scripter->context);
|
||||
assetBufferClose(asset);
|
||||
}
|
@ -86,4 +86,8 @@ void assetTextureLoad(texture_t *texture, char *fileName);
|
||||
* @param assetName Asset name for the TTF font.
|
||||
* @param size Size of the font.
|
||||
*/
|
||||
void assetFontLoad(font_t *font, char *assetName);
|
||||
void assetFontLoad(font_t *font, char *assetName);
|
||||
|
||||
|
||||
|
||||
void assetScripterAppend(scripter_t *scripter, char *fileName);
|
@ -13,11 +13,11 @@ bool gameInit(game_t *game) {
|
||||
|
||||
// Send off to the game instance
|
||||
#if SETTING_GAME == SETTING_GAME_POKER
|
||||
return pokerGameInit(&game->pokerGame);
|
||||
return pokerGameInit(&game->pokerGame, &game->engine);
|
||||
#elif SETTING_GAME == SETTING_GAME_DAWN
|
||||
return dawnGameInit(game);
|
||||
#elif SETTING_GAME == SETTING_GAME_SANDBOX
|
||||
return sandboxSceneInit(&game->sandboxScene);
|
||||
return sandboxSceneInit(&game->sandboxScene, &game->engine);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,12 @@ void _pokerGameActionBetOnUpdate(
|
||||
|
||||
// Handle as an AI
|
||||
if(isHuman) {
|
||||
turn.type = POKER_TURN_TYPE_FOLD;
|
||||
turnMade = true;
|
||||
|
||||
if(inputIsPressed(&game->engine->input, INPUT_DOWN)) {
|
||||
} else if(inputIsPressed(&game->engine->input, INPUT_RIGHT)) {
|
||||
} else if(inputIsPressed(&game->engine->input, INPUT_UP)) {
|
||||
}
|
||||
|
||||
} else {
|
||||
turn = pokerTurnGet(&game->poker, game->poker.bet.better);
|
||||
turnMade = true;
|
||||
@ -87,6 +91,7 @@ void _pokerGameActionBetOnEnd(
|
||||
|
||||
// Are we waiting on any players?
|
||||
if(game->poker.bet.better != 0xFF) {
|
||||
pokerGameActionLookAdd(game, game->poker.bet.better);
|
||||
pokerGameActionBetAdd(game);
|
||||
return;
|
||||
}
|
||||
@ -103,6 +108,7 @@ void _pokerGameActionBetOnEnd(
|
||||
|
||||
pokerBetResetBetter(&game->poker);
|
||||
pokerGameActionRestackAdd(game);
|
||||
pokerGameActionLookAdd(game, game->poker.bet.better);
|
||||
pokerGameActionBetAdd(game);
|
||||
return;
|
||||
}
|
||||
|
@ -7,7 +7,9 @@
|
||||
|
||||
#include "pokergame.h"
|
||||
|
||||
bool pokerGameInit(pokergame_t *game) {
|
||||
bool pokerGameInit(pokergame_t *game, engine_t *engine) {
|
||||
game->engine = engine;
|
||||
|
||||
// Load the Assets.
|
||||
pokerGameAssetsInit(&game->assets);
|
||||
|
||||
|
@ -21,9 +21,10 @@
|
||||
* Initializes the game state for the poker game.
|
||||
*
|
||||
* @param game Game to initialize.
|
||||
* @param engine Engine to use when initializing.
|
||||
* @returns True if successful, otherwise false.
|
||||
*/
|
||||
bool pokerGameInit(pokergame_t *game);
|
||||
bool pokerGameInit(pokergame_t *game, engine_t *engine);
|
||||
|
||||
/**
|
||||
* Updates the poker game instance.
|
||||
|
@ -20,6 +20,7 @@ bool pokerGameAssetsInit(pokergameassets_t *assets) {
|
||||
|
||||
// Load the world textures.
|
||||
assetTextureLoad(&assets->testTexture, "test_texture.png");
|
||||
assetTextureLoad(&assets->cardTexture, "cards_normal.png");
|
||||
assetTextureLoad(&assets->roomTexture, "world/pub/pub_skywall.png");
|
||||
|
||||
// Load the character textures.
|
||||
|
23
src/game/poker/ui/pokercardui.c
Normal file
23
src/game/poker/ui/pokercardui.c
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "pokercardui.h"
|
||||
|
||||
void pokerCardSetImage(image_t *image, texture_t *texture, card_t card) {
|
||||
uint8_t cardImageIndex = (
|
||||
cardGetNumber(card) == CARD_ACE ? (
|
||||
card - CARD_COUNT_PER_SUIT + 1
|
||||
) : card+0x01
|
||||
);
|
||||
|
||||
imageSetTextureAndCrop(
|
||||
image, texture,
|
||||
cardGetNumber(cardImageIndex) * 71,
|
||||
cardGetSuit(card) * 96,
|
||||
71, 96
|
||||
);
|
||||
}
|
14
src/game/poker/ui/pokercardui.h
Normal file
14
src/game/poker/ui/pokercardui.h
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "../../../ui/image.h"
|
||||
#include "../../../poker/card.h"
|
||||
|
||||
|
||||
void pokerCardSetImage(image_t *image, texture_t *texture, card_t card);
|
@ -17,7 +17,14 @@ void pokerPlayerUiInit(pokerplayerui_t *ui) {
|
||||
0, 0, 0, 1,
|
||||
POKER_PLAYER_UI_IMAGE_SIZE, POKER_PLAYER_UI_IMAGE_SIZE, 1, 0
|
||||
);
|
||||
|
||||
|
||||
// Set up the grid
|
||||
ui->grid.gutterX = POKER_PLAYER_UI_PADDING;
|
||||
ui->grid.columns = 2;
|
||||
ui->grid.rows = 2;
|
||||
ui->grid.columnDefinitions[1] = POKER_PLAYER_UI_IMAGE_SIZE;
|
||||
ui->grid.rowDefinitions[0] = POKER_PLAYER_UI_IMAGE_SIZE / 2.0f;
|
||||
ui->grid.rowDefinitions[1] = POKER_PLAYER_UI_IMAGE_SIZE / 2.0f;
|
||||
}
|
||||
|
||||
void pokerPlayerUiUpdate(
|
||||
@ -72,62 +79,51 @@ void pokerPlayerUiRender(
|
||||
float scale;
|
||||
align_t align;
|
||||
|
||||
float gx, gy, gw, gh, sCol, sRow;
|
||||
float gx, gy, gw, gh;
|
||||
|
||||
// Font crap.
|
||||
scale = fontGetScale(FONT_SIZE_DEFAULT);
|
||||
player = game->poker.players + playerIndex;
|
||||
|
||||
// Resize the grid
|
||||
align = alignmentGet(
|
||||
ALIGN_POS_END | ALIGN_SIZE_ORIGINAL, ALIGN_POS_START | ALIGN_SIZE_ORIGINAL,
|
||||
engine->render.width, engine->render.height,
|
||||
POKER_PLAYER_UI_IMAGE_SIZE*2, POKER_PLAYER_UI_IMAGE_SIZE, -1, -1
|
||||
// Align the grid itself.
|
||||
gridResize(&ui->grid, POKER_PLAYER_UI_WIDTH, POKER_PLAYER_UI_HEIGHT);
|
||||
|
||||
// Render face
|
||||
gridGetChild(&ui->grid, 1, 0, 1, 2, &gx, &gy, &gw, &gh);
|
||||
shaderUseTexture(shader, &ui->frame.texture);
|
||||
shaderUsePosition(shader, x+gx, y+gy, 0, 0,0,0);
|
||||
primitiveDraw(&ui->quad, 0, -1);
|
||||
|
||||
// Render chips
|
||||
sprintf(buffer, "$%i", player->chips);
|
||||
ui->label.maxWidth = -1;
|
||||
labelSetText(&ui->label, font, buffer);
|
||||
align = gridGetAndAlignChild(
|
||||
&ui->grid, 0, 0, 1, 1,
|
||||
ALIGN_POS_END | ALIGN_SIZE_ORIGINAL, ALIGN_POS_CENTER | ALIGN_SIZE_ORIGINAL,
|
||||
ui->label.info.width, ui->label.info.height
|
||||
);
|
||||
// gridSetSize(
|
||||
// &ui->grid, engine->render.width, engine->render.height,
|
||||
// align.width, align.height,
|
||||
// align.x + x, align.y + y
|
||||
// );
|
||||
labelRender(&ui->label, shader, x+align.x, y+align.y);
|
||||
|
||||
// // Render face
|
||||
// gridGetChildSize(&ui->grid, ui->grid.breakpointCurrent, ui->grid.children+0,
|
||||
// &sCol, &sRow, &gx, &gy, &gw, &gh
|
||||
// );
|
||||
// shaderUseTexture(shader, &ui->frame.texture);
|
||||
// shaderUsePosition(shader, gx, gy, 0, 0,0,0);
|
||||
// primitiveDraw(&ui->quad, 0, -1);
|
||||
|
||||
// // Render chips
|
||||
// sprintf(buffer, "$%i", player->chips);
|
||||
// ui->label.maxWidth = -1;
|
||||
// labelSetText(&ui->label, font, buffer);
|
||||
// align = gridAlignChild(
|
||||
// &ui->grid, ui->grid.breakpointCurrent, ui->grid.children + 1, &sCol, &sRow,
|
||||
// ALIGN_POS_END | ALIGN_SIZE_ORIGINAL, ALIGN_POS_CENTER | ALIGN_SIZE_ORIGINAL,
|
||||
// ui->label.info.width, ui->label.info.height
|
||||
// );
|
||||
// labelRender(&ui->label, shader, align.x, align.y);
|
||||
|
||||
|
||||
// // Render state
|
||||
// if(player->state & POKER_PLAYER_STATE_OUT) {
|
||||
// sprintf(buffer, "Out");
|
||||
// } else if(player->state & POKER_PLAYER_STATE_FOLDED) {
|
||||
// sprintf(buffer, "Folded");
|
||||
// } else if(player->state & POKER_PLAYER_STATE_SHOWING) {
|
||||
// sprintf(buffer, "Showing");
|
||||
// } else if(game->poker.bet.better == playerIndex) {
|
||||
// sprintf(buffer, "Thinking");
|
||||
// } else {
|
||||
// sprintf(buffer, "Whatever");
|
||||
// }
|
||||
// labelSetText(&ui->label, font, buffer);
|
||||
// align = gridAlignChild(
|
||||
// &ui->grid, ui->grid.breakpointCurrent, ui->grid.children + 2, &sCol, &sRow,
|
||||
// ALIGN_POS_END | ALIGN_SIZE_ORIGINAL, ALIGN_POS_CENTER | ALIGN_SIZE_ORIGINAL,
|
||||
// ui->label.info.width, ui->label.info.height
|
||||
// );
|
||||
// labelRender(&ui->label, shader, align.x, align.y);
|
||||
// Render state
|
||||
if(player->state & POKER_PLAYER_STATE_OUT) {
|
||||
sprintf(buffer, "Out");
|
||||
} else if(player->state & POKER_PLAYER_STATE_FOLDED) {
|
||||
sprintf(buffer, "Folded");
|
||||
} else if(player->state & POKER_PLAYER_STATE_SHOWING) {
|
||||
sprintf(buffer, "Showing");
|
||||
} else if(game->poker.bet.better == playerIndex) {
|
||||
sprintf(buffer, "Thinking");
|
||||
} else {
|
||||
sprintf(buffer, "Whatever");
|
||||
}
|
||||
labelSetText(&ui->label, font, buffer);
|
||||
align = gridGetAndAlignChild(
|
||||
&ui->grid, 0, 1, 1, 1,
|
||||
ALIGN_POS_END | ALIGN_SIZE_ORIGINAL, ALIGN_POS_CENTER | ALIGN_SIZE_ORIGINAL,
|
||||
ui->label.info.width, ui->label.info.height
|
||||
);
|
||||
labelRender(&ui->label, shader, x+align.x, y+align.y);
|
||||
}
|
||||
|
||||
void pokerPlayerUiDispose(pokerplayerui_t *ui) {
|
||||
|
@ -10,6 +10,10 @@
|
||||
void pokerUiInit(pokergame_t *pokerGame) {
|
||||
uint8_t i, j;
|
||||
|
||||
// Initialize card render(s)
|
||||
imageInit(&pokerGame->ui.card);
|
||||
|
||||
// Initialize players
|
||||
j = 0;
|
||||
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
|
||||
if(i == POKER_PLAYER_HUMAN_INDEX) continue;
|
||||
@ -34,6 +38,29 @@ void pokerUiUpdate(pokergame_t *pokerGame, engine_t *engine) {
|
||||
void pokerUiRender(pokergame_t *pokerGame, engine_t *engine) {
|
||||
uint8_t i, j;
|
||||
pokerplayerui_t *ui;
|
||||
pokerplayer_t *player;
|
||||
|
||||
char message[128];
|
||||
|
||||
// cards
|
||||
if(pokerGame->poker.state >= POKER_STATE_DEALING) {
|
||||
for(j = 0; j < POKER_PLAYER_COUNT; j++) {
|
||||
player = pokerGame->poker.players + j;
|
||||
for(i = 0; i < player->cardCount; i++) {
|
||||
pokerCardSetImage(&pokerGame->ui.card, &pokerGame->assets.cardTexture, player->cards[i]);
|
||||
imageRender(&pokerGame->ui.card, &pokerGame->assets.shader, i * 64.0f, j * 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// show uh
|
||||
player = pokerGame->poker.players + POKER_PLAYER_HUMAN_INDEX;
|
||||
if(pokerGame->poker.bet.better == POKER_PLAYER_HUMAN_INDEX) {
|
||||
sprintf(message, "Press down to fold, up to bet, right to check/call.");
|
||||
labelSetText(&pokerGame->ui.player->label, &pokerGame->assets.font, message);
|
||||
labelRender(&pokerGame->ui.player->label, &pokerGame->assets.shader, 300, 100);
|
||||
}
|
||||
|
||||
|
||||
j = 0;
|
||||
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
|
||||
@ -42,7 +69,7 @@ void pokerUiRender(pokergame_t *pokerGame, engine_t *engine) {
|
||||
|
||||
pokerPlayerUiRender(
|
||||
ui, pokerGame, &pokerGame->assets.shader, &pokerGame->assets.font, engine,
|
||||
i, 0, j * 75.0f
|
||||
i, engine->render.width - ui->grid.width, j * 75.0f
|
||||
);
|
||||
j++;
|
||||
}
|
||||
@ -51,6 +78,8 @@ void pokerUiRender(pokergame_t *pokerGame, engine_t *engine) {
|
||||
void pokerUiDispose(pokergame_t *pokerGame) {
|
||||
uint8_t i, j;
|
||||
|
||||
imageDispose(&pokerGame->ui.card);
|
||||
|
||||
j = 0;
|
||||
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
|
||||
if(i == POKER_PLAYER_HUMAN_INDEX) continue;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <dawn/dawn.h>
|
||||
#include "../../../ui/label.h"
|
||||
#include "pokerplayerui.h"
|
||||
#include "pokercardui.h"
|
||||
|
||||
/**
|
||||
* Initializes the UI Module.
|
||||
|
@ -7,48 +7,48 @@
|
||||
|
||||
#include "sandboxscene.h"
|
||||
|
||||
framedtextmenu_t ftm;
|
||||
scripter_t scripter;
|
||||
|
||||
bool sandboxSceneInit(sandboxscene_t *game) {
|
||||
bool sandboxSceneInit(sandboxscene_t *game, engine_t *engine) {
|
||||
assetFontLoad(&game->font, "fonts/opensans/OpenSans-Regular.ttf");
|
||||
assetTextureLoad(&game->texture, "test_texture.png");
|
||||
assetShaderLoad(&game->shader,
|
||||
"shaders/textured.vert", "shaders/textured.frag"
|
||||
);
|
||||
|
||||
menuitem_t *item;
|
||||
framedTextMenuInit(&ftm, &game->font, &game->texture);
|
||||
ftm.menu.grid.rows = 3;
|
||||
item = textMenuAdd(&ftm.menu, "Option 1");
|
||||
item->y = 0;
|
||||
item = textMenuAdd(&ftm.menu, "Option 2");
|
||||
item->y = 1;
|
||||
item = textMenuAdd(&ftm.menu, "Option 3");
|
||||
item->y = 2;
|
||||
scripterInit(&scripter, engine);
|
||||
assetScripterAppend(&scripter, "scripts/main.js");
|
||||
scripterInvokeMethodSimple(&scripter, "init");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void sandboxSceneUpdate(sandboxscene_t *game, engine_t *engine) {
|
||||
cameraLookAt(&game->camera,
|
||||
0, 0, 10,
|
||||
0, 0, 0
|
||||
);
|
||||
cameraLookAt(&game->camera, 3,3,3, 0,0,0);
|
||||
|
||||
cameraOrtho(&game->camera,
|
||||
0, engine->render.width,
|
||||
engine->render.height, 0,
|
||||
cameraPerspective(&game->camera, 45,
|
||||
engine->render.width/engine->render.height,
|
||||
0.01f, 1000.0f
|
||||
);
|
||||
|
||||
// cameraLookAt(&game->camera,
|
||||
// 0, 0, 10,
|
||||
// 0, 0, 0
|
||||
// );
|
||||
// cameraOrtho(&game->camera,
|
||||
// 0, engine->render.width,
|
||||
// engine->render.height, 0,
|
||||
// 0.01f, 1000.0f
|
||||
// );
|
||||
|
||||
shaderUse(&game->shader);
|
||||
shaderUseCamera(&game->shader, &game->camera);
|
||||
|
||||
framedTextMenuResize(&ftm, 400, 400);
|
||||
framedTextMenuUpdate(&ftm, engine);
|
||||
framedTextMenuRender(&ftm, &game->shader, 0, 0);
|
||||
shaderUsePosition(&game->shader, 0,0,0, 0,0,0);
|
||||
shaderUseTexture(&game->shader, &game->texture);
|
||||
scripterInvokeMethodSimple(&scripter, "update");
|
||||
}
|
||||
|
||||
void sandboxSceneDispose(sandboxscene_t *game) {
|
||||
|
||||
// scripterInvokeMethodSimple(&scripter, "dispose");
|
||||
scripterDispose(&scripter);
|
||||
}
|
@ -18,7 +18,8 @@
|
||||
#include "../../file/asset.h"
|
||||
|
||||
#include "../../file/xml.h"
|
||||
|
||||
#include "../../file/asset.h"
|
||||
#include "../../script/scripter.h"
|
||||
#include "../../ui/grid.h"
|
||||
#include "../../ui/menu.h"
|
||||
#include "../../ui/textmenu.h"
|
||||
@ -29,9 +30,10 @@
|
||||
* Initialize the sandbox scene test game.
|
||||
*
|
||||
* @param game Game to initialize.
|
||||
* @param engine Engine to use during init.
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool sandboxSceneInit(sandboxscene_t *game);
|
||||
bool sandboxSceneInit(sandboxscene_t *game, engine_t *engine);
|
||||
|
||||
/**
|
||||
* Update a sandbox scene.
|
||||
|
@ -11,6 +11,8 @@ void _pokerActionBlindsOnStart(queue_t *queue,queueaction_t *action,uint8_t i) {
|
||||
poker_t *poker;
|
||||
poker = (poker_t *)action->data;
|
||||
|
||||
poker->state = POKER_STATE_TAKING_BLINDS;
|
||||
|
||||
pokerBetTakeBlinds(poker);
|
||||
printf("Taken Blinds\n");
|
||||
queueNext(queue);
|
||||
|
@ -11,6 +11,8 @@ void _pokerActionDealOnStart(queue_t *queue, queueaction_t *action, uint8_t i) {
|
||||
poker_t *poker;
|
||||
poker = (poker_t *)action->data;
|
||||
|
||||
poker->state = POKER_STATE_DEALING;
|
||||
|
||||
// Shuffle the deck
|
||||
cardShuffle(poker->dealer.deck, CARD_DECK_SIZE);
|
||||
|
||||
|
@ -11,6 +11,8 @@ void _pokerActionFlopDo(queue_t *queue, queueaction_t *action, uint8_t count) {
|
||||
poker_t *poker;
|
||||
poker = (poker_t *)action->data;
|
||||
|
||||
poker->state = POKER_STATE_CARDS_FLOPPING;
|
||||
|
||||
pokerDealerBurn(&poker->dealer, 1);
|
||||
pokerDealerTurn(&poker->dealer, count);
|
||||
|
||||
|
@ -13,6 +13,8 @@ void _pokerActionMatchOnStart(queue_t *queue, queueaction_t *action, uint8_t i){
|
||||
|
||||
poker = (poker_t *)action->data;
|
||||
|
||||
poker->state = POKER_STATE_STARTING_MATCH;
|
||||
|
||||
// Reset the main game state. This does not init the round.
|
||||
pokerBetInit(&poker->bet);
|
||||
poker->roundDealer = POKER_PLAYER_COUNT-2;
|
||||
|
@ -15,6 +15,8 @@ void _pokerActionRoundOnStart(queue_t *queue, queueaction_t *action ,uint8_t i){
|
||||
|
||||
poker = (poker_t *)action->data;
|
||||
|
||||
poker->state = POKER_STATE_STARTING_ROUND;
|
||||
|
||||
// Prepare the initial game state
|
||||
pokerBetReset(&poker->bet);
|
||||
pokerDealerInit(&poker->dealer);
|
||||
|
13
src/script/api/api.c
Normal file
13
src/script/api/api.c
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "api.h"
|
||||
|
||||
void scriptApiAdd(scripter_t *scripter) {
|
||||
scriptsApiIo(scripter);
|
||||
scriptsApiPrimitive(scripter);
|
||||
}
|
13
src/script/api/api.h
Normal file
13
src/script/api/api.h
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "primitive.h"
|
||||
#include "io.h"
|
||||
|
||||
void scriptApiAdd(scripter_t *scripter);
|
1
src/script/api/global.d.ts
vendored
Normal file
1
src/script/api/global.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
declare type Pointer<T> = { 'POINTER':T };
|
24
src/script/api/io.c
Normal file
24
src/script/api/io.c
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "io.h"
|
||||
|
||||
scripterreturn_t _scriptPrint(scriptercontext_t *ctx) {
|
||||
duk_push_string(ctx, " ");
|
||||
duk_insert(ctx, 0);
|
||||
duk_join(ctx, duk_get_top(ctx) - 1);
|
||||
printf("%s\n", duk_safe_to_string(ctx, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void scriptsApiIo(scripter_t *scripter) {
|
||||
scripterDefineMethod(scripter,
|
||||
SCRIPT_IO_PRINT_NAME,
|
||||
SCRIPT_IO_PRINT_ARGS,
|
||||
&_scriptPrint
|
||||
);
|
||||
}
|
1
src/script/api/io.d.ts
vendored
Normal file
1
src/script/api/io.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
declare function print(...args:any):void;
|
13
src/script/api/io.h
Normal file
13
src/script/api/io.h
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "../scripter.h"
|
||||
|
||||
#define SCRIPT_IO_PRINT_NAME "print"
|
||||
#define SCRIPT_IO_PRINT_ARGS SCRIPTER_VARIABLE_ARGUMENT_COUNT
|
||||
|
||||
void scriptsApiIo(scripter_t *scripter);
|
36
src/script/api/primitive.c
Normal file
36
src/script/api/primitive.c
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "primitive.h"
|
||||
|
||||
scripterreturn_t _scriptPrimitiveDraw(scriptercontext_t *context) {
|
||||
primitive_t *primitive = duk_to_pointer(context, 0);
|
||||
int32_t start = duk_to_number(context, 1);
|
||||
int32_t count = duk_to_number(context, 2);
|
||||
primitiveDraw(primitive, start, count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
scripterreturn_t _scriptCubeInit(scriptercontext_t *context) {
|
||||
primitive_t *primitive = malloc(sizeof(primitive_t));
|
||||
cubeInit(primitive, 1, 1, 1);
|
||||
duk_push_pointer(context, primitive);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void scriptsApiPrimitive(scripter_t *scripter) {
|
||||
scripterDefineMethod(scripter,
|
||||
SCRIPT_PRIMITIVE_DRAW_NAME,
|
||||
SCRIPT_PRIMITIVE_DRAW_ARGS,
|
||||
&_scriptPrimitiveDraw
|
||||
);
|
||||
scripterDefineMethod(scripter,
|
||||
SCRIPT_CUBE_INIT_NAME,
|
||||
SCRIPT_CUBE_INIT_ARGS,
|
||||
&_scriptCubeInit
|
||||
);
|
||||
}
|
5
src/script/api/primitive.d.ts
vendored
Normal file
5
src/script/api/primitive.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
declare type PointerPrimitive = Pointer<'PRIMITIVE'>;
|
||||
|
||||
declare function primitiveDraw(primitive:PointerPrimitive, start:number, count:number);
|
||||
|
||||
declare function cubeCreate():PointerPrimitive;
|
20
src/script/api/primitive.h
Normal file
20
src/script/api/primitive.h
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "../scripter.h"
|
||||
#include "../../display/primitive.h"
|
||||
#include "../../display/primitives/cube.h"
|
||||
|
||||
#define SCRIPT_PRIMITIVE_DRAW_NAME "primitiveDraw"
|
||||
#define SCRIPT_PRIMITIVE_DRAW_ARGS 3
|
||||
|
||||
#define SCRIPT_CUBE_INIT_NAME "cubeCreate"
|
||||
#define SCRIPT_CUBE_INIT_ARGS 0
|
||||
|
||||
void scriptsApiPrimitive(scripter_t *scripter);
|
73
src/script/scripter.c
Normal file
73
src/script/scripter.c
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "scripter.h"
|
||||
|
||||
void scripterInit(scripter_t *scripter, engine_t *engine) {
|
||||
scripter->context = duk_create_heap_default();
|
||||
scripter->engine = engine;
|
||||
|
||||
// Global context is implied here?
|
||||
// Push the script self reference
|
||||
duk_push_pointer(scripter->context, scripter);
|
||||
duk_put_global_string(scripter->context, SCRIPTER_SELF_NAME);
|
||||
|
||||
// Inject API
|
||||
scriptApiAdd(scripter);
|
||||
}
|
||||
|
||||
void scripterDispose(scripter_t *scripter) {
|
||||
duk_destroy_heap(scripter->context);
|
||||
}
|
||||
|
||||
scripter_t * scripterFromContext(scriptercontext_t *ctx) {
|
||||
// Switch to global object
|
||||
duk_push_global_object(ctx);
|
||||
|
||||
// Get the string in the object.
|
||||
duk_get_prop_string(ctx, -1, SCRIPTER_SELF_NAME);
|
||||
|
||||
// Get the pointer from that string.
|
||||
scripter_t *scripter = (scripter_t *)duk_get_pointer(ctx, -1);
|
||||
|
||||
// Pop the string.
|
||||
duk_pop(ctx);
|
||||
|
||||
// Pop the global.
|
||||
duk_pop(ctx);
|
||||
|
||||
return scripter;
|
||||
}
|
||||
|
||||
void scripterDefineMethod(scripter_t *scripter,
|
||||
char *name, int32_t argCount, scriptermethod_t *method
|
||||
) {
|
||||
duk_push_c_function(scripter->context, method, argCount);
|
||||
duk_put_global_string(scripter->context, name);
|
||||
}
|
||||
|
||||
bool scripterInvokeMethodSimple(scripter_t *scripter, char *method) {
|
||||
// Push global
|
||||
duk_push_global_object(scripter->context);
|
||||
|
||||
// Push method string
|
||||
duk_get_prop_string(scripter->context, -1, method);
|
||||
|
||||
// Invoke string method
|
||||
if(duk_pcall(scripter->context, 0) != 0) {
|
||||
printf("Error: %s\n", duk_safe_to_string(scripter->context, -1));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Pop result
|
||||
duk_pop(scripter->context);
|
||||
|
||||
// Pop global
|
||||
duk_pop(scripter->context);
|
||||
|
||||
return true;
|
||||
}
|
54
src/script/scripter.h
Normal file
54
src/script/scripter.h
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "api/api.h"
|
||||
|
||||
/**
|
||||
* Initialize the scripter engine.
|
||||
*
|
||||
* @param scripter Scripter engine to initialize.
|
||||
* @param engine Game engine to use.
|
||||
*/
|
||||
void scripterInit(scripter_t *scripter, engine_t *engine);
|
||||
|
||||
/**
|
||||
* Dispose a previously created scripter instance.
|
||||
*
|
||||
* @param scripter Scripter to dispose.
|
||||
*/
|
||||
void scripterDispose(scripter_t *scripter);
|
||||
|
||||
/**
|
||||
* Retreive the scripter instance frm a scripter context.
|
||||
*
|
||||
* @param ctx Scripter context.
|
||||
* @return Pointer to the scripter instance.
|
||||
*/
|
||||
scripter_t * scripterFromContext(scriptercontext_t *ctx);
|
||||
|
||||
/**
|
||||
* Define a method onto the global scripter stack.
|
||||
*
|
||||
* @param scripter Scripter to define onto.
|
||||
* @param name Name of the method.
|
||||
* @param argCount Arguments that the method takes.
|
||||
* @param method Pointer to the method to receive the callback.
|
||||
*/
|
||||
void scripterDefineMethod(scripter_t *scripter,
|
||||
char *name, int32_t argCount, scriptermethod_t *method
|
||||
);
|
||||
|
||||
/**
|
||||
* Invoke a method (without arguments) off the global stack.
|
||||
*
|
||||
* @param scripter Scripter to invoke frmo
|
||||
* @param method Method to invoke.
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool scripterInvokeMethodSimple(scripter_t *scripter, char *method);
|
16
src/scripts/main.ts
Normal file
16
src/scripts/main.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { Primitive } from "./primitive";
|
||||
|
||||
let cube:PointerPrimitive;
|
||||
let prim = new Primitive();
|
||||
|
||||
const init = () => {
|
||||
cube = cubeCreate();
|
||||
print("Created cube", cube);
|
||||
}
|
||||
|
||||
const update = () => {
|
||||
primitiveDraw(cube, 0, -1);
|
||||
}
|
||||
|
||||
const dispose = () => {
|
||||
}
|
5
src/scripts/primitive.ts
Normal file
5
src/scripts/primitive.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export class Primitive {
|
||||
constructor() {
|
||||
print('Hello Class!');
|
||||
}
|
||||
}
|
@ -38,6 +38,8 @@ void imageSetTextureAndCrop(image_t *image, texture_t *texture,
|
||||
v1 = v0 + (height / texture->height);
|
||||
|
||||
image->texture = texture;
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
quadInit(&image->quad, 0,
|
||||
0,0,u0,v0,
|
||||
1,1,u1,v1
|
||||
|
23
tsconfig.json
Normal file
23
tsconfig.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES3",
|
||||
"lib": [ "esnext" ],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"jsx": "preserve",
|
||||
"baseUrl": ".",
|
||||
"outDir": "build/assets/scripts",
|
||||
"alwaysStrict": false,
|
||||
"noImplicitUseStrict": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"include": [
|
||||
"**/*.ts", "**/*.tsx", "**/*.d.ts"
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user