Preliminary pattern / wildcard colour support
Currently avatars only, no user customization yet
This commit is contained in:
parent
f2eba1f87d
commit
8620f53358
|
@ -15,7 +15,7 @@
|
||||||
line-height:1.2
|
line-height:1.2
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="index.js?v=3"></script>
|
<script src="index.js?v=4"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 id="filename"></h1>
|
<h1 id="filename"></h1>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
line-height:1.2
|
line-height:1.2
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="index.js?v=1"></script>
|
<script src="index.js?v=4"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 id="filename"></h1>
|
<h1 id="filename"></h1>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
line-height:1.2
|
line-height:1.2
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="index.js?v=3"></script>
|
<script src="index.js?v=4"></script>
|
||||||
<script>
|
<script>
|
||||||
function showErrors() {
|
function showErrors() {
|
||||||
document.getElementById('errors').style.display = 'block'
|
document.getElementById('errors').style.display = 'block'
|
||||||
|
|
81
index.js
81
index.js
|
@ -16,10 +16,45 @@ const makeCanvas = (w, h) => {
|
||||||
return canvas
|
return canvas
|
||||||
}
|
}
|
||||||
|
|
||||||
const canvasFromBitmap = (bitmap) => {
|
// C64 RGB values taken from https://www.c64-wiki.com/wiki/Color
|
||||||
|
const c64Colors = [
|
||||||
|
0x000000, 0xffffff, 0x880000, 0xaaffee, 0xcc44cc, 0x00cc55,
|
||||||
|
0x0000aa, 0xeeee77, 0xdd8855, 0x664400, 0xff7777, 0x333333,
|
||||||
|
0x777777, 0xaaff66, 0x0088ff, 0xbbbbbb
|
||||||
|
]
|
||||||
|
|
||||||
|
// from paint.m:447
|
||||||
|
const celPatterns = [
|
||||||
|
[0x00, 0x00, 0x00, 0x00],
|
||||||
|
[0xaa, 0xaa, 0xaa, 0xaa],
|
||||||
|
[0xff, 0xff, 0xff, 0xff],
|
||||||
|
[0xe2, 0xe2, 0xe2, 0xe2],
|
||||||
|
[0x8b, 0xbe, 0x0f, 0xcc],
|
||||||
|
[0xee, 0x00, 0xee, 0x00],
|
||||||
|
[0xf0, 0xf0, 0x0f, 0x0f],
|
||||||
|
[0x22, 0x88, 0x22, 0x88],
|
||||||
|
[0x32, 0x88, 0x23, 0x88],
|
||||||
|
[0x00, 0x28, 0x3b, 0x0c],
|
||||||
|
[0x33, 0xcc, 0x33, 0xcc],
|
||||||
|
[0x08, 0x80, 0x0c, 0x80],
|
||||||
|
[0x3f, 0x3f, 0xf3, 0xf3],
|
||||||
|
[0xaa, 0x3f, 0xaa, 0xf3],
|
||||||
|
[0xaa, 0x00, 0xaa, 0x00],
|
||||||
|
[0x55, 0x55, 0x55, 0x55]
|
||||||
|
]
|
||||||
|
|
||||||
|
const defaultColors = {
|
||||||
|
wildcard: 6,
|
||||||
|
skin: 10,
|
||||||
|
pattern: 15
|
||||||
|
}
|
||||||
|
|
||||||
|
const canvasFromBitmap = (bitmap, colors = {}) => {
|
||||||
if (bitmap.length == 0 || bitmap[0].length == 0) {
|
if (bitmap.length == 0 || bitmap[0].length == 0) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
const { wildcard, pattern, skin } = { ...defaultColors, ...colors }
|
||||||
|
const patternColors = [6, wildcard, 0, skin]
|
||||||
const h = bitmap.length
|
const h = bitmap.length
|
||||||
const w = bitmap[0].length * 2
|
const w = bitmap[0].length * 2
|
||||||
const canvas = makeCanvas(w, h)
|
const canvas = makeCanvas(w, h)
|
||||||
|
@ -40,19 +75,21 @@ const canvasFromBitmap = (bitmap) => {
|
||||||
|
|
||||||
for (let y = 0; y < bitmap.length; y ++) {
|
for (let y = 0; y < bitmap.length; y ++) {
|
||||||
const line = bitmap[y]
|
const line = bitmap[y]
|
||||||
|
const patbyte = celPatterns[pattern][y % 4]
|
||||||
for (let x = 0; x < line.length; x ++) {
|
for (let x = 0; x < line.length; x ++) {
|
||||||
const pixel = line[x]
|
const pixel = line[x]
|
||||||
|
let color = null
|
||||||
if (pixel == 0) { // transparent
|
if (pixel == 0) { // transparent
|
||||||
putpixel(x, y, 0, 0, 0, 0)
|
putpixel(x, y, 0, 0, 0, 0)
|
||||||
} else if (pixel == 1) { // wild
|
} else if (pixel == 1) { // wild
|
||||||
// TODO: patterns + colors
|
const shift = (x % 4) * 2
|
||||||
// for now, always blue
|
color = patternColors[(patbyte & (0xc0 >> shift)) >> (6 - shift)]
|
||||||
putpixel(x, y, 0, 0, 170, 255)
|
} else {
|
||||||
} else if (pixel == 2) { // black
|
color = patternColors[pixel]
|
||||||
putpixel(x, y, 0, 0, 0, 255)
|
}
|
||||||
} else { // skin
|
if (color != null) {
|
||||||
// TODO: custom skin colors
|
const rgb = c64Colors[color]
|
||||||
putpixel(x, y, 255, 119, 119, 255)
|
putpixel(x, y, (rgb & 0xff0000) >> 16, (rgb & 0xff00) >> 8, rgb & 0xff, 0xff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +124,7 @@ const emptyBitmap = (w, h, color = 0) => {
|
||||||
|
|
||||||
const drawByte = (bitmap, x, y, byte) => {
|
const drawByte = (bitmap, x, y, byte) => {
|
||||||
bitmap[y][x] = (byte & 0xc0) >> 6
|
bitmap[y][x] = (byte & 0xc0) >> 6
|
||||||
bitmap[y][x + 1] = (byte & 0x3c) >> 4
|
bitmap[y][x + 1] = (byte & 0x30) >> 4
|
||||||
bitmap[y][x + 2] = (byte & 0x0c) >> 2
|
bitmap[y][x + 2] = (byte & 0x0c) >> 2
|
||||||
bitmap[y][x + 3] = (byte & 0x03)
|
bitmap[y][x + 3] = (byte & 0x03)
|
||||||
}
|
}
|
||||||
|
@ -372,9 +409,6 @@ const decodeCel = (data, changesColorRam) => {
|
||||||
if (celDecoder[cel.type]) {
|
if (celDecoder[cel.type]) {
|
||||||
celDecoder[cel.type](data, cel)
|
celDecoder[cel.type](data, cel)
|
||||||
}
|
}
|
||||||
if (cel.bitmap) {
|
|
||||||
cel.canvas = canvasFromBitmap(cel.bitmap)
|
|
||||||
}
|
|
||||||
return cel
|
return cel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +605,7 @@ const celsFromMask = (prop, celMask) => {
|
||||||
return cels
|
return cels
|
||||||
}
|
}
|
||||||
|
|
||||||
const compositeCels = (cels, paintOrder = null) => {
|
const compositeCels = (cels, celColors = null, paintOrder = null) => {
|
||||||
if (cels.length == 0) {
|
if (cels.length == 0) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -582,7 +616,7 @@ const compositeCels = (cels, paintOrder = null) => {
|
||||||
let xRel = 0
|
let xRel = 0
|
||||||
let yRel = 0
|
let yRel = 0
|
||||||
let layers = []
|
let layers = []
|
||||||
for (let cel of cels) {
|
for (const [icel, cel] of cels.entries()) {
|
||||||
if (cel) {
|
if (cel) {
|
||||||
const x = cel.xOffset + xRel
|
const x = cel.xOffset + xRel
|
||||||
const y = -(cel.yOffset + yRel)
|
const y = -(cel.yOffset + yRel)
|
||||||
|
@ -590,7 +624,12 @@ const compositeCels = (cels, paintOrder = null) => {
|
||||||
minY = Math.min(minY, y)
|
minY = Math.min(minY, y)
|
||||||
maxX = Math.max(maxX, cel.width + x)
|
maxX = Math.max(maxX, cel.width + x)
|
||||||
maxY = Math.max(maxY, cel.height + y)
|
maxY = Math.max(maxY, cel.height + y)
|
||||||
layers.push({ cel, x, y })
|
if (cel.bitmap) {
|
||||||
|
const colors = Array.isArray(celColors) ? celColors[icel] : (celColors ?? {})
|
||||||
|
layers.push({ canvas: canvasFromBitmap(cel.bitmap, colors), x, y })
|
||||||
|
} else {
|
||||||
|
layers.push(null)
|
||||||
|
}
|
||||||
xRel += cel.xRel
|
xRel += cel.xRel
|
||||||
yRel += cel.yRel
|
yRel += cel.yRel
|
||||||
} else {
|
} else {
|
||||||
|
@ -612,8 +651,8 @@ const compositeCels = (cels, paintOrder = null) => {
|
||||||
const canvas = makeCanvas(w, h)
|
const canvas = makeCanvas(w, h)
|
||||||
const ctx = canvas.getContext("2d")
|
const ctx = canvas.getContext("2d")
|
||||||
for (const layer of layers) {
|
for (const layer of layers) {
|
||||||
if (layer && layer.cel.canvas) {
|
if (layer && layer.canvas) {
|
||||||
ctx.drawImage(layer.cel.canvas, (layer.x - minX) * 8, layer.y - minY)
|
ctx.drawImage(layer.canvas, (layer.x - minX) * 8, layer.y - minY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { canvas: canvas, xOffset: minX * 8, yOffset: minY, w: w, h: h }
|
return { canvas: canvas, xOffset: minX * 8, yOffset: minY, w: w, h: h }
|
||||||
|
@ -628,6 +667,8 @@ const imageFromCanvas = (canvas) => {
|
||||||
return img
|
return img
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const imageFromBitmap = (bitmap, colors = {}) => imageFromCanvas(canvasFromBitmap(bitmap, colors))
|
||||||
|
|
||||||
const textNode = (text, type = "span") => {
|
const textNode = (text, type = "span") => {
|
||||||
const node = document.createElement(type)
|
const node = document.createElement(type)
|
||||||
node.innerText = text
|
node.innerText = text
|
||||||
|
@ -690,6 +731,7 @@ const BodyImpl = {
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
const cels = []
|
const cels = []
|
||||||
|
const celColors = []
|
||||||
let restartedCount = 0
|
let restartedCount = 0
|
||||||
for (const [ilimb, limb] of body.limbs.entries()) {
|
for (const [ilimb, limb] of body.limbs.entries()) {
|
||||||
const animation = animations[ilimb]
|
const animation = animations[ilimb]
|
||||||
|
@ -708,11 +750,12 @@ const BodyImpl = {
|
||||||
} else {
|
} else {
|
||||||
cels.push(null)
|
cels.push(null)
|
||||||
}
|
}
|
||||||
|
celColors.push({ pattern: limb.pattern })
|
||||||
}
|
}
|
||||||
if (restartedCount == animations.length) {
|
if (restartedCount == animations.length) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
frames.push(compositeCels(cels, limbOrder))
|
frames.push(compositeCels(cels, celColors, limbOrder))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue