Add readScreen summary format and readVicState sprite visibility
- readScreen now supports format: "summary" | "full" option - summary: non-empty lines with trimming (agent-friendly) - full: all 25 lines (debugging use) - readVicState now tracks sprite visibility: - visibleSprites array with sprite numbers - visibleCount for quick checking - Updated hint when sprites enabled but not visible AX feedback from owl review. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
37f53616ff
commit
56ea0984bb
1 changed files with 47 additions and 9 deletions
54
src/index.ts
54
src/index.ts
|
|
@ -673,10 +673,15 @@ Note: This reads from the current screen RAM location (may not be $0400 if the p
|
||||||
In bitmap modes, the data won't represent text.
|
In bitmap modes, the data won't represent text.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
|
- format: "full" (default) returns all 25 lines, "summary" returns only non-empty lines
|
||||||
- includeRaw: Also return raw screen codes (default: false)
|
- includeRaw: Also return raw screen codes (default: false)
|
||||||
|
|
||||||
Related tools: readColorRam, readVicState, readMemory`,
|
Related tools: readColorRam, readVicState, readMemory`,
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
|
format: z
|
||||||
|
.enum(["full", "summary"])
|
||||||
|
.optional()
|
||||||
|
.describe("Output format: 'full' (all 25 lines) or 'summary' (non-empty lines only)"),
|
||||||
includeRaw: z
|
includeRaw: z
|
||||||
.boolean()
|
.boolean()
|
||||||
.optional()
|
.optional()
|
||||||
|
|
@ -707,21 +712,36 @@ Related tools: readColorRam, readVicState, readMemory`,
|
||||||
.map((line, idx) => ({ line: idx, content: line }))
|
.map((line, idx) => ({ line: idx, content: line }))
|
||||||
.filter((l) => l.content.trim().length > 0);
|
.filter((l) => l.content.trim().length > 0);
|
||||||
|
|
||||||
|
const useSummaryFormat = args.format === "summary";
|
||||||
|
|
||||||
const response: Record<string, unknown> = {
|
const response: Record<string, unknown> = {
|
||||||
screenAddress: {
|
screenAddress: {
|
||||||
value: videoAddrs.screenAddress,
|
value: videoAddrs.screenAddress,
|
||||||
hex: `$${videoAddrs.screenAddress.toString(16).padStart(4, "0")}`,
|
hex: `$${videoAddrs.screenAddress.toString(16).padStart(4, "0")}`,
|
||||||
},
|
},
|
||||||
vicBank: bankInfo.bank,
|
vicBank: bankInfo.bank,
|
||||||
lines: textLines,
|
format: useSummaryFormat ? "summary" : "full",
|
||||||
summary: {
|
};
|
||||||
|
|
||||||
|
if (useSummaryFormat) {
|
||||||
|
// Summary format: only non-empty lines with line numbers
|
||||||
|
response.lines = nonEmptyLines.map((l) => ({
|
||||||
|
lineNumber: l.line,
|
||||||
|
content: l.content,
|
||||||
|
}));
|
||||||
|
response.totalLines = 25;
|
||||||
|
response.nonEmptyCount = nonEmptyLines.length;
|
||||||
|
} else {
|
||||||
|
// Full format: all 25 lines
|
||||||
|
response.lines = textLines;
|
||||||
|
response.summary = {
|
||||||
nonEmptyLines: nonEmptyLines.length,
|
nonEmptyLines: nonEmptyLines.length,
|
||||||
preview:
|
preview:
|
||||||
nonEmptyLines.length > 0
|
nonEmptyLines.length > 0
|
||||||
? nonEmptyLines.slice(0, 3).map((l) => `Line ${l.line}: "${l.content}"`)
|
? nonEmptyLines.slice(0, 3).map((l) => `Line ${l.line}: "${l.content}"`)
|
||||||
: ["Screen appears empty"],
|
: ["Screen appears empty"],
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (args.includeRaw) {
|
if (args.includeRaw) {
|
||||||
response.raw = Array.from(screenData);
|
response.raw = Array.from(screenData);
|
||||||
|
|
@ -863,11 +883,25 @@ Related tools: readScreen, readSprites, readMemory (for $D000-$D02E)`,
|
||||||
// Raster position (9-bit)
|
// Raster position (9-bit)
|
||||||
const rasterLine = vicData[0x12] | ((d011 & 0x80) << 1);
|
const rasterLine = vicData[0x12] | ((d011 & 0x80) << 1);
|
||||||
|
|
||||||
// Sprite enable
|
// Sprite enable and visibility check
|
||||||
const spriteEnable = vicData[0x15];
|
const spriteEnable = vicData[0x15];
|
||||||
const enabledSprites = [];
|
const spriteXMsb = vicData[0x10];
|
||||||
|
const enabledSprites: number[] = [];
|
||||||
|
const visibleSprites: number[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < 8; i++) {
|
for (let i = 0; i < 8; i++) {
|
||||||
if (spriteEnable & (1 << i)) enabledSprites.push(i);
|
if (spriteEnable & (1 << i)) {
|
||||||
|
enabledSprites.push(i);
|
||||||
|
// Check visibility
|
||||||
|
const xLow = vicData[i * 2];
|
||||||
|
const xHigh = (spriteXMsb & (1 << i)) ? 256 : 0;
|
||||||
|
const x = xLow + xHigh;
|
||||||
|
const y = vicData[i * 2 + 1];
|
||||||
|
const visibility = isSpriteVisible(x, y, true);
|
||||||
|
if (visibility.visible) {
|
||||||
|
visibleSprites.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display enable
|
// Display enable
|
||||||
|
|
@ -921,7 +955,9 @@ Related tools: readScreen, readSprites, readMemory (for $D000-$D02E)`,
|
||||||
value: spriteEnable,
|
value: spriteEnable,
|
||||||
binary: spriteEnable.toString(2).padStart(8, "0"),
|
binary: spriteEnable.toString(2).padStart(8, "0"),
|
||||||
enabledSprites,
|
enabledSprites,
|
||||||
count: enabledSprites.length,
|
enabledCount: enabledSprites.length,
|
||||||
|
visibleSprites,
|
||||||
|
visibleCount: visibleSprites.length,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Sprite multicolor registers
|
// Sprite multicolor registers
|
||||||
|
|
@ -931,7 +967,9 @@ Related tools: readScreen, readSprites, readMemory (for $D000-$D02E)`,
|
||||||
hint: !displayEnabled
|
hint: !displayEnabled
|
||||||
? "Display is blanked (DEN=0) - screen shows border color only"
|
? "Display is blanked (DEN=0) - screen shows border color only"
|
||||||
: enabledSprites.length > 0
|
: enabledSprites.length > 0
|
||||||
? `${graphicsMode.mode} mode, ${enabledSprites.length} sprite(s) enabled. Use readSprites() for sprite details.`
|
? visibleSprites.length < enabledSprites.length
|
||||||
|
? `${graphicsMode.mode} mode, ${enabledSprites.length} sprite(s) enabled but only ${visibleSprites.length} visible. Use readSprites() for details.`
|
||||||
|
: `${graphicsMode.mode} mode, ${enabledSprites.length} sprite(s) enabled and visible.`
|
||||||
: `${graphicsMode.mode} mode, no sprites enabled.`,
|
: `${graphicsMode.mode} mode, no sprites enabled.`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue