Files
cc65/targettest/conio.c
Colin Leroy-Mira 816666615b Apple2: Make 80-columns support dynamic on apple2 target
Add a machinetype identifier to help us quickly identify
Apple //e (bit 7) and //e enhanced (bit 6).

Use it in conio functions for 80-columns code instead of
relying entirely on the __APPLE2ENH__ target.

Move videomode() to the apple2 target, and have it return
an error if 80-columns hardware is not available - this
is a lie for now, it is considered available on //e enhanced,
which may not be true, and not available on //e, which
may also be not true. An ulterior patch will make that
check correctly.

Adapt the box/line drawing characters so that one can use
MouseText on the apple2 target if it is available, by
defining DYN_DRAW_BOX. No change by default: MouseText is
considered available on apple2enh and not available on
apple2.
2025-05-27 19:03:20 +02:00

312 lines
8.2 KiB
C

/*
* conio API test program
*
* keys:
*
* 1...0 change text color
* F5/F6 change border color
* F7/F8 change background color
*
*/
/* Box drawing characters are usually constant expressions. However, there
* are scenarios where this is not the case. To ensure compatibility with
* code that assumes they are constant expressions, the scenarios in question
* must be explicitly enabled by defining DYN_BOX_DRAW. Currently, the only
* such scenario is the apple2 target. There, DYN_BOX_DRAW can be used to
* enable the use of MouseText characters on exactly those machines that
* support them.
*/
#define DYN_BOX_DRAW
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <joystick.h>
#if defined(__GAMATE__) || defined(__OSIC1P__)
/* there is not enough screen space to show all 256 characters at the bottom */
#define NUMCHARS 128
#else
#define NUMCHARS 256
#endif
#if defined(__GAMATE__)
#define NUMCOLS 4
#else
#define NUMCOLS 16
#endif
#if defined(__ATMOS__)
// FIXME: those should be defined elsewhere?
#define CH_HLINE '-'
#define CH_VLINE '!'
#endif
#if defined(DYN_BOX_DRAW)
static char grid[5][5];
#else
static char grid[5][5] = {
{CH_ULCORNER, CH_HLINE, CH_TTEE, CH_HLINE, CH_URCORNER},
{CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE },
{CH_LTEE, CH_HLINE, CH_CROSS, CH_HLINE, CH_RTEE },
{CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE },
{CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER}
};
#endif
#if defined(DYN_BOX_DRAW)
static void init_grid(void)
{
/* Programmatically fill the array with extern chars
* instead of constants. */
grid[0][0] = CH_ULCORNER;
grid[2][0] = CH_LTEE;
grid[4][0] = CH_LLCORNER;
grid[0][2] = CH_TTEE;
grid[2][2] = CH_CROSS;
grid[4][2] = CH_BTEE;
grid[0][4] = CH_URCORNER;
grid[2][4] = CH_RTEE;
grid[4][4] = CH_LRCORNER;
grid[1][1] = grid[1][3] =
grid[3][1] = grid[3][3] = ' ';
grid[1][0] = grid[1][2] = grid[1][4] =
grid[3][0] = grid[3][2] = grid[3][4] = CH_VLINE;
grid[0][1] = grid[0][3] =
grid[2][1] = grid[2][3] =
grid[4][1] = grid[4][3] = CH_HLINE;
}
#endif
#define LINE_COLORTEST 3
#define LINE_PEEKTEST 11
void colortest(void)
{
unsigned int i, j;
cputsxy(0, 2, "Colors:" );
for (i = 0; i < 3; ++i) {
gotoxy(i, LINE_COLORTEST + i);
for (j = 0; j < NUMCOLS; ++j) {
(void)textcolor(j);
cputc('X');
}
}
}
void peektest(void)
{
int j;
char buf[NUMCOLS];
char cbuf[NUMCOLS];
char rbuf[NUMCOLS];
gotoxy(0, LINE_PEEKTEST);
for (j = 0; j < NUMCOLS; ++j) {
(void)textcolor(j);
revers((j >> 1)&1);
cputc('a' + j);
buf[j] ='#';
cbuf[j] = 1;
rbuf[j] = 0;
}
for (j = 0; j < NUMCOLS; ++j) {
gotoxy(j, LINE_PEEKTEST);
// TODO: cpeekc() implementation missing for those:
#if !defined(__TELESTRAT__)
buf[j] = cpeekc();
#endif
// TODO: cpeekcolor() implementation missing for those:
#if !defined(__TELESTRAT__)
cbuf[j] = cpeekcolor();
#endif
// TODO: cpeekrevers() implementation missing for those:
#if !defined(__TELESTRAT__)
rbuf[j] = cpeekrevers();
#endif
}
gotoxy(0, (LINE_PEEKTEST+1));
for (j = 0; j < NUMCOLS; ++j) {
(void)textcolor(cbuf[j]);
revers(rbuf[j]);
cputc(buf[j]);
}
// TODO: cpeeks() implementation missing for those:
#if !defined(__APPLE2__) && \
!defined(__APPLE2ENH__) && \
!defined(__ATARI__) && \
!defined(__CX16__) && \
!defined(__NES__) && \
!defined(__TELESTRAT__) && \
!defined(__OSIC1P__)
gotoxy(0, LINE_PEEKTEST);
cpeeks(buf, NUMCOLS);
(void)textcolor(1);
revers(0);
gotoxy(20, LINE_PEEKTEST);
for (j = 0; j < NUMCOLS; ++j) {
cputc(buf[j]);
}
#endif
}
void allchars(int xsize, int ysize)
{
int i;
gotoxy(0, ysize - 2 - ((NUMCHARS + (xsize-1)) / xsize));
// one line with 0123..pattern
revers(1);
for (i = 0; i < xsize; ++i) {
cputc('0' + i % 10);
}
revers(0);
for (i = 0; i < NUMCHARS; ++i) {
if ((i != '\n') && (i != '\r')) {
cputc(i);
} else {
cputc(' ');
}
}
// fill last line of the block with '#'
while(wherex() > 0) {
cputc('#');
}
// one more line with 0123..pattern
revers(1);
for (i = 0; i < xsize; ++i) {
cputc('0' + i % 10);
}
revers(0);
}
void main(void)
{
unsigned int i, j, n;
unsigned char xsize, ysize, tcol, bgcol, bcol, inpos = 0;
#if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__)
unsigned char joy;
joy_install(joy_static_stddrv);
#endif
#if defined(DYN_BOX_DRAW)
init_grid();
#endif
clrscr();
screensize(&xsize, &ysize);
cputs("cc65 conio test\n\r");
cputs("Input:[ ]"); /* 8 spaces */
tcol = textcolor(0); /* memorize original textcolor */
bgcol = bgcolor(0); /* memorize original background color */
bcol = bordercolor(0); /* memorize original border color */
(void)bordercolor(bcol);
(void)bgcolor(bgcol);
colortest();
peektest();
(void)textcolor(tcol);
revers(0);
gotoxy(4,5);
cprintf("\n\n\r Screensize: %ux%u", xsize, ysize);
chlinexy(0, 6, xsize);
cvlinexy(0, 6, 3);
chlinexy(0, 8, xsize);
cvlinexy(xsize - 1, 6, 3);
cputcxy(0, 6, CH_ULCORNER);
cputcxy(xsize - 1, 6, CH_URCORNER);
cputcxy(0, 8, CH_LLCORNER);
cputcxy(xsize - 1, 8, CH_LRCORNER);
for (i = 0; i < 5; ++i) {
gotoxy(xsize - 5, i);
for (j = 0; j < 5; ++j) {
cputc(grid[i][j]);
}
}
allchars(xsize, ysize);
cursor(1);
for (;;) {
/* do the "rvs" blinking */
i = textcolor(COLOR_BLACK);
gotoxy(8, 2);
j = (++n / 16) & 1;
revers(j);
cputc(j ? 'R' : ' ');
revers(j ^ 1);
cputs(" rvs");
revers(0);
(void)textcolor(i);
gotoxy(7 + inpos, 1);
#if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__)
/* not all targets have waitvsync */
waitvsync();
/* for targets that do not have a keyboard, read the first
joystick */
joy = joy_read(JOY_1);
cprintf("%02x", joy);
#else
i = cgetc();
switch (i) {
case CH_ENTER:
clrscr();
return;
#ifdef CH_CURS_LEFT
case CH_CURS_LEFT:
inpos = (inpos - 1) % 8;
break;
#endif
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
(void)textcolor(i - '0');
break;
#ifdef CH_F5
case CH_F5:
bcol = (bcol + 1) & 0x0f;
(void)bordercolor(bcol);
break;
#endif
#ifdef CH_F6
case CH_F6:
bcol = (bcol - 1) & 0x0f;
(void)bordercolor(bcol);
break;
#endif
#ifdef CH_F7
case CH_F7:
bgcol = (bgcol + 1) & 0x0f;
(void)bgcolor(bgcol);
break;
#endif
#ifdef CH_F8
case CH_F8:
bgcol = (bgcol - 1) & 0x0f;
(void)bgcolor(bgcol);
break;
#endif
default:
cputc(i);
/* fallthrough */
#ifdef CH_CURS_RIGHT
case CH_CURS_RIGHT:
#endif
inpos = (inpos + 1) % 8;
}
#endif
}
}