+zx screen printing

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
efa
New member
Posts: 1
Joined: Tue Jan 16, 2024 6:54 pm

+zx screen printing

Post by efa »

I want to use the <graphics.h> primitive (and work well), together printf() cursor positioning via VT/ESC codes (possibly with 64 colums), targeting ZX Spectrum. I tryed with this:

Code: Select all

// build with: $ zcc +zx -startup=5 -lndos -clib=ansi -pragma-define:ansicolumns=64
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
void main() {
	printf("line0\n");
	printf("\x1B\x41"); // ESC A
	printf("line1\n");
	printf("\x1B\x45"); // ESC E
	printf("line2\n");
	printf("\x1B\x59\x29\x29"); // ESC Y r c
	printf("line3\n");
	printf("\x16,\x29,\x29"); // ZX Control codes: Move to position y,x
	printf("line4\n");   
	while(1);
}
but no sequence do what is documented for classic lib
Any hint please?
Last edited by efa on Tue Jan 16, 2024 7:07 pm, edited 1 time in total.
User avatar
dom
Well known member
Posts: 2214
Joined: Sun Jul 15, 2007 10:01 pm

Re: +zx screen printing

Post by dom »

[I've split this off since this from the previous topic since this about +zx rather than +zx81]

It looks like you're using VT52 escape sequences but compiling using the VT100 driver. If you compile with: zcc +zx [file.c] -lndos and make one small change indicated below (removing the commas) it will work as you expect. That is you'll end up with "line 2" at (0,0) and "line 4" at (7,7)

Code: Select all

	printf("\x16\x29\x29"); // ZX Control codes: Move to position y,x
Zetr0
Member
Posts: 63
Joined: Mon Aug 22, 2011 12:38 pm

Re: +zx screen printing

Post by Zetr0 »

@efa

Hello there fellow z88dk'er!

I see you are tackling a problem that I had long ago, so let me share my solutions to help =)

Some initial setup -

Code: Select all

#include <stdio.h>

// Pre-processor

typedef unsigned char ubyte;
typedef unsigned int uword;

#define print_mode      32 // set 32 for 64 character or 0 for default text mode
The above "print_mode"is used as either "32" or "0" depending on my compilation target as I had older code that didn't use 64 column output. however I included it later as a legacy for said code - this could just be rolled into the printf setup -

Code: Select all

// printf control characters
#define zxp_at          22
#define zxp_paper       17
#define zxp_ink         16
#define zxp_bright      19
#define zxp_flash       18
#define zxp_over        21       
#define zxp_inverse     20
#define zxp_tab         23

// zx spectrum attribute enum colours ( zx spectrum attribute organized )
#define _black          0           
#define _blue           1           
#define _red            2           
#define _magenta        3           
#define _green          4           
#define _cyan           5           
#define _yellow         6          
#define _white          7       

#define _bright         1
#define _flash          1
Thats all the zx spectrum stuff no we need to look at how the "printf" handles colour, again these are mention in the docs and graphics.h, this code doesn't use "graphics.h" as I wanted a small compilation. lol not sure how thats turned out these days, but its what I went with ;) =)

Code: Select all

// z88dk printf driver enum colour calls 
#define BLACK           0           // zx spectrum colour 0
#define BLUE            1           // zx spectrum colour 1 
#define RED             4           // zx spectrum colour 2 
#define MAGENTA         5           // zx spectrum colour 3 
#define GREEN           2           // zx spectrum colour 4
#define CYAN            3           // zx spectrum colour 5
#define YELLOW          14          // zx spectrum colour 6
#define WHITE           7           // zx spectrum colour 7
As you can see the vaules for the colour displayed is different to the humble zx - this is because the "printf" driver / function is many things for many targets.

to offset this with my older code and to help my aged brain to swim more in with the zx-spectrum-ny-ness I put the following enum conversion. again this is more for my own code but it will *i hope* give you insight into "printf" under z88dk

Code: Select all

// Global Vectors
ubyte zx_colour[8];

// Debug Functions
void init_zxcolours( void );                        // initialize enum vector of zx spectrum colours 0-7                       
void init_zxcolours( void )                         // for use with the printf driver.
{ /* zx spectrum colour pallet */  
    zx_colour[ 0 ] = BLACK;    //   0       zx_colour[ _black ];
    zx_colour[ 1 ] = BLUE;     //   1       zx_colour[ _blue ];
    zx_colour[ 2 ] = RED;      //   4       zx_colour[ _red ];
    zx_colour[ 3 ] = MAGENTA;  //   5       zx_colour[ _magenta ];
    zx_colour[ 4 ] = GREEN;    //   2       zx_colour[ _green ];
    zx_colour[ 5 ] = CYAN;     //   3       zx_colour[ _cyan ];
    zx_colour[ 6 ] = YELLOW;   //  14       zx_colour[ _yellow ];
    zx_colour[ 7 ] = WHITE;    //   7       zx_colour[ _white ];
}
so I can use zx_colour[ 0-7 ]; with "printf" to ensure I get the correct colour, again this is mainly for my old code and

so lets talk about printing it all out - the following is a function I often use when debugging code as its relatively quick to write for example -

zxprintf"Hello World", 10,5, zx_colours[ _black ], zx_colours[ _cyan ], bright. 0, 0 );

The above prints on the spectrum console at cell 10, row 5, "Hello World", in black ink and Cyan Paper

Code: Select all

void zxprintf( char *str, char x, char y, char ink, char paper, char bright, char flash, char over );
void zxprintf( char *str, char x, char y, char ink, char paper, char bright, char flash, char over )
{
/*       *NB 
         in 64 column mode the printf driver requires an offset value of 32 added to the 
         coords of x and y sent to the function when using 64column mode.
*/
    x = x + print_mode;
    y = y + print_mode;

    printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%s", zxp_at,
                                           y,
                                           x,
                                           zxp_paper,
                                           paper,
                                           zxp_ink,
                                           ink,
                                           zxp_bright,
                                           bright,
                                           zxp_flash,
                                           flash,
                                           zxp_over,
                                           over,
                                           str); 
}
Alternatively I often use this function in conjunction with "sprintf" for example

Code: Select all

sprintf( str,"Testing loop Level = %d", loop_index );
zxprintf( str, 5,2, YELLOW, BLACK, 1, 0, 0 );
As you may notice I used the direct colour codes defined earlier and sent string to the function, and instead of using "_bright" or "_flash" etc. I just used "1" for on and "0" for off.

There is a lot of weight and legacy in these functions but my hope is that it makes the printf driver a bit easier to grasp under 64 column mode.

hopefully you find these functions useful in your research, i look forward to seeing what mischief you get upto =)

Z.
Post Reply