SEDORIC in C

Since we do not have native C compilers on the Oric, this forum will be mostly be used by people using CC65 or the OSDK. But any general C related post will be welcome !
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: SEDORIC in C

Post by xahmol »

Thanks. And I do certainly did not want to disregard the tremendous effort done by all contributors that is now OSDK. So certainly not intended as bashing that work. Just that I like to make a choice before I am invested with a codebase in a tool.
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: SEDORIC in C

Post by xahmol »

Did some testing in CC65 with my WIP code. Code is indeed almost half the size, but do encounter some issues:
- Regardless if I use cprintf or sprintf, printing a "%c",colorattribute works for all colors, but not for black. Is there any logic there, especially as exactly the same code is working in OSDK with sprintf? Even textcolor(0) does not seem to do anything (other colors do).
- The .tap output of CC65 is working great in Oricutron (apart from the black ink being completely ignored). Converting the TAP with OSDK TAP2DSK though to .dsk gives a .bas file on the disk instead of a .com that results if I compile via OSDK. But more importantly, it completely fails on run.

Anybody recognising these issues and having a solution? Something I am doing stupid?
Otherwise I will stick to OSDK, as that code may be bigger but works.....

EDIT: The second issue I found already answered on this forum (by Iss again): https://forum.defence-force.org/viewtop ... 553#p18553
That has succesfully solved that second issue.
Leaves the black ink by printing "%c",0 being completely ignored in CC65, while printing "%c",attributevalue in any other text and background color (including black as background color) works.
User avatar
jbperin
Flight Lieutenant
Posts: 480
Joined: Wed Nov 06, 2019 11:00 am
Location: Valence, France

Re: SEDORIC in C

Post by jbperin »

I don't know if it is linked to the problem you're encountering but you have to know that, in C language, the value 0 in a character string means "end of string". And the value of attribute "Change INK to BLACK" is zero.
The zero value is used by the printf family function to detect the end of a string.

It is hard to be sure that it is the problem in your case without seeing the code.

If you want to write the value 0 at coordinate (line, column) on the LORES screen, you can use something like:

Code: Select all

poke ($BB80 + 40*line + column, 0);
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: SEDORIC in C

Post by xahmol »

jbperin wrote: Sun Jan 31, 2021 3:58 am The zero value is used by the printf family function to detect the end of a string.
Makes sense and was thinking of that myself. But then why does it work in OSDK? Has OSDK adapted the sprintf() implementation?

Code snippet example of what I use:

Code: Select all

 void menuplacebar()
{
    char* screen = (char*)0xbba8;
    char x;

    sprintf(screen,"%c%c", A_FWBLACK, A_BGGREEN);
    screen+=2;
    for(x=0;x<menubaroptions;x++)
    {
        sprintf(screen,"%s ",menubartitles[x]);
        screen+=strlen(menubartitles[x])+1;
    }
}
And this works on OSDK, on CC65 it works but the A_FWBLACK (which has the value zero) is ignored.
jbperin wrote: Sun Jan 31, 2021 3:58 am If you want to write the value 0 at coordinate (line, column) on the LORES screen, you can use something like:

Code: Select all

poke ($BB80 + 40*line + column, 0);
I know. But was hoping not to have to do that as I wanted to change from sprintf to cprintf and use gotyxy() instead of the screen addresss pointer. That would make the code somewhat more portable. But in that case, changing ink to black midway a print string needs calculating the coordinates instead of cprintf just printing in the next position after where the last cprintf left it.
But will do if it is really the only way.
User avatar
ibisum
Wing Commander
Posts: 1643
Joined: Fri Apr 03, 2009 8:56 am
Location: Vienna, Austria
Contact:

Re: SEDORIC in C

Post by ibisum »

sprintf stops its loop on a NULL char?
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: SEDORIC in C

Post by xahmol »

ibisum wrote: Sun Jan 31, 2021 11:36 am sprintf stops its loop on a NULL char?
In CC65 is does not stop, the rest after it is printed correctly. It is just being ignored.
In LCC65 in OSDK it works fine.

Another snippet from my code:

Code: Select all

 screen = screenpos(xpos+2,ypos+menuchoice);
        sprintf(screen,"%c%c%s%c%c%c",
            A_BGYELLOW,A_FWBLACK,
            pulldownmenutitles[menunumber-1][menuchoice-1],
            A_FWRED,91,A_BGBLACK);
Everything prints OK in CC65 but just the black ink attribute is ignored (the 91 character by the way is the right menu border character in my custom charset).
User avatar
iss
Wing Commander
Posts: 1637
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: SEDORIC in C

Post by iss »

Yes, I think too this is a BUG in CC65's sprintf implementation.

Code:

Code: Select all

static char* colors[] = {
  "BLACK  ",
  "RED    ",
  "GREEN  ",
  "YELLOW ",
  "BLUE   ",
  "MAGENTA",
  "CYAN   ",
  "WHITE  "
};
void main(void)
{
  char i;
  text();
  cls();

#ifdef __CC65__
  sprintf((void*)(0xbb80),"   CC65");
#else
  sprintf((void*)(0xbb80),"   LCC65");
#endif

  for(i=0; i<8; i++)
    sprintf((void*)(0xbb80+40*(i+2)),"%c%c %s on %s",i+16,7-i,colors[7-i],colors[i]);
}
Result:
cc65-lcc65.png
And indeed, the '0' char is simply skipped - after manual POKE the text is revealed as shifted 1 char on the left:
cc65.png
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: SEDORIC in C

