Beta 1 for F256!
This commit is contained in:
parent
52c03bb42c
commit
25f8ccc72d
18 changed files with 268 additions and 69 deletions
|
@ -28,6 +28,7 @@
|
|||
#include "common.h"
|
||||
|
||||
|
||||
void portAttributeSet(byte attribute);
|
||||
uint8_t portByteGet(uint32_t address);
|
||||
void portByteSet(uint32_t address, uint8_t value);
|
||||
char portCharGet(void);
|
||||
|
|
|
@ -40,6 +40,7 @@ typedef struct stateS {
|
|||
uint8_t operandCount;
|
||||
uint16_t operands[8];
|
||||
char alphabetTable[78];
|
||||
uint16_t checksum;
|
||||
char statusBar[256];
|
||||
byte statusBarLen;
|
||||
byte currentWindow;
|
||||
|
@ -48,6 +49,7 @@ typedef struct stateS {
|
|||
byte savedY;
|
||||
bool outputting;
|
||||
bool redirecting;
|
||||
byte linesOut;
|
||||
#ifdef DEBUGGING
|
||||
char *opcodesName[256];
|
||||
char *extOpcodesName[30];
|
||||
|
|
|
@ -118,6 +118,7 @@
|
|||
#define storyHXTrueDefaultBackgroundColor() portWordGet(storyHeaderExtensionTableAddress() + 12)
|
||||
|
||||
|
||||
void storyChecksumCalculate(void);
|
||||
uint32_t storyLength(void);
|
||||
void storySetup(byte width, byte height);
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef TEXT_H
|
||||
#define TEXT_H
|
||||
#ifndef TEXT_ZIP_H
|
||||
#define TEXT_ZIP_H
|
||||
|
||||
|
||||
#include "common.h"
|
||||
|
@ -33,6 +33,12 @@
|
|||
#define STREAM_OUTPUT_MEMORY 3
|
||||
#define STREAM_OUTPUT_SCRIPT 4
|
||||
|
||||
#define TEXT_ATTR_NORMAL 0
|
||||
#define TEXT_ATTR_REVERSE 1
|
||||
#define TEXT_ATTR_BOLD 2
|
||||
#define TEXT_ATTR_EMPHASIS 4
|
||||
#define TEXT_ATTR_FIXED_FONT 8
|
||||
|
||||
|
||||
void textCharPrint(char c);
|
||||
void textInput(uint32_t ramAddr, uint8_t length);
|
||||
|
@ -43,4 +49,4 @@ void textStringPrint(char *s);
|
|||
void textTimePrint(uint16_t hours, uint16_t minutes);
|
||||
|
||||
|
||||
#endif // TEXT_H
|
||||
#endif // TEXT_ZIP_H
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
project(zip LANGUAGES C)
|
||||
project(dos-like-zip LANGUAGES C)
|
||||
|
||||
find_package(SDL2 REQUIRED)
|
||||
|
||||
|
@ -30,8 +30,6 @@ set(HEADERS
|
|||
variable.h
|
||||
window.h
|
||||
zscii.h
|
||||
# czech.z3.h
|
||||
zork1.h
|
||||
)
|
||||
list(TRANSFORM HEADERS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/../../include/")
|
||||
|
||||
|
|
|
@ -30,9 +30,7 @@
|
|||
#include "story.h"
|
||||
#include "state.h"
|
||||
#include "interpreter.h"
|
||||
|
||||
#include "zork1.h"
|
||||
//#include "czech.z3.h"
|
||||
#include "text.h"
|
||||
|
||||
#pragma push_macro("bool")
|
||||
#undef bool
|
||||
|
@ -41,8 +39,38 @@
|
|||
#pragma pop_macro("bool")
|
||||
|
||||
|
||||
// The F256 has 512k of RAM. We use everything except the lower 64k.
|
||||
static uint8_t _RAM[1024 * (512 - 64)];
|
||||
static char *_storyFile = NULL;
|
||||
static uint8_t *_RAM = NULL;
|
||||
static uint8_t _attr = 7;
|
||||
|
||||
|
||||
void portAttributeSet(byte attribute) {
|
||||
switch (attribute) {
|
||||
case TEXT_ATTR_NORMAL:
|
||||
textbackground(1);
|
||||
textcolor(7);
|
||||
_attr = (1 << 4) + 7;
|
||||
break;
|
||||
|
||||
case TEXT_ATTR_REVERSE:
|
||||
textbackground(7);
|
||||
textcolor(1);
|
||||
_attr = (7 << 4) + 1;
|
||||
break;
|
||||
|
||||
case TEXT_ATTR_BOLD:
|
||||
textbackground(1);
|
||||
textcolor(15);
|
||||
_attr = (1 << 4) + 15;
|
||||
break;
|
||||
|
||||
case TEXT_ATTR_EMPHASIS:
|
||||
textbackground(1);
|
||||
textcolor(14);
|
||||
_attr = (1 << 4) + 14;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t portByteGet(uint32_t address) {
|
||||
|
@ -85,13 +113,17 @@ void portCharGetPos(byte *x, byte *y) {
|
|||
|
||||
|
||||
void portCharPrint(char c) {
|
||||
char ch[2] = { 0, 0 };
|
||||
char ch[2] = { 0, 0 };
|
||||
uint16_t *p;
|
||||
uint16_t v = (_attr << 8) + ' ';
|
||||
byte x;
|
||||
|
||||
if ((wherex() >= screenwidth()) || (c == '\n')) {
|
||||
gotoxy(0, wherey() + 1);
|
||||
while (wherey() >= screenheight()) {
|
||||
memmove(((uint16_t*)screenbuffer()), ((uint16_t*)screenbuffer()) + screenwidth(), screenwidth() * (screenheight() - 1) * sizeof(uint16_t));
|
||||
memset(((uint16_t*)screenbuffer()) + screenwidth() * (screenheight() - 1), 0, screenwidth() * sizeof(uint16_t));
|
||||
p = (uint16_t *)screenbuffer() + (screenwidth() * (screenheight() - 1));
|
||||
for (x=0; x<screenwidth(); x++) *p++ = v;
|
||||
gotoxy(0, wherey() - 1);
|
||||
}
|
||||
return;
|
||||
|
@ -177,14 +209,41 @@ uint16_t portRandomGet(int16_t range) {
|
|||
// If range is zero, randomize with "best" random seed.
|
||||
// If range is negative, use the positive value to seed.
|
||||
|
||||
return 42;
|
||||
if (range <= 0) {
|
||||
srandom(range < 0 ? -range : time(NULL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (random() % range) + 1;
|
||||
}
|
||||
|
||||
|
||||
void portStoryLoad(void) {
|
||||
// For now, we just copy an embedded Zork 1 into RAM.
|
||||
memcpy(_RAM, zork1, zork1_len);
|
||||
//memcpy(_RAM, czech_z3, czech_z3_len);
|
||||
FILE *in;
|
||||
uint32_t length;
|
||||
|
||||
in = fopen(_storyFile, "rb");
|
||||
if (!in) portDie("Unable to open %s!\n", _storyFile);
|
||||
|
||||
fseek(in, 0, SEEK_END);
|
||||
length = ftell(in);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
|
||||
_RAM = (byte *)malloc(length);
|
||||
if (!_RAM) {
|
||||
fclose(in);
|
||||
portDie("Unable to allocate %u bytes!\n", length);
|
||||
}
|
||||
|
||||
if (fread(_RAM, length, 1, in) != 1) {
|
||||
free(_RAM);
|
||||
fclose(in);
|
||||
portDie("Unable to read %s!\n", _storyFile);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
|
||||
storyChecksumCalculate();
|
||||
}
|
||||
|
||||
|
||||
|
@ -201,12 +260,16 @@ void portWordSet(uint32_t address, uint16_t value) {
|
|||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
if (argc != 2) portDie("Usage: %s [storyfile]\n", argv[0]);
|
||||
|
||||
_storyFile = argv[1];
|
||||
|
||||
setvideomode(videomode_80x25_9x16);
|
||||
curson();
|
||||
textbackground(1);
|
||||
textcolor(7);
|
||||
clrscr();
|
||||
gotoxy(0, screenheight() - 1);
|
||||
|
||||
stateReset();
|
||||
portStoryLoad();
|
||||
|
@ -214,5 +277,7 @@ int main(int argc, char *argv[]) {
|
|||
storySetup(80, 25);
|
||||
interpreterRun();
|
||||
|
||||
free(_RAM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
project(zip LANGUAGES C)
|
||||
project(f256-zip LANGUAGES C)
|
||||
|
||||
set(HEADERS
|
||||
common.h
|
||||
|
@ -64,4 +64,8 @@ add_executable(${CMAKE_PROJECT_NAME}
|
|||
f256zip.c
|
||||
)
|
||||
|
||||
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include)
|
||||
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../f256/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../f256/f256lib
|
||||
)
|
||||
|
|
|
@ -33,7 +33,7 @@ PATH=${LLVM}/bin:${PATH}
|
|||
|
||||
echo "__f256_start = ${START};" > ${SETTINGS}
|
||||
|
||||
CLANG="mos-f256k-clang -I../../../include -I${F256}/include -I${F256}/f256lib -Os"
|
||||
CLANG="mos-f256k-clang -I${F256}/include -I../../../include -I${F256}/f256lib -Os"
|
||||
|
||||
[[ -d .builddir ]] && rm -rf .builddir
|
||||
mkdir -p .builddir
|
||||
|
|
|
@ -42,12 +42,36 @@
|
|||
#include "memory.h"
|
||||
#include "state.h"
|
||||
#include "interpreter.h"
|
||||
#include "lib.h"
|
||||
#include "../../include/text.h"
|
||||
|
||||
|
||||
#define BASE_ADDRESS 0x10000
|
||||
|
||||
|
||||
static char *_saveName = 0;
|
||||
|
||||
|
||||
void portAttributeSet(byte attribute) {
|
||||
switch (attribute) {
|
||||
case TEXT_ATTR_NORMAL:
|
||||
textSetColor(7, 1);
|
||||
break;
|
||||
|
||||
case TEXT_ATTR_REVERSE:
|
||||
textSetColor(1, 7);
|
||||
break;
|
||||
|
||||
case TEXT_ATTR_BOLD:
|
||||
textSetColor(15, 1);
|
||||
break;
|
||||
|
||||
case TEXT_ATTR_EMPHASIS:
|
||||
textSetColor(14, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t portByteGet(uint32_t address) {
|
||||
return FAR_PEEK(BASE_ADDRESS + address);
|
||||
}
|
||||
|
@ -97,7 +121,7 @@ bool portFileRestore(void) {
|
|||
uint32_t i;
|
||||
byte b;
|
||||
|
||||
in = fopen("save.dat", "rb");
|
||||
in = fopen(_saveName, "rb");
|
||||
if (in) {
|
||||
ok = true;
|
||||
|
||||
|
@ -128,7 +152,7 @@ bool portFileSave(void) {
|
|||
uint32_t i;
|
||||
byte b;
|
||||
|
||||
out = fopen("save.dat", "wb");
|
||||
out = fopen(_saveName, "wb");
|
||||
if (out) {
|
||||
ok = true;
|
||||
|
||||
|
@ -154,7 +178,7 @@ bool portFileSave(void) {
|
|||
|
||||
|
||||
char portCharGet(void) {
|
||||
#if 1
|
||||
#if 0
|
||||
static char playback[] = "open mailbox\ntake leaflet\nread leaflet\ndrop leaflet\n";
|
||||
static uint32_t pointer = 0;
|
||||
|
||||
|
@ -183,10 +207,13 @@ uint16_t portRandomGet(int16_t range) {
|
|||
void portStoryLoad(void) {
|
||||
|
||||
// On the F256, the story is loaded into RAM along with the ZIP.
|
||||
// ***TODO*** This likely breaks the "restart" command.
|
||||
|
||||
// Later, we probably want to see if the user has a memory expansion
|
||||
// installed. If they do, we can use it and then use the lower memory
|
||||
// for graphics and sound.
|
||||
|
||||
storyChecksumCalculate();
|
||||
}
|
||||
|
||||
|
||||
|
@ -201,15 +228,54 @@ void portWordSet(uint32_t address, uint16_t value) {
|
|||
|
||||
|
||||
int main(void) {
|
||||
byte c;
|
||||
byte colors[16][3] = {
|
||||
{ 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0xaa },
|
||||
{ 0x00, 0xaa, 0x00 },
|
||||
{ 0x00, 0xaa, 0xaa },
|
||||
{ 0xaa, 0x00, 0x00 },
|
||||
{ 0xaa, 0x00, 0xaa },
|
||||
{ 0xaa, 0x55, 0x00 },
|
||||
{ 0xaa, 0xaa, 0xaa },
|
||||
{ 0x55, 0x55, 0x55 },
|
||||
{ 0x55, 0x55, 0xff },
|
||||
{ 0x55, 0xff, 0x55 },
|
||||
{ 0x55, 0xff, 0xff },
|
||||
{ 0xff, 0x55, 0x55 },
|
||||
{ 0xff, 0x55, 0xff },
|
||||
{ 0xff, 0xff, 0x55 },
|
||||
{ 0xff, 0xff, 0xff }
|
||||
};
|
||||
|
||||
_saveName = "zork1.sav";
|
||||
|
||||
f256Init();
|
||||
|
||||
textSetCursor(199);
|
||||
// Load EGA palette into text CLUT.
|
||||
for (c=0; c<16; c++) {
|
||||
textDefineForegroundColor(c, colors[c][0], colors[c][1], colors[c][2]);
|
||||
textDefineBackgroundColor(c, colors[c][0], colors[c][1], colors[c][2]);
|
||||
}
|
||||
textEnableBackgroundColors(true);
|
||||
|
||||
textSetColor(15, 0);
|
||||
textPrint("Welcome to MUDDLE Beta 1, Another Z-Machine!\n\n");
|
||||
textSetColor(7, 0);
|
||||
textPrint("Copyright 2024 Scott Duensing, All Rights Reserved.\n");
|
||||
textPrint("Kangaroo Punch Studios https://kangaroopunch.com\n\n\n");
|
||||
textSetColor(8, 0);
|
||||
textPrint("Thinking...");
|
||||
|
||||
stateReset();
|
||||
portStoryLoad();
|
||||
opcodesSetup();
|
||||
storySetup(80, 30);
|
||||
|
||||
textSetColor(7, 1);
|
||||
textClear();
|
||||
textSetCursor(199);
|
||||
|
||||
interpreterRun();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -64,7 +64,7 @@ void interpreterDoReturn(uint16_t r) {
|
|||
|
||||
if (__state.bp == 0) portDie(MSG_INT_STACK_UNDERFLOW);
|
||||
|
||||
#ifdef DEBUGGING
|
||||
#ifdef DEBUGGINGx
|
||||
printf("Returning: initial pc=%X, bp=%u, sp=%u\n", (unsigned int)__state.pc, __state.bp, __state.sp);
|
||||
#endif
|
||||
|
||||
|
@ -82,7 +82,7 @@ void interpreterDoReturn(uint16_t r) {
|
|||
// Pop the result storage location.
|
||||
storeId = (uint8_t)__state.stack[--__state.sp];
|
||||
|
||||
#ifdef DEBUGGING
|
||||
#ifdef DEBUGGINGx
|
||||
printf("Returning: new pc=%X, bp=%u, sp=%u\n", (unsigned int)__state.pc, __state.bp, __state.sp);
|
||||
#endif
|
||||
|
||||
|
@ -136,6 +136,10 @@ void interpreterRun(void) {
|
|||
opcodeT op;
|
||||
bool eight;
|
||||
|
||||
__state.savedX = 1;
|
||||
__state.savedY = storyScreenHeightLines();
|
||||
portCharSetPos(__state.savedX, __state.savedY);
|
||||
|
||||
while (__state.quit == 0) {
|
||||
opcode = ZPEEK(__state.pc++);
|
||||
extended = ((opcode == 190) && (storyVersion() >= 5)) ? true : false;
|
||||
|
@ -183,7 +187,7 @@ void interpreterRun(void) {
|
|||
|
||||
if (op == 0) portDie(MSG_INT_UNIMPLEMENTED_OPCODE, extended ? "ext" : "", opcode);
|
||||
|
||||
#ifdef DEBUGGING
|
||||
#ifdef DEBUGGINGx
|
||||
printf("ins=%u pc=%X sp=%u bp=%u %sopcode=%u ('%s') [",
|
||||
__state.instructionsRun,
|
||||
(unsigned int)__state.pc,
|
||||
|
@ -199,6 +203,7 @@ void interpreterRun(void) {
|
|||
printf("%X", (unsigned int)__state.operands[i]);
|
||||
}
|
||||
printf("]\n");
|
||||
fflush(stdout);
|
||||
|
||||
if (__state.instructionsRun == 261) {
|
||||
printf("\n*** BREAKING ***\n");
|
||||
|
@ -247,6 +252,7 @@ void interpreterTokenizeInput(void) {
|
|||
|
||||
#ifdef DEBUGGING
|
||||
printf("Max parse: %u\n", parseLen);
|
||||
printf("Parse Input: [");
|
||||
#endif
|
||||
|
||||
if (parseLen == 0) portDie(MSG_INT_PARSE_BUFFER_TOO_SMALL);
|
||||
|
@ -260,7 +266,9 @@ void interpreterTokenizeInput(void) {
|
|||
while (1) {
|
||||
isSep = false;
|
||||
ch = ZPEEK(ptr);
|
||||
|
||||
#ifdef DEBUGGING
|
||||
printf("%c", ch);
|
||||
#endif
|
||||
if ((ch == ' ') || (ch == 0)) {
|
||||
isSep = true;
|
||||
} else {
|
||||
|
@ -358,7 +366,9 @@ void interpreterTokenizeInput(void) {
|
|||
} // while
|
||||
|
||||
#ifdef DEBUGGING
|
||||
printf("]\n");
|
||||
printf("Tokenized %u tokens\n", (unsigned int)numToks);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
ZPOKE(__state.operands[1] + 1, numToks);
|
||||
|
|
|
@ -46,7 +46,7 @@ void opcodes_call(void) {
|
|||
} else {
|
||||
routine = memoryUnpackAddress(__state.operands[0], MEMORY_ROUTINE);
|
||||
numLocals = ZPEEK(routine++);
|
||||
#ifdef DEBUGGING
|
||||
#ifdef DEBUGGINGx
|
||||
printf("op0=%u routine=%X, numLocals=%d\n", __state.operands[0], (unsigned int)routine, numLocals);
|
||||
#endif
|
||||
if (numLocals > 15) portDie(MSG_OP_CALL_TOO_MANY_LOCALS, numLocals);
|
||||
|
|
|
@ -68,11 +68,15 @@ void opcodes_read(void) {
|
|||
ZPOKE(i, ch);
|
||||
} else if ((ch == '\n') || (ch == '\r') || (ch == 0)) {
|
||||
// End of line, end of input.
|
||||
ch = 0;
|
||||
ZPOKE(i, ch);
|
||||
ZPOKE(i, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
for (; i<input+inputLen; i++) ZPOKE(i, 0);
|
||||
|
||||
// Reset [MORE] counter.
|
||||
__state.linesOut = 0;
|
||||
|
||||
interpreterTokenizeInput();
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
#include "variable.h"
|
||||
#include "portme.h"
|
||||
#include "story.h"
|
||||
#include "memory.h"
|
||||
#include "interpreter.h"
|
||||
#include "memory.h"
|
||||
|
||||
|
||||
void opcodes_nop(void) {
|
||||
|
@ -47,26 +47,10 @@ void opcodes_piracy(void) {
|
|||
|
||||
|
||||
void opcodes_random(void) {
|
||||
variableStore((__state.pc++), portRandomGet((int16_t)__state.operands[0]));
|
||||
variableStore(ZPEEK(__state.pc++), portRandomGet((int16_t)__state.operands[0]));
|
||||
}
|
||||
|
||||
|
||||
void opcodes_verify(void) {
|
||||
/*
|
||||
uint16_t checksum = 0;
|
||||
uint32_t i;
|
||||
|
||||
for (i=64; i<storyLength(); i++) checksum += ZPEEK(i);
|
||||
|
||||
checksum %= 0x10000;
|
||||
|
||||
#ifdef DEBUGGING
|
||||
printf("\n\nChecksum = %u Header = %d\n\n", checksum, storyChecksum());
|
||||
#endif
|
||||
|
||||
interpreterDoBranch(checksum == storyChecksum() ? 1 : 0);
|
||||
*/
|
||||
|
||||
// We lie. Everything passes.
|
||||
interpreterDoBranch(1);
|
||||
interpreterDoBranch(__state.checksum == storyChecksum() ? 1 : 0);
|
||||
}
|
||||
|
|
|
@ -37,23 +37,26 @@ void opcodes_save(void) {
|
|||
|
||||
|
||||
void opcodes_restart(void) {
|
||||
byte width = ZPEEK(STORY_SCREEN_WIDTH_CHARACTERS);
|
||||
byte height = ZPEEK(STORY_SCREEN_HEIGHT_LINES);
|
||||
byte width = ZPEEK(STORY_SCREEN_WIDTH_CHARACTERS);
|
||||
byte height = ZPEEK(STORY_SCREEN_HEIGHT_LINES);
|
||||
uint16_t checksum = __state.checksum;
|
||||
|
||||
stateReset();
|
||||
portStoryLoad();
|
||||
__state.checksum = checksum;
|
||||
opcodesSetup();
|
||||
storySetup(width, height);
|
||||
}
|
||||
|
||||
|
||||
void opcodes_restore(void) {
|
||||
bool ok = portFileRestore();
|
||||
uint16_t oldLines = __state.statusWindowLineCount;
|
||||
bool ok = portFileRestore();
|
||||
|
||||
// Collapse upper window.
|
||||
__state.statusWindowLineCount = 0;
|
||||
windowSplit(0);
|
||||
if (ok) {
|
||||
// Collapse upper window.
|
||||
__state.statusWindowLineCount = 0;
|
||||
windowSplit(0);
|
||||
}
|
||||
|
||||
interpreterDoBranch(ok ? 1 : 0);
|
||||
}
|
||||
|
|
14
src/story.c
14
src/story.c
|
@ -26,6 +26,20 @@
|
|||
#include "memory.h"
|
||||
|
||||
|
||||
void storyChecksumCalculate(void) {
|
||||
uint32_t i;
|
||||
|
||||
__state.checksum = 0;
|
||||
for (i=64; i<storyLength(); i++) __state.checksum += ZPEEK(i);
|
||||
|
||||
__state.checksum %= 0x10000;
|
||||
|
||||
#ifdef DEBUGGING
|
||||
printf("\n\nChecksum = %u Header = %d\n\n", __state.checksum, storyChecksum());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uint32_t storyLength() {
|
||||
uint32_t m = (uint32_t)storyFileSize() * 2;
|
||||
|
||||
|
|
41
src/text.c
41
src/text.c
|
@ -32,6 +32,10 @@
|
|||
#include "lib.h"
|
||||
|
||||
|
||||
static void textMoreCheck(void);
|
||||
static void textNumPrint_r(int32_t val);
|
||||
|
||||
|
||||
void textCharPrint(char c) {
|
||||
static char lineBuffer[256];
|
||||
static uint16_t lineWidth = 0;
|
||||
|
@ -53,7 +57,7 @@ void textCharPrint(char c) {
|
|||
if (!__state.outputting) return;
|
||||
|
||||
// Do we need to word wrap?
|
||||
if (lineWidth == width - 2) {
|
||||
if (lineWidth == width - 1) {
|
||||
// Are we printing a space or CR? If so, just go to next line.
|
||||
if ((c == ' ') || (c == '\n')) {
|
||||
c = '\n';
|
||||
|
@ -77,9 +81,11 @@ void textCharPrint(char c) {
|
|||
}
|
||||
// Wrap display.
|
||||
portCharPrint('\n');
|
||||
__state.linesOut++;
|
||||
// Move erased characters to front of buffer & redisplay.
|
||||
portCharGetPos(&x, &y);
|
||||
portCharSetPos(1, y);
|
||||
textMoreCheck();
|
||||
x = 0;
|
||||
for (i=space; i<=lineWidth; i++) {
|
||||
lineBuffer[x++] = lineBuffer[i];
|
||||
|
@ -97,12 +103,32 @@ void textCharPrint(char c) {
|
|||
if (c == '\n') {
|
||||
// New line.
|
||||
lineWidth = 0;
|
||||
__state.linesOut++;
|
||||
textMoreCheck();
|
||||
} else {
|
||||
lineBuffer[lineWidth++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void textMoreCheck(void) {
|
||||
byte x;
|
||||
byte y;
|
||||
|
||||
if (__state.linesOut >= storyScreenHeightLines() - __state.statusWindowLineCount - 1) {
|
||||
// Display [MORE] prompt.
|
||||
portCharGetPos(&x, &y);
|
||||
textStringPrint("[MORE]");
|
||||
textStringPrint(" ");
|
||||
portCharGet();
|
||||
portCharSetPos(x, y);
|
||||
textStringPrint(" ");
|
||||
portCharSetPos(x, y);
|
||||
__state.linesOut = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void textNumPrint_r(int32_t val) {
|
||||
|
||||
if (val > 9) {
|
||||
|
@ -212,5 +238,18 @@ void textStringPrint(char *s) {
|
|||
|
||||
|
||||
void textTimePrint(uint16_t hours, uint16_t minutes) {
|
||||
bool PM = (hours < 12) ? false : true;
|
||||
|
||||
hours %= 12;
|
||||
if (hours == 0) hours = 12;
|
||||
|
||||
if (hours < 10) textCharPrint(' ');
|
||||
textNumPrint(hours);
|
||||
|
||||
textCharPrint(':');
|
||||
|
||||
if (minutes < 10) textCharPrint('0');
|
||||
textNumPrint(minutes);
|
||||
|
||||
textStringPrint((PM ? " pm" : " am"));
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ uint8_t variableAddress(uint8_t var, bool writing) {
|
|||
if (writing) {
|
||||
|
||||
if (__state.sp >= sizeof(__state.stack)) portDie(MSG_INT_STACK_OVERFLOW);
|
||||
#ifdef DEBUGGING
|
||||
#ifdef DEBUGGINGx
|
||||
printf("Push stack\n");
|
||||
#endif
|
||||
return __state.sp++;
|
||||
|
@ -71,7 +71,7 @@ uint8_t variableAddress(uint8_t var, bool writing) {
|
|||
if (__state.sp == 0) portDie(MSG_INT_STACK_UNDERFLOW);
|
||||
numLocals = __state.bp ? __state.stack[__state.bp - 1] : 0;
|
||||
if ((__state.bp + numLocals) >= sizeof(__state.stack)) portDie(MSG_INT_STACK_UNDERFLOW);
|
||||
#ifdef DEBUGGING
|
||||
#ifdef DEBUGGINGx
|
||||
printf("Pop stack\n");
|
||||
#endif
|
||||
return --__state.sp;
|
||||
|
|
14
src/window.c
14
src/window.c
|
@ -130,9 +130,11 @@ void windowSplit(byte newLines) {
|
|||
|
||||
|
||||
void windowUpdateStatusBar(void) {
|
||||
byte width = storyScreenWidthCharacters() - 1;
|
||||
|
||||
windowSet(WINDOW_STATUS);
|
||||
portCharSetPos(1, 1);
|
||||
// Reverse attribute.
|
||||
portAttributeSet(TEXT_ATTR_REVERSE);
|
||||
textOutputStream(STREAM_OUTPUT_MEMORY, 0);
|
||||
|
||||
windowPadStatus(1);
|
||||
|
@ -142,26 +144,26 @@ void windowUpdateStatusBar(void) {
|
|||
|
||||
if ((storyFlags() & STORY_STATUS_MASK) == STORY_STATUS_HOURS_MINUTES) {
|
||||
// Timed game.
|
||||
windowPadStatus(storyScreenWidthCharacters() - 21);
|
||||
windowPadStatus(width - 21);
|
||||
textStringPrint(" Time: ");
|
||||
textTimePrint(variableLoad(17), variableLoad(18));
|
||||
} else {
|
||||
// Scored game.
|
||||
windowPadStatus(storyScreenWidthCharacters() - 31);
|
||||
windowPadStatus(width - 31);
|
||||
textStringPrint(" Score: ");
|
||||
textNumPrint(variableLoad(17));
|
||||
windowPadStatus(storyScreenWidthCharacters() - 15);
|
||||
windowPadStatus(width - 15);
|
||||
textStringPrint(" Moves: ");
|
||||
textNumPrint(variableLoad(18));
|
||||
}
|
||||
|
||||
windowPadStatus(storyScreenWidthCharacters());
|
||||
windowPadStatus(width);
|
||||
__state.statusBar[__state.statusBarLen] = 0;
|
||||
|
||||
textOutputStream(-STREAM_OUTPUT_MEMORY, 0);
|
||||
|
||||
textStringPrint(__state.statusBar);
|
||||
|
||||
// Normal attribute.
|
||||
portAttributeSet(TEXT_ATTR_NORMAL);
|
||||
windowSet(WINDOW_TEXT);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue