beginners question

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

beginners question

Post by cborn »

Hello,
i get an error message but i dont know why

~/Desktop/try-C/c_in_zx/farkle$ zcc +zx -vn dice_096c.c -o dice096c -lndos -create-app -zorg=32768
dice_096c.c:146:9: warning: Implicit definition of function 'memset' it will return an int. Prototype it explicitly if this is not what you want. [-Wimplicit-function-definition]
dice_096c.c:172:7: fatal error: Must be lvalue
Compilation aborted

Its becouse of the sort routine.
But it worked without any error when it was inside main().
Now i have separated it as a routine it suddenly insist on a 'lvalue' which was NOT any problem before.
Its a character array to be sorted with a very simple exchange sort.
I can replace it with other sortings i found, but those are INT based and this one is CHAR based .
https://www.tutorialride.com/c-programm ... amming.htm

in asm you just putin that value, but c insist on so much different ways of doing the same....
eg using %d or %c changes the BEHAVIOR of the scanf routine, i mean the BEHAVIOR of the routine is changed by using an INT or an CHAR
thats very anoying ...
what do i have to do extra to explain to C what i want ???

Code: Select all


 /* C source start */
 /* by chris born ad 2020 as homework for z88dk, farkle */

 /* classic (not needed but BUILD_SDCC=0 or BUILD_SDCC=undefined) */
 /* zcc +zx -vn  dice_096c.c -o dice096c -lndos -create-app -zorg=32768 */

 #include <spectrum.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <input.h>

void  rndseed()  // not realy very random, still needs better one
        {
      #asm              // uses HL, A, B register
         di             //  4t
         ld hl,23672    // 10t  raises only once in 69288 tstate with 1 per frame

         ld a,r         //  9t  raises every ~4~24 tstate with 1 or maybe 2 per instruction , inner LDR , LDI instructions counted.
         bit 0,a        //  8t
         jp z,r1        // 10t  z=0=even

         cpl            //|  4t the value of 'r' now decreases instead of raising
         jp n1          //| 10t  odd is now even  0xff=0x00
r1:
         inc a          //~  4t  raise and  even is now odd  0x00=0x01
         jp n1          //~ 10t  jp=only for timing sake here, DELAY

n1:
         xor (hl)       //  7t xor on FRAMES value

         ld b,a         //  4t
         inc hl         //  7t raise once per 256 FRAMES of 69288 = after ~5.5 seconds

         ld a,r         //  9t
         bit 0,a        //  8t
         jp z,r2        // 10t  z=0=even

         rlca           //|  4t
         jp n2          //| 10t
r2:
         rrca           //~  4t
         jp n2          //~ 10t
n2:
         xor (hl)       //  7t

         ld h,b         //  4t
         ld l,a         //  4t

         ld (23670),hl  //  15t write new seed

         ei             //   4t
         ret            //  10t  
      #endasm           // always(*) equal timing = 4+10+9+8+10 +4+10  +7+4+7+9+8+10 +4+10 +7+4+4   +15+4+10 =158 tstate
        }               // (*) in NON contended memory

//----------------------------------

void setrand()
        {
        rndseed() ;
        char* sd = 23670 ;
        srand(*sd) ; 
        }

//----------------------------------

int dice(int aods)      // aods  = amount of dice sides
        {
//        randomize() ;
        char d = rand()%aods +1 ;
        return d ;
        }

//----------------------------------

void sortit(char h[] , int hod)
{
    char t  ;
    int x ;

sorting:
    t=0 ; // mind chr$0
    for ( x=0 ; x < hod-1 ; x++ )
      {
       if ( h[x] > h[x+1] )
            { 
             t = h[x] ;
             h[x]=h[x+1] ;
             h[x+1]=t ;
            }
       } //endx
    if ( t != 0 ) { goto sorting ; }
 return ;
 }           

//++++++++++++++++++++++++++++++++++

int main()
   {
   unsigned char x , number , hand[256] , hand2[256] , p8 , i8 , select[6][6] ;
   int           hand_of_dice , players , play , round  , key , key2 , k , amount_of_dice_sides , all[256] ;

   setrand() ;
   zx_cls() ;

//   printf("Give number of sides of dice:\n") ;
//   scanf("%d", &amount_of_dice_sides) ;

   amount_of_dice_sides=6 ;

//   printf("how many dice do you want:\n") ;
//   scanf("%d", &hand_of_dice) ;
//   printf(" amount of dice %d ",hand_of_dice );
//   if (hand_of_dice > 255) 
//          {
//          hand_of_dice = 255 ;
//          printf(" is now %d", hand_of_dice) ;
//          }
//   printf("\n") ;

// farkle
   hand_of_dice=6 ;


// https://stackoverflow.com/questions/64331843/in-c-char-foofoo-is-not-allowed-but-why-and-how-to-use-input-as-declaration
// char *hand  = malloc(hand_of_dice * sizeof *hand);
// char *hand2 = malloc(hand_of_dice * sizeof *hand2);
// char *all   = malloc(amount_of_dice_sides * sizeof *all);
//

  printf("Give number of players:") ;
  scanf("%d", &players) ;
  printf("\n\n%d players use %d dice", players, hand_of_dice ) ;
  sleep(3) ;

  round = 1 ;
     char p[]={ 17,' ',16,' ','P','l','a','y','e','r',' ' } ; // 4 spaces reserved for colour info \x10 etc
//     p[0]=17 ; //paper
//     p[2]=16 ; //ink

start:
  zx_cls() ; 
  memset(hand2, '' , amount_of_dice_sides+1 ) ;

  for (play=1 ; play<=players ; play++)
       {
    k=0 ;
    i8= play % 8 ; //integer modulo cuts off rest // just some colour information for ZX
    i8++ ;  // avoid  / 0 null terminator
    p8=55 - 7*(i8 ==7 || i8==8);
  
    p[1]=p8 ; //paper colour
    p[3]=i8 ; // ink colour

    printf("%s%2d : \x10\x10\x11\x37", p , play ) ;

    for ( x=0 ; x<hand_of_dice ; x++ )
          {
          number=dice(amount_of_dice_sides) ;
          hand[x]=number  ;   // only to 255
          hand2[number]++ ;   // only to 255
          all[number]++ ;
          printf("%4d",hand[x]) ;
          }


//sort for easy picking dice for farkle, or do it manualy ??

 hand=sortit( hand , hand_of_dice ) ;

    printf(".") ;
    for ( x=0 ; x < hand_of_dice ; x++ )
               { printf("%4d" , hand[x] ) ; }
    printf("\n") ;

//    while(1)
//          {

rekey:
    key = in_Inkey() ;
    if (key2 == key) {goto rekey ; }
    if (key == 32)
             {
             if ( k == 1) { printf("\n") ; }
             k = 0 ;
             goto next ;
             }
     
    if ( key > 48 && key < hand_of_dice+1+48 && hand[key-49] !='X')
             {
              select[key-49][0]=hand[key-49] ;
              hand[key-49]='X' ;
              printf("d%d=%d | ", key-48, select[key-49][0] ) ;
              k = 1 ;
             }

    key2 = key ;
    goto rekey ;
//    } //end of while

next:

  } //end player
   
  printf("\n statistics 'dicevalue=amount' with %d times %d = %d dice\n", players , hand_of_dice , players* hand_of_dice);
  printf(" last round (%dX%d) :  \n  ",round,players) ;
  for (x=1 ; x<=amount_of_dice_sides ;x++) { printf("%5d |",x) ; }

  printf("\n  ") ;
  for (x=1 ; x<=amount_of_dice_sides ;x++) { printf("%5d |",hand2[x]) ; }

  printf("\n overall results(%d): \n  ",round*players) ;
  for (x=1 ; x<=amount_of_dice_sides ;x++) { printf("%5d |",all[x]) ; }

  printf("\npress key to dice again, '0' will stop") ;
  scanf("%d",&key ) ;
  if (key != 0)
             {
             round++  ;
             goto start ;
             }
  return 0 ;
  } //endmain

 /* C source end */


edit:
i just tried with
#include <string.h>
and now i have solved the other error about memset
~/Desktop/try-C/c_in_zx/farkle$ zcc +zx -vn dice_096e.c -o dice096e -lndos -create-app -zorg=32768
dice_096e.c:173:7: fatal error: Must be lvalue
Compilation aborted
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: beginners question

Post by dom »

The report is off by a couple of lines which is *very* annoying, I'm not sure why it keeps doing that.

Anyway, I'll leave the evidence now and you can join up the dots:

Code: Select all

void sortit(char h[] , int hod)

Code: Select all

  unsigned char x , number , hand[256]

Code: Select all

 hand=sortit( hand , hand_of_dice ) ;
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: beginners question

Post by cborn »

the dots, i hope:
i have to use the full notation,

Code: Select all

 int sortit(unsigned char h[256] , int hod) 
    unsigned char t  ;
    
  hand[256]=sortit( hand[256] , hand_of_dice ) ;
 
It does compile but sortit() now ends in an infinitive loop, so it does not end.
It first did, so i have to look what is more different now.
thank you

Code: Select all

int sortit(unsigned char h[256] , int hod)  // [] or [256] does not differ in error
{
   unsigned char t  ;
    int x ;

sorting:
    t=0 ; // mind chr$0
    for ( x=0 ; x < hod-1 ; x++ )
      {
       if ( h[x] > h[x+1] )
            { 
             t = h[x] ;
             h[x]=h[x+1] ;
             h[x+1]=t ;
    printf(" %d ",t);
            }
       } //endx
    if ( t != 0 ) { goto sorting ; }
 return ;
 }           

About the 2 extra line that are counted, perhaps its a tag like
#!/bin/sh
#
which is counted in or not or some alike???
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: beginners question

Post by dom »

The warning was because you were trying to return an array which isn't supported.

So, if you replace the assignment in this line:

Code: Select all

hand=sortit( hand , hand_of_dice ) ;
[code]

Then it should compile ok - given that you are sorting the hand array is being sorted (you passed a pointer to it into the function), there's no need to assign it.
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: beginners question

Post by cborn »

I am more on "trail on error" then logic but
hand[256]=sortit( hand , hand_of_dice ) ;
now works and there is no infinitive loop.

i have to rechew this a few times
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: beginners question

Post by cborn »

Code: Select all

hand[256]=sortit( hand , hand_of_dice ) ;
itself was part of the mistake
i only need

Code: Select all

sortit( hand , hand_of_dice ) ;
after 'including' the declaration for the LAST chr from hand[256] thing went more wrong
technicly the first line sets the 256st byte to the result of sortit() which has a empty return.
probably thats a zero by which ACCIDENTLY the \0 on hand[256] will be overwritten by another 0 being an \0 end marker as well
the fact that it still worked is becouse nothing was OVER written and the call to sortit still works and thus the sorting ITSELF still works.
i did TO MUCH...
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: beginners question

Post by cborn »

dom wrote: Tue Oct 20, 2020 2:38 pm The report is off by a couple of lines which is *very* annoying, I'm not sure why it keeps doing that.
it seems only to happen with C parts. but NOT in asm parts
this block has BOTH and if you temper with the ASM part, eg by chancing '#asm' to 'asm;'
the error is at line 15, were it is.
repair that one and temper a real c line, eg real line 62 ' int x;' to 'fgfgint x;'
the error is at 64 instead of 62
with exactly the SAME file !!!
ps: this is my 'home-work' but WIP very WIP

Code: Select all


 /* C source start */
 /* by chris born ad 2020 as homework for z88dk, farkle */

 /* classic (not needed but BUILD_SDCC=0 or BUILD_SDCC=undefined) */
 /* zcc +zx -vn  dice_105b2.c -o dice105b2 -lndos -create-app -zorg=32768 */

 #include <spectrum.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <input.h>
 #include <string.h>

void  rndseed()  // not realy very random, still needs better one, this one uses Z80 R_register and ZX Spectrum 'FRAME' system variable
        {
      #asm              // uses HL, A, B register , reads R
         di             //  4t
         ld hl,23672    // 10t  raises only once in 69288 tstate with 1 per frame

         ld a,r         //  9t  raises every ~4~24 tstate with 1 or maybe 2 per instruction , inner LDDr , LDIr instructions counted.
         bit 0,a        //  8t
         jp z,r1        // 10t  z=0=even

         cpl            //|  4t the value of 'r' now decreases instead of raising
         jp n1          //| 10t  odd is now even  0xff=0x00
r1:
         inc a          //`  4t  raise and  even is now odd  0x00=0x01
         jp n1          //` 10t  jp=only for timing sake here, DELAY

n1:
         xor (hl)       //  7t xor on FRAMES value

         ld b,a         //  4t
         inc hl         //  6t raise once per 256 FRAMES of 69288 = after ~5.5 seconds

         ld a,r         //  9t
         bit 0,a        //  8t
         jp z,r2        // 10t  z=0=even

         rlca           //|  4t
         jp n2          //| 10t
r2:
         rrca           //`  4t
         jp n2          //` 10t
n2:
         xor (hl)       //  7t

         ld h,b         //  4t
         ld l,a         //  4t

         ld (23670),hl  //  16t write new seed

         ei             //   4t
         ret            //  10t  
      #endasm           // always(*) equal timing = 4+10+9+8+10 +4+10  +7+4+6+9+8+10 +4+10 +7+4+4   +16+4+10 =158 tstate
        }               // (*) in NON contended memory

//----------------------------------

int roll(unsigned char h[] , int hod , int aods)      // aods  = amount of dice sides
        {
         int x  ;
         for ( x=0 ;( x<hod && hod<=255); x++ )     // x= hand of dice
            {
             h[x]=rand()%aods +1   ;   // x only to 255
            }
         return ;
        }

//----------------------------------

void setrand()
        {
        rndseed()  ;
        char* sd = 23670 ;
        srand(*sd) ; 
//        return     ; //void does not need a return but is it good practice to always do it ??
        }

//----------------------------------

int sortit(unsigned char h[] , int hod)
{
   unsigned char t ;
    int x ;

sorting:
    t=0 ; // mind chr$0
    for ( x=0 ; x < hod-1 ; x++ )
      {
       if ( h[x] > h[x+1] )
            { 
             t = h[x] ;
             h[x]=h[x+1] ;
             h[x+1]=t ;
            }
       } //endx
    if ( t != 0 ) { goto sorting ; }
 return ;
 }           

//++++++++++++++++++++++++++++++++++

void main()  // its a full program with no sum as outcome, 'void'?
   {
   unsigned char x , number ,hand[256] , hand2[256] , players ;
   int           p8 , i8 , hand_of_dice , max_hand , play , round  , key , key2 , k ,
                 amount_of_dice_sides , all[256] , do_sort , score[256] , max_score ;

   setrand() ;
   zx_cls() ;

//   printf("Give number of sides of dice:\n") ;
//   scanf("%d", &amount_of_dice_sides) ;

   amount_of_dice_sides=6 ;

//   printf("how many dice do you want:\n") ;
//   scanf("%d", &hand_of_dice) ;
//   printf(" amount of dice %d ",hand_of_dice );
//   if (hand_of_dice > 255) 
//          {
//          hand_of_dice = 255 ;
//          printf(" is now %d", hand_of_dice) ;
//          }
//   printf("\n") ;

//   printf("what maximum score do you want\n") ;
//    scanf("%d", &max_score) ;
//   printf("winning score set to: %d ", max_score );

// farkle
  hand_of_dice=6 ;
  max_score=5000 ;
printf("THIS IS NOT YET\n  FARKLE is a dice game with many names,\n Its played with 6 dices usualy, common dices with 6 sides.\n\n");

  printf("Give number of players:") ;
  scanf("%d", &players) ;
  printf("\n\n%d players use %d dice\n\n", players, hand_of_dice ) ;

  printf("Do you want sorted dice : y \\ n ? ") ;

ask_sort:
  scanf("%c", &do_sort) ;

  if ( do_sort != 110 && do_sort != 121 ) { goto ask_sort ; }  // y=121  n=110
  printf("\nSorting is ");
  if (do_sort == 110) { printf("OFF");}
      else  { printf("ON");}

  sleep(3) ;
  round = 1 ;

start:
  memset(hand2, '' , amount_of_dice_sides+1 ) ;

  for (play=1 ; play<=players ; play++)
       {

    unsigned char select[6][6] , thrown , dice  ;  // rewrites cq 'clears' every time next player ??

    k=0 ;
    i8= play % 8 ; //integer modulo cuts off rest // just some colour information for ZX
    i8++ ;  // avoid  / 0 null terminator, +16??
    p8=55 - 7*(i8 ==7 || i8==8) ;

//  char p[11]={ 17, p8 ,16, i8 ,'P','l','a','y','e','r', \0 } ; // why is p8 or &p8 UNknown symbol, but as single command it is known ???
  char p[]={ 17, ' ' ,16, ' ' ,'P','l','a','y','e','r', 0 } ; // 4 spaces reserved for ZX colour info \x11 etc

//   p[0]=17 ; //paper
    p[1]=p8 ; //paper colour
//   p[2]=16 ; //ink
    p[3]=i8 ; //ink colour

    zx_cls() ; 
    max_hand = hand_of_dice ;

    printf("select dice column WISELY with correct \x11\x30\x10\x37number\x11\x37\x10\x30,\n 'r'=rolls & crashes?, space = next player\n");
    printf("single '1' or '5' dice score, triples always(tomuch)\n\n");
    printf("\x10\x37\x11\x30  Dice No:   1  2  3  4  5  6 \x10\x30\x11\x37\n") ;

roll_dice:

for ( x=max_hand; x<=hand_of_dice ; x++ ) { hand[x]='X';}

    printf("%s%2d : \x10\x10\x11\x37", p , play ) ;

    roll( hand , max_hand , amount_of_dice_sides) ;

    for ( x=0 ; x<max_hand ; x++ ) // count statistics
          {
          number= hand[x] ;
          hand2[number]++ ;   // only to 255
          all[number]++ ;     //         65535
//          printf("%d",number);
          }


    char once=1 ; // first=only print of dices with an next line command, better make show_hand extended ??
    dice =0 ;

    if (do_sort == 121){ sortit( hand , hand_of_dice ) ; }

show_hand:

    for ( x=0 ; x < hand_of_dice ; x++ )
               {
               if(hand[x]==88)  { printf("%3c" , hand[x] ) ; }  // print 'X' , might change later
                  else          { printf("%3d" , hand[x] ) ; }
               }

    printf("  %6d",score[play]) ;


//    while(1)
//          {
rekey:
    key = in_Inkey() ;
    if (key2 == key) { goto rekey ; }
    if (key == 32)
             {
              // spacekey:
              // key = in_Inkey() ;
              // if (key == 32) { goto spacekey ; }  // release ' ' before continue
              while(key==32){key = in_Inkey() ; }  // release key 32 before continue

              if ( k == 1) { printf("\n") ; }
              k = 0 ;
              goto next_player ;
             }

    if ( key > 48 && key <= max_hand+48 && hand[key-49] !='X')
             {
              if (once==1){
                           printf("\n") ;
                           once = 0 ;
                          }
              select[thrown][dice]=hand[key-49] ;
              hand[key-49]='X' ;
              printf("\n\x0Btake %2d=%2d:",key-48, select[thrown][dice] ) ;
              k = 1 ;
              if (select[thrown][dice] == 1) { score[play]=score[play]+100 ; }
              if (select[thrown][dice] == 5) { score[play]=score[play]+50  ; }

              if (dice > 1)
                   { 
                   if (select[thrown][dice] == select[thrown][dice-1]  && select[thrown][dice] == select[thrown][dice-2])
                      { score[play]=score[play] + 100 * select[thrown][dice] ; }
                   }
              dice++ ;
              goto show_hand ;
             }

// asci 'r'= chr$ 114
    if ( key == 114 && max_hand>0 )
             {
              max_hand = max_hand-dice ;
              thrown++ ;
              once = 1 ;
              while(key==114) {key = in_Inkey() ; }
              p[4]='R' ;
              p[5]='o' ;
              p[6]='l' ;
              p[7]='l' ;
              p[8]='e' ;
              p[9]='d' ;
              for (x=0 ;x<dice ;x++) { printf("%2d", select[thrown][x] ) ; }
              printf(" %d dice taken\n",dice) ;
              if (max_hand == 0) { max_hand = hand_of_dice ; }
              goto roll_dice ;
             } // throw again

    key2 = key ;
    goto rekey ;
//    } //end of while

next_player:
              p[4]='P' ;
              p[5]='l' ;
              p[6]='a' ;
              p[7]='y' ;
              p[8]='e' ;
              p[9]='r' ;
printf("%s%2d\x11\x37\x10\x30  has scored:%6d",p , play , score[play] ) ;
once = 1 ;
sleep(3) ;
  } //end player

printf("scores: \n");
  for (play=1 ; play<=players ; play++)
       { printf("",score[play]);}





  printf("\n statistics 'dicevalue=amount' with %d times %d = %d dice\n", players , hand_of_dice , players* hand_of_dice);
  printf(" last round (%dX%d) :  \n  ",round,players) ;
  for (x=1 ; x<=amount_of_dice_sides ;x++) { printf("%5d |",x) ; }

  printf("\n  ") ;
  for (x=1 ; x<=amount_of_dice_sides ;x++) { printf("%5d |",hand2[x]) ; }

  printf("\n overall results(%d): \n  ",round*players) ;
  for (x=1 ; x<=amount_of_dice_sides ;x++) { printf("%5d |",all[x]) ; }

  printf("\npress key to dice again, '0' will stop") ;

  scanf("%c",&key ) ;
  if (key != '0' )
             {
             round++  ;
             goto start ;
             }
  // return 0 ;   // its a void
  } //endmain

 /* C source end */

cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: beginners question

Post by cborn »

Code: Select all

warning: Implicit definition of function 'checking4connect' it will return an int. Prototype it explicitly if this is not what you want. [-Wimplicit-function-definition]
except that this routine does do return an INT value from 'int key' there is no variable needed to use/call it.
If look up on severall internet pages i did not get the answer :
"cut and paste that routine to a position above 'main()' in the c-script file"

main(){}
connect(){}

will give that error but

connect(){}
main(){}
will NOT....
the following order of the to BE compiled file is very importend, to C.
one error less for my c version sofar.
and i think i red it somewere long time ago, but all those tut's seem not to mention it as a kind off reminder.
Post Reply