213 lines
6.8 KiB
TypeScript
213 lines
6.8 KiB
TypeScript
import { clearScreen, fillRect } from "../io/window.ts";
|
|
import { drawSprite, drawText, useSpritesheet } from "../runtime/builtins.ts";
|
|
import { COLOR } from "../data/colors.ts";
|
|
import { getMapSheet, getSheet, setSheet } from "../io/sheet.ts";
|
|
import { M, mouseClick, mouseDown, mouseHeld, mousePos } from "../io/mouse.ts";
|
|
import { drawTransparentRect, drawVoidRect, inRect, reGrid } from "../util/util.ts";
|
|
import { page } from "./viewsheets.ts";
|
|
import { keyPressed, K } from "../io/keyboard.ts";
|
|
|
|
const state = {
|
|
selectedSpriteSheet: 0,
|
|
selectedSprite: 0,
|
|
viewX: 0,
|
|
viewY: 0,
|
|
dragging: false,
|
|
dragFromViewX: 0,
|
|
dragFromViewY: 0,
|
|
dragFromX: 0,
|
|
dragFromY: 0,
|
|
get spriteSheetPage() {
|
|
return Math.floor(this.selectedSprite/64);
|
|
},
|
|
set spriteSheetPage(val) {
|
|
this.selectedSprite = 64*val+this.spriteWithinPage;
|
|
},
|
|
get spriteWithinPage() {
|
|
return this.selectedSprite%64;
|
|
},
|
|
set spriteWithinPage(val) {
|
|
this.selectedSprite = 64*this.spriteSheetPage+val;
|
|
},
|
|
get map() {
|
|
return getMapSheet(page.activeSheet);
|
|
},
|
|
set map(val) {
|
|
setSheet(page.activeSheet, "map", val);
|
|
},
|
|
setInPatch(i: number, sprsheet: number, sprite: number) {
|
|
const cellVal = this.map.subgrid(this.viewX, this.viewY, patchW, patchH).values[i];
|
|
if (cellVal) {
|
|
cellVal[0] = sprsheet
|
|
cellVal[1] = sprite;
|
|
}
|
|
},
|
|
get patch() {
|
|
return this.map.subgrid(this.viewX, this.viewY, patchW, patchH);
|
|
}
|
|
}
|
|
|
|
const patchX = 0;
|
|
const patchY = 8;
|
|
const patchW = 16;
|
|
const patchH = 9;
|
|
|
|
const spriteW = 8;
|
|
const spriteH = 8;
|
|
|
|
const spriteSheetX = 0;
|
|
const spriteSheetY = 88;
|
|
const spriteSheetW = 16;
|
|
const spriteSheetH = 4;
|
|
|
|
const spriteSheetPickerX = 0;
|
|
const spriteSheetPickerY = 81;
|
|
const spriteSheetPickerW = 16;
|
|
const spriteSheetPickerH = 1;
|
|
const spriteSheetPickerTabW = 7;
|
|
const spriteSheetPickerTabH = 7;
|
|
|
|
const spriteSheetPageSwapX = 121;
|
|
const spriteSheetPageSwapY = 81;
|
|
const spriteSheetPageSwapW = 7;
|
|
const spriteSheetPageSwapH = 7;
|
|
|
|
const update = () => {
|
|
const {x: mouseX, y: mouseY} = mousePos();
|
|
const inPatch = inRect(mouseX, mouseY, patchX, patchY, patchW*spriteW, patchH*spriteH - 2);
|
|
const inSpriteSheetPicker = inRect(mouseX, mouseY, spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerW*spriteSheetPickerTabW, spriteSheetPickerH*spriteSheetPickerTabH);
|
|
const inSpriteSheet = inRect(mouseX, mouseY, spriteSheetX, spriteSheetY, spriteSheetW*spriteW, spriteSheetH*spriteH);
|
|
const inSpriteSheetPageSwap = inRect(mouseX, mouseY, spriteSheetPageSwapX, spriteSheetPageSwapY, spriteSheetPageSwapW, spriteSheetPageSwapH);
|
|
if (mouseHeld()) {
|
|
if (inPatch) {
|
|
const {x, y} = reGrid(mouseX, mouseY, patchX, patchY, spriteW, spriteH);
|
|
const cellNumber = patchW*y+x;
|
|
state.setInPatch(cellNumber, state.selectedSpriteSheet, state.selectedSprite);
|
|
}
|
|
if (inSpriteSheetPicker) {
|
|
const {x, y} = reGrid(mouseX, mouseY, spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerTabW, spriteSheetPickerTabH);
|
|
state.selectedSpriteSheet = spriteSheetPickerW*y+x;
|
|
}
|
|
if (inSpriteSheet) {
|
|
const {x, y} = reGrid(mouseX, mouseY, spriteSheetX, spriteSheetY, spriteW, spriteH);
|
|
state.spriteWithinPage = spriteSheetW*y+x;
|
|
}
|
|
} else if (mouseDown(M.MIDDLE)) {
|
|
if (inPatch) {
|
|
const {x, y} = reGrid(mouseX, mouseY, patchX, patchY, spriteW, spriteH);
|
|
state.dragging = true;
|
|
state.dragFromX = x;
|
|
state.dragFromY = y;
|
|
state.dragFromViewX = state.viewX;
|
|
state.dragFromViewY = state.viewY;
|
|
}
|
|
} else if (mouseHeld(M.MIDDLE)) {
|
|
if (state.dragging) {
|
|
const {x, y} = reGrid(mouseX, mouseY, patchX, patchY, spriteW, spriteH);
|
|
state.viewX = state.dragFromViewX - x + state.dragFromX;
|
|
state.viewY = state.dragFromViewY - y + state.dragFromY;
|
|
}
|
|
} else if (mouseClick(M.MIDDLE)) {
|
|
state.dragging = false;
|
|
} else if (mouseClick()) {
|
|
if (inSpriteSheetPageSwap) {
|
|
state.spriteSheetPage = (1+state.spriteSheetPage)%2;
|
|
}
|
|
}
|
|
if (keyPressed(K.ARROW_RIGHT)) {
|
|
state.viewX += 1;
|
|
}
|
|
if (keyPressed(K.ARROW_LEFT)) {
|
|
state.viewX -= 1;
|
|
}
|
|
if (keyPressed(K.ARROW_UP)) {
|
|
state.viewY -= 1;
|
|
}
|
|
if (keyPressed(K.ARROW_DOWN)) {
|
|
state.viewY += 1;
|
|
}
|
|
}
|
|
|
|
const outlineRect = (x: number, y: number, w: number, h: number, color: number) => {
|
|
fillRect(x, y, w, 1, color);
|
|
fillRect(x, y, 1, h, color);
|
|
fillRect(x+w-1, y, 1, h, color);
|
|
fillRect(x, y+h-1, w, 1, color);
|
|
}
|
|
|
|
const draw = () => {
|
|
const {
|
|
selectedSpriteSheet,
|
|
spriteWithinPage,
|
|
spriteSheetPage,
|
|
} = state;
|
|
clearScreen();
|
|
fillRect(0, 8, 128, 112, COLOR.DARKGRAY);
|
|
|
|
// Draw the current patch
|
|
drawVoidRect(patchX-1, patchY-1, (patchW*spriteW)+2, (patchH*spriteH)+2);
|
|
state.patch.values.forEach((val, i) => {
|
|
const spriteX = patchX+spriteW*(i%patchW);
|
|
const spriteY = patchY+spriteH*Math.floor(i/patchW);
|
|
if (!val) {
|
|
return;
|
|
}
|
|
const [sprsheet, sprite] = val;
|
|
drawTransparentRect(spriteX, spriteY, 8, 8);
|
|
if (getSheet(sprsheet).sheet_type === "spritesheet") {
|
|
useSpritesheet(sprsheet);
|
|
drawSprite(spriteX, spriteY, sprite);
|
|
}
|
|
});
|
|
|
|
// Draw the bar
|
|
fillRect(spriteSheetPickerX, spriteSheetPickerY-1, 128, 1, COLOR.BLACK);
|
|
fillRect(spriteSheetPickerX, spriteSheetPickerY, 128, 7, COLOR.DARKGRAY);
|
|
|
|
// Draw the spritesheet picker
|
|
fillRect(spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerTabW*spriteSheetPickerW, spriteSheetPickerTabW, COLOR.BLACK);
|
|
Array(spriteSheetPickerW*spriteSheetPickerH).fill(0).forEach((_, i) => {
|
|
const tabX = spriteSheetPickerX+spriteSheetPickerTabW*(i%spriteSheetPickerW);
|
|
const tabY = spriteSheetPickerY+spriteSheetPickerTabH*Math.floor(i/spriteSheetPickerW);
|
|
let color = COLOR.DARKGREEN;
|
|
if (getSheet(i).sheet_type !== "spritesheet") {
|
|
color = COLOR.BROWN;
|
|
}
|
|
if (i === page.activeSheet) {
|
|
color = COLOR.PURPLE;
|
|
}
|
|
if (i === selectedSpriteSheet) {
|
|
color = {
|
|
[COLOR.BROWN]: COLOR.TAN,
|
|
[COLOR.DARKGREEN]: COLOR.GREEN,
|
|
[COLOR.PURPLE]: COLOR.PINK,
|
|
}[color];
|
|
}
|
|
fillRect(tabX, tabY, spriteSheetPickerTabW, spriteSheetPickerTabH, color);
|
|
drawText(tabX+2, tabY+1, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"][i]);
|
|
});
|
|
|
|
// Draw the spritesheet page swap button
|
|
fillRect(spriteSheetPageSwapX, spriteSheetPageSwapY, spriteSheetPageSwapW, spriteSheetPageSwapH, COLOR.BLUE);
|
|
drawText(spriteSheetPageSwapX+2, spriteSheetPageSwapY+1, state.spriteSheetPage.toString());
|
|
|
|
// Draw the spritesheet
|
|
fillRect(spriteSheetX, spriteSheetY, (spriteSheetW*spriteW), (spriteSheetH*spriteH), COLOR.BLACK);
|
|
if (getSheet(selectedSpriteSheet).sheet_type === "spritesheet") {
|
|
useSpritesheet(selectedSpriteSheet);
|
|
Array(64).fill(0).forEach((_, i) => {
|
|
const sprI = i+64*spriteSheetPage;
|
|
const sprX = spriteSheetX+spriteW*(i%spriteSheetW);
|
|
const sprY = spriteSheetY+spriteH*Math.floor(i/spriteSheetW);
|
|
drawSprite(sprX, sprY, sprI);
|
|
if (i === spriteWithinPage) {
|
|
outlineRect(sprX, sprY, spriteW, spriteH, COLOR.WHITE);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
export const maptab = {
|
|
update,
|
|
draw,
|
|
} |