Simple print string at screen location?
-
- Member
- Posts: 121
- Joined: Mon Mar 26, 2018 1:49 pm
Simple print string at screen location?
I need to print a simple string, at a given screen location (char cells, no need for pixel precision). I don't need colours and I certainly don't need stdio features. The ROM character set would do, although my own would be nicer. 48K only, and using the ROM would be fine.
Do we have a way to do that? SDCC and newlib ideally, I can probably port something from classic if I need to.
Do we have a way to do that? SDCC and newlib ideally, I can probably port something from classic if I need to.
Re: Simple print string at screen location?
According to the info at https://github.com/z88dk/z88dk/wiki/Pla ... X-Spectrum you can use the spectrum's own 'print char' routine (rst 16) to print a sting, using this command line option:
The cursor location where printing occurs can be changed by printing cursor control characters first (https://github.com/z88dk/z88dk/wiki/Pla ... ole-driver). These special characters don't appear on the screen but instead control the console.
Then you can use fputs("your string here", stdout) to print your string. If you want to go more low level you can call fputc_cons in a loop, something like this:
fputc_cons is a z88dk specific function that always prints to the console, however that's done for the platform you're compiling for.
Code: Select all
-pragma-redirect:fputc_cons=fputc_cons_rom_rst
Then you can use fputs("your string here", stdout) to print your string. If you want to go more low level you can call fputc_cons in a loop, something like this:
Code: Select all
char* str = "your string";
int i =0, j = strlen(str);
for(; i< j; i++){
fputc_cons(str[i]);
}
Re: Simple print string at screen location?
Forgot to mention, I think the 'move the cursor' control character is 0x16.
Re: Simple print string at screen location?
I remember when I was writing a demo game in z88dk and I couldn't find a function for it, so I wrote a quick and dirty one in assembly.
https://worldofspectrum.org/forums/disc ... ent_970049
(For 1 character only, but there's a string version that used this function a few posts under it.)
Yes, it's a bit strange that z88dk do offer the address calculation functions but there was no print function to use them.
https://worldofspectrum.org/forums/disc ... ent_970049
(For 1 character only, but there's a string version that used this function a few posts under it.)
Yes, it's a bit strange that z88dk do offer the address calculation functions but there was no print function to use them.
Re: Simple print string at screen location?
That does seems strange. I guess there must be some reason for their existence.
I thought maybe as the default fputc_cons on the zx spectrum target does write to screen memory directly (https://github.com/z88dk/z88dk/blob/mas ... c_cons.asm) maybe these functions would've been used internally by it. However, that function contains it's own separate means of calculating the memory address of the screen to use (calc_screen_address).
I thought maybe as the default fputc_cons on the zx spectrum target does write to screen memory directly (https://github.com/z88dk/z88dk/blob/mas ... c_cons.asm) maybe these functions would've been used internally by it. However, that function contains it's own separate means of calculating the memory address of the screen to use (calc_screen_address).
-
- Member
- Posts: 121
- Joined: Mon Mar 26, 2018 1:49 pm
Re: Simple print string at screen location?
Thanks guys. The fputc thing appears to be classic lib? fputs works on newlib but requires stdio. I think, anyway. It all gets a bit confusing when you start digging down.
A 'C' version of Timmy's "poke the char bytes into the screen" code is as much as I need, so I'll probably go with that. Or maybe a quick interface to the RST16 routine. I was more concerned that there was a simple function in the newlib which I was missing. Seems there isn't!
A 'C' version of Timmy's "poke the char bytes into the screen" code is as much as I need, so I'll probably go with that. Or maybe a quick interface to the RST16 routine. I was more concerned that there was a simple function in the newlib which I was missing. Seems there isn't!
Re: Simple print string at screen location?
Fair enough. Glad you've got what you need
Re: Simple print string at screen location?
If you use e.g. the direct fputc_cons(c) call, it could require declaring 'stdio' or similar. BTW it does not mean that the whole STDIO related functions will be linked in !
-
- Member
- Posts: 121
- Joined: Mon Mar 26, 2018 1:49 pm
Re: Simple print string at screen location?
What would be linked in?
That function/macro doesn't seem to appear in the newlib headers. Does it work in a way I don't understand, or is it classic only?
Re: Simple print string at screen location?
I thought I'd written something on this thread but it appears not.
newlib does have a rst16 driver, but it's hidden behind layers of stdio so isn't user accessible.
classic has the conio layer (of which fputc_cons is one piece) which allows driving of the screen without all the (usual unnecessary) gunk of stdio
To add to the fun/confusion, sp1 (which is in both classic and newlib) has its own set of functions to write to the screen.
newlib does have a rst16 driver, but it's hidden behind layers of stdio so isn't user accessible.
classic has the conio layer (of which fputc_cons is one piece) which allows driving of the screen without all the (usual unnecessary) gunk of stdio
To add to the fun/confusion, sp1 (which is in both classic and newlib) has its own set of functions to write to the screen.
Re: Simple print string at screen location?
My personal view is that if a minimal output binary size is desired, using the classic lib and the rst16 version of fputc_cons would be the way to go. Any rst16 'hand- rolled' wrapper of would still need to do the same things anyhow. Using the classic lib, functions are only pulled into the output binary if they are used. This can be confirmed by generating a .map file at compile time and inspecting its contents to see the symbols that were used.
Of course, folks can do whatever they want right? There's many different options available.
Of course, folks can do whatever they want right? There's many different options available.
-
- Member
- Posts: 121
- Joined: Mon Mar 26, 2018 1:49 pm
Re: Simple print string at screen location?
Yes, but I settled on zsdcc and newlib several years ago and all my games and tutorials are based on that combination. It is a bit frustrating when I come across something simple which is in the other part of z88dk but which I can't use!
Re: Simple print string at screen location?
That's fine too of course. Stick with what you prefer.
@dom, I wonder whether fputc_cons, fgetc_cons and getk could be made available when using newlib? Or are they already available somehow?
@dom, I wonder whether fputc_cons, fgetc_cons and getk could be made available when using newlib? Or are they already available somehow?
Re: Simple print string at screen location?
Hi,
Sorry for grave digging, but I wrote a drag and drop routine for this, just copy this in to your code and write: 'printc(10,10,"hello");
That simple, hope it helps:
int * getASCIIValue(char *array) {
int i, ascii;
int result[100];
for(i=0; array; i++) {
ascii = (int)array;
result = ascii;
}
return result;
}
void printc(unsigned char x, unsigned char y, char text[])
{
int *arr = getASCIIValue(text);
unsigned char *p, *dat;
unsigned char i;
unsigned char jj;
for(jj=0; text[jj]; jj++) {
dat = 15360 + arr[jj]*8; // points into the rom character set
p = zx_cxy2saddr(x, y);
for (i = 0; i < 8; ++i)
{
*p = *dat++;
p += 256;
}
x++;
}}
Sorry for grave digging, but I wrote a drag and drop routine for this, just copy this in to your code and write: 'printc(10,10,"hello");
That simple, hope it helps:
int * getASCIIValue(char *array) {
int i, ascii;
int result[100];
for(i=0; array; i++) {
ascii = (int)array;
result = ascii;
}
return result;
}
void printc(unsigned char x, unsigned char y, char text[])
{
int *arr = getASCIIValue(text);
unsigned char *p, *dat;
unsigned char i;
unsigned char jj;
for(jj=0; text[jj]; jj++) {
dat = 15360 + arr[jj]*8; // points into the rom character set
p = zx_cxy2saddr(x, y);
for (i = 0; i < 8; ++i)
{
*p = *dat++;
p += 256;
}
x++;
}}
Re: Simple print string at screen location?
I can't edit posts but note that the 'result[100]' will need to be increased to suit if you're printing a screen of text, ie result[200] or more.
Also you might think you can optimise this to be a little more simple, not including the result array at all, but the compiler did some weird things when you don't copy it to another array, it would 'remember' the previous text and sometimes overflow. Maybe a typo by me, or my C knowledge is lacking. The above fixed it, and I've left it alone because it works 100%.
Also you might think you can optimise this to be a little more simple, not including the result array at all, but the compiler did some weird things when you don't copy it to another array, it would 'remember' the previous text and sometimes overflow. Maybe a typo by me, or my C knowledge is lacking. The above fixed it, and I've left it alone because it works 100%.