From 2266b9497ce91c2d700f3026b8eef586f3977d6f Mon Sep 17 00:00:00 2001 From: acn Date: Tue, 21 Apr 2020 16:16:06 +0200 Subject: [PATCH] changed ks/ftm to be more compliant with KS system --- FindThatMine/ftm.c | 172 ++++++++++++++------ FindThatMine/ftm.com | Bin 8704 -> 10112 bytes FindThatMine/ks.h | 373 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 432 insertions(+), 113 deletions(-) diff --git a/FindThatMine/ftm.c b/FindThatMine/ftm.c index 567b5be..856a0b8 100644 --- a/FindThatMine/ftm.c +++ b/FindThatMine/ftm.c @@ -5,8 +5,7 @@ Derived from the plain CP/M version. Copyright (c) 2012-2020 Miguel Garcia / FloppySoftware, Spain. - - VT100 color version by Anna Christina Naß + Color version by Anna Christina Naß This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -22,6 +21,12 @@ along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + Author's contact: + + www.floppysoftware.es + cpm-connections.blogspot.com + floppysoftware@gmail.com + To compile with MESCC: cc ftm @@ -29,6 +34,20 @@ zsm ftm hextocom ftm + Usage: + + ftm [tty_name] + If no tty_name is given, VT100COL is + + Revisions: + + 11 Sep 2012 : v1.0 : Initial version for Amstrad PCW & Samaruc GUI. + 26 Jul 2013 : v1.2 : Adapted to Samaruc v1.5. + 16 Feb 2014 : v1.3 : Adapted to last changes in Samaruc. + 09 Jul 2014 : v1.4 : CP/M version. + 07 Apr 2020 : v2.0 : Adapted to KS library for CP/M. + 21 Apr 2020 : v2.1 : Added color option (by Anna Christina Naß + Notes: LEVELS: 1 2 3 NOTES @@ -50,7 +69,7 @@ #include #include -/* KS library +/* KS libraries */ #include "ks.h" @@ -104,7 +123,32 @@ int argc, argv[]; /* char *argv[] - unsupported by MESCC */ /* Init KS */ - KsHello(0); + if(argc == 1) { + KsHello(KS_VT100COL); + } + else { + if(strcmp(argv[1], "/?")==0) { + tty_s = KsGetNames(); + tty_n = KsGetHowMany(); + + puts("Usage: ftm [tty_name]\n"); + puts("Supported TTY names:"); + + for(i = 0; i < tty_n; ++i) { + putchar('\t'); puts(tty_s[i]); + } + + puts("If no tty_name is given, VT100COL (VT100 with color) is used."); + + return; + } + else { + if(KsHello(KsGetCode(argv[1])) == -1) { + puts("Unknown TTY name.\n\nRun 'ftm' to know supported TTYs.\n"); + return; + } + } + } /* Setup */ @@ -123,7 +167,6 @@ int argc, argv[]; /* char *argv[] - unsupported by MESCC */ */ Setup() { - int i; BYTE *p; /* Build array to help in calculation of adjacent squares @@ -159,21 +202,25 @@ Setup() Copyright() { int r; - char str[80]; + char str[100]; KsClear(); - sprintf(str, "%sFind %sThat %sMine%s!%s\n", FGBRED, FGBCYN, FGBBLU, FGBYEL, RESET); - KsPosCursor(r = 0, 32); - KsPutStr(str); - //KsCenterStr(r = 0, "Find That Mine!\n"); - KsCenterStr(++r , "v2.0 for CP/M & Z80\n\n"); + if(KsCan(KS_CAN_COLOR)) { + //sprintf(str, "%sFind %sThat %sMine%s!%s\n", KsFgCol(RED), KsFgCol(CYN), KsFgCol(BLU), KsFgCol(YEL), KsResetAttr()); + KsPosCursor(r = 2, 32); + KsFgCol(BRED); KsPutStr("Find "); KsFgCol(BCYN); KsPutStr("That "); KsFgCol(BBLU); KsPutStr("Mine"); KsFgCol(BYEL); KsPutStr("!\n"); KsResetAttr(); + } + else { + KsCenterStr(r = 2, "Find That Mine!\n"); + } + KsCenterStr(++r , "v2.1 for CP/M & Z80\n\n"); ++r; KsCenterStr(++r ,"A minesweeper type game.\n"); ++r; KsCenterStr(++r ,"(c) 2012-2020 Miguel Garcia / Floppy Software, Spain.\n"); KsCenterStr(++r ,"www.floppysoftware.es\n"); - KsCenterStr(++r ,"VT100 color version by acn@acn.wtf\n\n"); + KsCenterStr(++r ,"color version by acn@acn.wtf\n\n"); } /* Select and play a level @@ -485,8 +532,11 @@ int row, col; ShowBoard() { int r, c; + int col; + col = KsCan(KS_CAN_COLOR); KsClear(); + PrStr("\n\n"); PrStr("\t "); for(c = 0; c < brd_cols; ++c) { @@ -494,15 +544,20 @@ ShowBoard() } PrCh('\n'); - PrStr(FGBGRY); - PrStr("\t "); PrCh(201); - PrChTimes(205, brd_cols + brd_cols + 1); - PrCh(187); PrCh('\n'); - PrStr(RESET); + if(col) KsFgCol(BBLK); + PrStr("\t +"); + PrChTimes('-', brd_cols + brd_cols + 1); + PrCh('+'); PrCh('\n'); + if(col) KsResetAttr(); for(r = 0; r < brd_rows; ++r) { - PrCh('\t'); PrCh('0' + r); PrStr(FGBGRY); PrCh(186); PrStr(RESET); + PrCh('\t'); PrCh('0' + r); + if(col) { + KsFgCol(BBLK); PrCh('|'); KsResetAttr(); + } + else + PrCh('|'); for(c = 0; c < brd_cols; ++c) { @@ -511,37 +566,55 @@ ShowBoard() if(TstVis(r, c)) { if(GetCount(r, c)) { - switch(GetCount(r, c)) - { - case 1: PrStr(FGBBLU); break; - case 2: PrStr(FGGRN); break; - case 3: PrStr(FGBRED); break; - case 4: PrStr(FGBLU); break; - case 5: PrStr(FGRED); break; - default: PrStr(FGCYN); break; + if(col) { + switch(GetCount(r, c)) + { + case 1: KsFgCol(BBLU); break; + case 2: KsFgCol(GRN); break; + case 3: KsFgCol(BRED); break; + case 4: KsFgCol(BLU); break; + case 5: KsFgCol(RED); break; + default: KsFgCol(CYN); break; + } + PrCh('0' + GetCount(r, c)); + KsResetAttr(); } - PrCh('0' + GetCount(r, c)); - PrStr(RESET); + else + PrCh('0' + GetCount(r, c)); } - else { + else PrCh(SPR_BLANK); - } } else if(gameover) { - if(TstMine(r, c)) { + if(TstMine(r, c)) + { if(TstFlag(r, c)) { - PrStr(FGRED); PrCh(SPR_FLAG); PrStr(RESET); + if(col) { + KsFgCol(RED); + PrCh(SPR_FLAG); + KsResetAttr(); + } else + PrCh(SPR_FLAG); } else { - PrStr(FGRED); PrCh(SPR_MINE); PrStr(RESET); + if(col) { + KsFgCol(RED); + PrCh(SPR_MINE); + KsResetAttr(); + } else + PrCh(SPR_MINE); } } + else if(TstFlag(r, c)) + PrCh(SPR_ERR); else { - if(TstFlag(r, c)) - PrCh(SPR_ERR); - else - PrStr(FGBGRY); PrCh(SPR_UNK); PrStr(RESET); + if(col) { + KsFgCol(BBLK); + PrCh(SPR_UNK); + KsResetAttr(); + } else + PrCh(SPR_UNK); } } else @@ -555,16 +628,25 @@ ShowBoard() PrCh(SPR_UNK); #else if(TstFlag(r, c)) { - PrStr(FGRED); PrCh(SPR_FLAG); PrStr(RESET); + if(col) KsFgCol(RED); + PrCh(SPR_FLAG); + if(col) KsResetAttr(); } else { - PrStr(FGBGRY); PrCh(SPR_UNK); PrStr(RESET); + if(col) KsFgCol(BBLK); + PrCh(SPR_UNK); + if(col) KsResetAttr(); } #endif } } - PrCh(' '); PrStr(FGBGRY); PrCh(186); PrStr(RESET); PrCh('0' + r); + if(col) { + PrCh(' '); KsFgCol(BBLK); PrCh('|'); KsResetAttr(); PrCh('0' + r); + } + else { + PrCh(' '); PrCh('|'); PrCh('0' + r); + } switch(r) { @@ -605,11 +687,11 @@ ShowBoard() PrCh('\n'); } - PrStr(FGBGRY); - PrStr("\t "); PrCh(200); - PrChTimes(205, brd_cols + brd_cols + 1); - PrCh(188); PrCh('\n'); - PrStr(RESET); + if(col) KsFgCol(BBLK); + PrStr("\t +"); + PrChTimes('-', brd_cols + brd_cols + 1); + PrCh('+'); PrCh('\n'); + if(col) KsResetAttr(); PrStr("\t "); for(c = 0; c < brd_cols; ++c) { diff --git a/FindThatMine/ftm.com b/FindThatMine/ftm.com index 587de7b1dbbb834119b9d69408c6cec40de2a5b4..0e968ef9dd1882bc1e96932a14eb535230e17731 100644 GIT binary patch literal 10112 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 literal 8704 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 Copyright (c) 2016, 2017 Miguel I. Garcia Lopez / FloppySoftware, Spain @@ -29,45 +38,82 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + Author's contact: + + www.floppysoftware.es + cpm-connections.blogspot.com + floppysoftware@gmail.com + + Revisions: + + 03 Sep 2016 : Work begins. + 29 Sep 2016 : Rename functions. + 03 Oct 2016 : Reworked KsInit() and others. Added support for reverse and underline. + 14 Jul 2017 : Added TTY names. + 07 Apr 2020 : TTY names in uppercase. + 08 Apr 2020 : Added KsGetNames(), KsGetHowMany(). */ -int xks_rows = 25; // Screen rows -int xks_cols = 80; // Screen columns -BYTE *xks_clrscr = "\e[H\e[J"; // Clear screen -BYTE *xks_poscur = "\e[%r;%cH"; // Position cursor -BYTE *xks_shwcur = "\e[?25h"; // Show cursor -BYTE *xks_hidcur = "\e[?25l"; // Hide cursor -BYTE *xks_yrever = "\e[7m"; // Reverse on -BYTE *xks_nrever = "\e[m"; // Reverse off -BYTE *xks_yuline = "\e[4m"; // Underline on -BYTE *xks_nuline = "\e[m"; // Underline off +/* Public defines + -------------- +*/ +#define KS_VT52 0 +#define KS_VT100 1 +#define KS_PCW 2 +#define KS_CPC 3 +#define KS_SPECTRUM 4 +#define KS_KAYPRO 5 +#define KS_VT100COL 6 -#define RESET "\e[0m" // reset all attributes -#define FGBLK "\e[30m" // black -#define FGRED "\e[31m" // red -#define FGGRN "\e[32m" // green -#define FGYEL "\e[33m" // yellow -#define FGBLU "\e[34m" // blue -#define FGMAG "\e[35m" // magenta -#define FGCYN "\e[36m" // cyan -#define FGWHT "\e[37m" // white/gray -#define FGBGRY "\e[30;1m" // gray ("bright black") -#define FGBRED "\e[31;1m" // bright red -#define FGBGRN "\e[32;1m" // bright green -#define FGBYEL "\e[33;1m" // bright yellow -#define FGBBLU "\e[34;1m" // bright blue -#define FGBMAG "\e[35;1m" // bright magenta -#define FGBCYN "\e[36;1m" // bright cyan -#define FGBWHT "\e[37;1m" // bright white -#define BGBLK "\e[40m" // black -#define BGRED "\e[41m" // red -#define BGGRN "\e[42m" // green -#define BGYEL "\e[43m" // yellow -#define BGBLU "\e[44m" // blue -#define BGMAG "\e[45m" // magenta -#define BGCYN "\e[46m" // cyan -#define BGWHT "\e[47m" // white +#define KS_CAN_HIDE 0 // Can hide & show cursor +#define KS_CAN_REVERSE 1 // Can reverse text +#define KS_CAN_UNDERLINE 2 // Can underline text +#define KS_CAN_COLOR 3 // Can display color +/* Define color numbers + -------------------- +*/ +// usable as foreground + background colors: +#define BLK 0 // black +#define RED 1 // red +#define GRN 2 // green +#define YEL 3 // yellow +#define BLU 4 // blue +#define MAG 5 // magenta +#define CYN 6 // cyan +#define WHT 7 // gray +// the following colors are "bright" colors, these do not work as background colors +#define BBLK 8 // dark gray ("bright black") +#define BRED 9 // bright red +#define BGRN 10 // bright green +#define BYEL 11 // bright yellow +#define BBLU 12 // bright blue +#define BMAG 13 // bright magenta +#define BCYN 14 // bright cyan +#define BWHT 15 // bright white + +/* Private defines + --------------- +*/ +#define XKS_TTYS 7 // Number of supported TTYs + +/* Private globals + --------------- +*/ +WORD xks_names[XKS_TTYS]; // TTY names by code -- char *xks_names[] + +int xks_rows; // Screen rows +int xks_cols; // Screen columns +BYTE *xks_clrscr; // Clear screen +BYTE *xks_poscur; // Position cursor +BYTE *xks_shwcur; // Show cursor +BYTE *xks_hidcur; // Hide cursor +BYTE *xks_yrever; // Reverse on +BYTE *xks_nrever; // Reverse off +BYTE *xks_yuline; // Underline on +BYTE *xks_nuline; // Underline off +int xks_color; // TTY can display color /** * @fn int KsHello(char *tty_name) @@ -81,6 +127,73 @@ int code; { // Setup BIOS jumps, etc. xKsInit(); + + xks_color = FALSE; + + // Setup TTY + switch(code) { + case KS_VT52 : + xKsInit24x80(); + xks_clrscr = "\eH\eJ"; + xks_poscur = "A\eY%r%c"; + break; + + case KS_VT100 : + xks_rows = 25; + xks_cols = 80; + xks_clrscr = "\e[H\e[J"; + xks_poscur = "B\e[%r;%cH"; + xks_yrever = "\e[7m"; + xks_nrever = "\e[m"; + xks_yuline = "\e[4m"; + xks_nuline = "\e[m"; + break; + + case KS_PCW : + xks_rows = 31; + xks_cols = 90; + xKsInitAmstrad(); + break; + + case KS_CPC : + xKsInit24x80(); + xKsInitAmstrad(); + break; + + case KS_SPECTRUM : + xks_rows = 23; + xks_cols = 51; + xKsInitAmstrad(); + + KsPutRawCh('\e'); KsPutRawCh('3'); KsPutRawCh(1); + break; + + case KS_KAYPRO : + xKsInit24x80(); + xks_clrscr = "?"; *xks_clrscr = 26; // ^Z + xks_poscur = "A\e=%r%c"; + break; + + case KS_VT100COL : + xks_rows = 25; + xks_cols = 80; + xks_clrscr = "\e[H\e[J"; + xks_poscur = "B\e[%r;%cH"; + xks_shwcur = "\e[?25h"; + xks_hidcur = "\e[?25l"; + xks_yrever = "\e[7m"; + xks_nrever = "\e[m"; + xks_yuline = "\e[4m"; + xks_nuline = "\e[m"; + xks_color = TRUE; + break; + + default : + // Unknown tty code + return -1; + } + + // Success return 0; } @@ -104,12 +217,21 @@ KsBye() KsGetCode(name) char *name; { - if(strcmp(name, "VT100")) { - return 0; - } - else { - return -1; + int i; + + if(!xks_names[0]) { + xKsNames(); } + + for(i = 0; i < XKS_TTYS; ++i) { + if(!strcmp(name, xks_names[i])) { + // Found + return i; + } + } + + // Unknown tty name + return -1; } /** @@ -122,12 +244,17 @@ char *name; KsGetName(code) int code; { - if(code==0) { - return "VT100"; + if(!xks_names[0]) { + xKsNames(); } - else { - return NULL; + + if(code >= 0 && code < XKS_TTYS) { + // Found + return xks_names[code]; } + + // Unknown tty code + return NULL; } /** @@ -138,8 +265,10 @@ int code; */ KsGetNames() { - WORD xks_names[1]; - xks_names[0] = "VT100"; + if(!xks_names[0]) { + xKsNames(); + } + return xks_names; } @@ -151,7 +280,7 @@ KsGetNames() */ KsGetHowMany() { - return 1; + return XKS_TTYS; } /** @@ -174,17 +303,44 @@ int row, col; { char *p; int v; - for(p = xks_poscur; *p; ++p) { + for(p = xks_poscur + 1; *p; ++p) { if(*p != '%') { KsPutRawCh(*p); } else { v = (*(++p) == 'r' ? row : col); - xKsPutDec(1 + v); + + if(*xks_poscur == 'A') { + // A + KsPutRawCh(32 + v); + } + else { + // B + xKsPutDec(1 + v); + } } } } +/** + * @fn int KsCan(int cap) + * @brief Check if the TTY has a capability. + * @param cap - capatility code + * @return 0 on NO, other on YES + */ +KsCan(cap) +int cap; +{ + switch(cap) { + case KS_CAN_HIDE : return xks_shwcur != NULL; + case KS_CAN_REVERSE : return xks_yrever != NULL; + case KS_CAN_UNDERLINE : return xks_yuline != NULL; + case KS_CAN_COLOR : return xks_color; + } + + return 0; +} + /** * @fn void KsSetCursor(int toggle) * @brief Show or hide the cursor on screen. @@ -226,6 +382,68 @@ int toggle; } } +/** + * @fn char *KsFgCol(int color) + * @brief Set foreground color + * If the TTY does not have this capability, does nothing. + * @param color - color number, see #defines + */ +KsFgCol(color) +int color; +{ + char rc[12]; + if(xks_color) { + if(color<8) { + sprintf(rc, "\e[3%dm", color); + KsPutStr(rc); + } + if(color>=8) { + sprintf(rc, "\e[3%d;1m", color-8); // bright colors begin at 8 + KsPutStr(rc); + } + } +} + +/** + * @fn void KsBgCol(int color) + * @brief Set background color + * If the TTY does not have this capability, does nothing. + * @param color - color number, see #defines + */ +KsBgCol(color) +int color; +{ + char str[6]; + if(xks_color) { + sprintf(str, "\e[4%dm", color); + KsPutStr(str); + } +} + +/** + * @fn void KsResetAttr() + * If the TTY does not support color, does nothing + * @brief Resets all attributes + */ +KsResetAttr() +{ + if(xks_color) + KsPutStr("\e[m"); +} + +/** + * @fn void KsCenterStr(int row, char *s) + * @brief Print a string centered on screen. + * @param row - screen row + * @param s - string + */ +KsCenterStr(row, s) +int row; char *s; +{ + KsPosCursor(row, (KsGetCols() - strlen(s)) / 2); + KsPutStr(s); +} + /** * @fn int KsGetRows(void) * @brief Get TTY rows. @@ -246,19 +464,6 @@ KsGetCols() return xks_cols; } -/** - * @fn void KsCenterStr(int row, char *s) - * @brief Print a string centered on screen. - * @param row - screen row - * @param s - string - */ -KsCenterStr(row, s) -int row; char *s; -{ - KsPosCursor(row, (KsGetCols() - strlen(s)) / 2); - KsPutStr(s); -} - /** * @fn void KsPutRawCh(int ch) * @brief Send a character to the TTY. @@ -364,6 +569,38 @@ xKsConOut jp 0 ; BIOS ConOut #endasm +// void xKsNames(void) : Set TTY names. +xKsNames() +{ + xks_names[KS_VT52] = "VT52"; + xks_names[KS_VT100] = "VT100"; + xks_names[KS_PCW] = "PCW"; + xks_names[KS_CPC] = "CPC"; + xks_names[KS_SPECTRUM] = "SPECTRUM"; + xks_names[KS_KAYPRO] = "KAYPRO"; + xks_names[KS_VT100COL] = "VT100COL"; +} + +// void xKsInit24x80(void) : Set TTY to 24 rows and 80 columns. +xKsInit24x80() +{ + xks_rows = 24; + xks_cols = 80; +} + +// void xKsInitAmstrad(void) : Set generic Amstrad mode. +xKsInitAmstrad() +{ + xks_clrscr = "\eH\eE"; + xks_poscur = "A\eY%r%c"; + xks_shwcur = "\ee"; + xks_hidcur = "\ef"; + xks_yrever = "\ep"; + xks_nrever = "\eq"; + xks_yuline = "\er"; + xks_nuline = "\eu"; +} + // void xKsPutDec(int num) : Send positive decimal number to TTY. xKsPutDec(num) int num;