Post by xahmol »

Well, the good thing is that at least it is not me doing something stupid then....
Will go for the poke workaround for now then. Do not know if I have the stomach to do a formal bug request to whoever is maintaining the Oric libs for CC65.
Is by the way not only sprintf, have exactly the same in cprintf (but assume both are using the same printf as basis),
User avatar
iss
Wing Commander
Posts: 1637
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: SEDORIC in C

Post by iss »

xahmol wrote: Sun Jan 31, 2021 2:42 pm Is by the way not only sprintf, have exactly the same in cprintf (but assume both are using the same printf as basis),
Exactly! The format string is held in one buffer, other following parameters are processed in second buffer which is 'printf'-ted out assuming that buffer contains a C string - and here is the bug - the '0' char stops the printing.

BTW, using 'sprintf' directly to screen has another side effect too: the terminating 0 is printed too, so any text which is already on the screen line will have INK0.

IMO, reporting the bug is very good idea, the guys at https://github.com/cc65/cc65 do great work and are very active in bug-fixing!
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: SEDORIC in C

Post by xahmol »

iss wrote: Sun Jan 31, 2021 3:09 pm BTW, using 'sprintf' directly to screen has another side effect too: the terminating 0 is printed too, so any text which is already on the screen line will have INK0.
Oh, great. Now notice that as well. Did not even see that yet as I was debugging the first problem. But that trailing 0 being printed to is really annoying as that is not something that can easily be worked around by a poke or such as it screws the already existing screen info.
So basically the sprintf function for the Oric in CC65 ignores 0s that should be printed, but prints zero's that should not be printed? Great.

Altough if I think of it, the trailing 0 being copied actually sounds like intended behaviour as sprintf normally is used to print to strings, right? Then including the trailing 0 makes sense. And it is actually weird that LCC65 does not do it in sprintf.

That means I probably should use cprintf instead of sprintf in CC65, but that makes the need to POKE black ink really cumbersome.

Illustration of what happens after I fixed printing the black ink with a poke, see the screenshot: in the window on the right side the extra 0 being printed not only removes the right border of the frame, but for the lines where I had to do multiple sprintfs because I had to split for the black ink poke midway, even two trailing zeros are printed that were not intented and therefore also spills over to the next line and screws up by overwriting the AltCharSet attribute there (and yes, the code was correctly woring in LCC65).
Schermafbeelding 2021-02-01 093225.png
Expected output as result using LCC65:
Schermafbeelding 2021-02-01 094240.png
Schermafbeelding 2021-02-01 094240.png (11.43 KiB) Viewed 4621 times
Will go for a bug report then if time permits on the black ink being ignored.

Thanks for the help.
User avatar
ibisum
Wing Commander
Posts: 1643
Joined: Fri Apr 03, 2009 8:56 am
Location: Vienna, Austria
Contact:

Re: SEDORIC in C

Post by ibisum »

That means I probably should use cprintf instead of sprintf in CC65, but that makes the need to POKE black ink really cumbersome.

This is Oric life. Attributes and strings need to be managed independently. (Edit: I concur that the printf()'s and co., seem to be righteously borked for Oric.. imho, NULL should mean return-from-output, 00 isn't printable ... but maybe there is a %format char that could be used to place a BYTE value, hmm..)
Last edited by ibisum on Mon Feb 01, 2021 1:12 pm, edited 1 time in total.
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: SEDORIC in C

Post by xahmol »

Update: have the CC65 code now working correctly with cprintf() and a poke() where needed. So can confirm that as expected I do not have the trailing zero printed issue using cprintf(). Using of course the conio.h lib for cprintf() and gotoxy().

Now get code like this:

Code: Select all

    for(x=0;x<pulldownmenuoptions[menunumber-1];x++)
    {
        gotoxy(xpos,ypos+x+2);
        cprintf("%c%c%c", A_FWRED,91, A_BGCYAN);
        poke(screenpos(xpos+3,ypos+x+2),A_FWBLACK);
        gotoxy(xpos+4,ypos+x+2);
        cprintf("%s%c%c%c",pulldownmenutitles[menunumber-1][x],A_FWRED,91,A_BGBLACK);
    }
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: SEDORIC in C

Post by xahmol »

Duh, completely overlooked the cputc() and cputcxy() commands of conio.h.
That command does print the zero attribute, and of course is much easier to use, more elegant and more portable than POKEing around. Especially as it keeps track of the cursorposition.

So updated example as above:

Code: Select all

for(x=0;x<pulldownmenuoptions[menunumber-1];x++)
    {
        gotoxy(xpos,ypos+x+2);
        cprintf("%c%c%c", A_FWRED,C_RIGHTLINE, A_BGCYAN);
        cputc(A_FWBLACK);
        cprintf("%s%c%c%c",            
            pulldownmenutitles[menunumber-1][x],A_FWRED,C_RIGHTLINE,A_BGBLACK);
    }
Post Reply