OK, I am making a little platformer where the player is an easter egg, trying to learn C at the same time.

here is my code so far:


Code:

#include <color.h>
#include <display.h>
#include <display_syscalls.h>
#include <keyboard.hpp>
#include <keyboard_syscalls.h>
#include <CONVERT_syscalls.h>
/* SPRITES */
#include "sprites.h"
/* ROUTINES */
#include "routines.h"

/* MAP */
int map[7][12] = {
   { 0,0,0,0,0,0,0,0,0,0,0,0 },
   { 0,0,0,0,0,0,0,0,0,0,0,0 },
   { 0,0,0,0,0,0,0,0,0,0,0,0 },
   { 0,0,0,0,0,0,0,0,0,0,0,0 },
   { 0,0,0,0,0,0,0,0,0,0,0,0 },
   { 2,0,0,0,0,0,0,0,0,0,0,2 },
   { 1,1,1,1,1,1,1,1,1,1,1,1 }
};

/* GAME ROUTINES */
void drawMap(int x, int y, int width, int height) {
   for (int i = 0; i < height; ++i) {
      for (int j = 0; j < width; ++j) {
         switch (map[i][j]) {
            case 1:
               CopySpriteNbitMasked(ground, j*32+x, i*32+y, 32, 32, ground_palette, COLOR_WHITE, 8);
               break;
            case 2:
               CopySpriteNbitMasked(grass, j*32+x, i*32+y, 32, 32, grass_palette, COLOR_WHITE, 8);
               break;
         }
      }
   }
}

/* MAIN LOOP */
int main() {
   /* VARIABLES */
   int key;
   int key_dump;

   int player_x = 64;
   int player_y = 1;

   int player_x_floored;
   int player_y_floored;

   int origin_x = 0;
   int origin_y = 0;

   char buffer;


   /* SETUP */
   // enable fullcolor mode
   Bdisp_EnableColor(1);

   /* MAIN LOOP */
   while (1) {
      /* GETKEY */
      key = PRGM_GetKey();

      if (key==KEY_PRGM_MENU) {
         GetKey(&key_dump);
      }

      /* COLLISIONS, ETC. */
      // check if a tile is under player
      player_x_floored = floor2((player_x/32)-1);
      player_y_floored = floor2(player_x/32);

      if (map[player_y_floored][player_x_floored]==0 && map[player_y_floored][player_x_floored+1]==0) {
         player_y++;
      }


      /* DRAWING */
      // draw BG
      Bdisp_Fill_VRAM(COLOR_LIGHTCYAN, 3);

      // draw map
      drawMap(origin_x, origin_y, 12, 7);

      // draw player
      CopySpriteNbitMasked(egg, player_x, player_y, 32, 32, egg_palette, COLOR_WHITE, 8);

      // debug
      strcpy(buffer, "  ");
      itoa(player_x_floored, buffer+2);
      PrintXY(1, 1, buffer, TEXT_MODE_NORMAL, TEXT_COLOR_BLACK);

      // refresh screen
      Bdisp_PutDisp_DD();
   }
   return 1;
}


The floor2 routine I am using:


Code:

float floor2(int x) {
   return ((int)x) - (x < 0);
}



OK, I don't really have a problem right now, I just have an issue.

Right now the debug PrintXY info is displaying "#BE". Is this a problem with the floor routine, itoa, or my code?
My guess is that you're treating buffer, a "char" value, like a char*, a pointer to a char array. You correct code for main() should be (with changes marked):

Code:
/* MAIN LOOP */
int main() {
   /* VARIABLES */
   int key;
   int key_dump;

   int player_x = 64;
   int player_y = 1;

   int player_x_floored;
   int player_y_floored;

   int origin_x = 0;
   int origin_y = 0;

   char buffer[4]; // needs to be an array of characters on the stack


   /* SETUP */
   // enable fullcolor mode
   Bdisp_EnableColor(1);

   /* MAIN LOOP */
   while (1) {
      /* GETKEY */
      key = PRGM_GetKey();

      if (key==KEY_PRGM_MENU) {
         GetKey(&key_dump);
      }

      /* COLLISIONS, ETC. */
      // check if a tile is under player
      player_x_floored = floor2((player_x/32)-1);
      player_y_floored = floor2(player_x/32);

      if (map[player_y_floored][player_x_floored]==0 && map[player_y_floored][player_x_floored+1]==0) {
         player_y++;
      }


      /* DRAWING */
      // draw BG
      Bdisp_Fill_VRAM(COLOR_LIGHTCYAN, 3);

      // draw map
      drawMap(origin_x, origin_y, 12, 7);

      // draw player
      CopySpriteNbitMasked(egg, player_x, player_y, 32, 32, egg_palette, COLOR_WHITE, 8);

      // debug
      // NOTE the user of "&" references below
      strcpy(&buffer, "  ");
      itoa(player_x_floored, &buffer+2);
      PrintXY(1, 1, &buffer, TEXT_MODE_NORMAL, TEXT_COLOR_BLACK);

      // refresh screen
      Bdisp_PutDisp_DD();
   }
   return 1;
}

That "#BE" happens to be the characters at 0x20 (the ASCII for space) and I have no idea what other bytes you're trying to overwrite. (And if the PrizmSDK is really letting you get away with this, it needs to be fixed).
ah ok. I did a search and found this page, so I just copy and pasted the code.
I think you need to review your use of pointers a bit. Buffer is an array of characters, which is the same as a pointer to character as far as your compiler and CPU are concerned. Here's your current code with errors:
Code:
strcpy(&buffer, "  "); 
      itoa(player_x_floored, &buffer+2); 
      PrintXY(1, 1, &buffer, TEXT_MODE_NORMAL, TEXT_COLOR_BLACK); 
First, you're getting the address of the pointer to character, and passing that to strcpy, which is like getting the address of the address of the first character. Too much indirection; remove the &. On the next line, you make the same mistake. Buffer is already a pointer, so buffer+2 is all you need. I'm surprised you didn't trigger a segfault there. Same thing with the PrintXY line: just remove the &.
Quote:
the player is an easter egg, trying to learn C at the same time


I almost had my hopes up, until i realized, this is just sloppy english.
KermMartian wrote:
I think you need to review your use of pointers a bit. Buffer is an array of characters, which is the same as a pointer to character as far as your compiler and CPU are concerned. Here's your current code with errors:
Code:
strcpy(&buffer, "  "); 
      itoa(player_x_floored, &buffer+2); 
      PrintXY(1, 1, &buffer, TEXT_MODE_NORMAL, TEXT_COLOR_BLACK); 
First, you're getting the address of the pointer to character, and passing that to strcpy, which is like getting the address of the address of the first character. Too much indirection; remove the &. On the next line, you make the same mistake. Buffer is already a pointer, so buffer+2 is all you need. I'm surprised you didn't trigger a segfault there. Same thing with the PrintXY line: just remove the &.

Ah, shoot. I overcorrected myself. Before, his "char" was just a local variable - I totally overlooked that a char[] is a pointer that you have to dereference. Yes, remove the "&"s and you should be fine.
OK, now... I changed my project to a paint program.

I wanted to get used to C arrays.

Here is my code right now:


Code:

#include <color.h>
#include <display.h>
#include <display_syscalls.h>
#include <keyboard.hpp>
#include <keyboard_syscalls.h>
/* USEFUL ROUTINES */
#include "routines.h"


/* FUNCTIONS */
void dispCanvas(int x, int y, int width, int height, int zoom, char **canvas) {
   int i;
   int j;
   for (i = 0; i < width; i++) {
      for (j = 0; j < height; j++) {
         if (canvas[i][j]) {
            fillArea(i*zoom+x, j*zoom+y, zoom, zoom, canvas[i][j]);
         }
      }
   }
}

void dispCursor(int origin_x, int origin_y, int x, int y, int zoom) {
   fillArea(x*zoom+origin_x, y*zoom+origin_y, zoom, zoom, COLOR_RED);
}

/* MAIN FUNCTION */
int main() {
   int key;
   int key_dump;

   int cursor[2] = {1,1};
   int origin[2] = {1,1};

   int canvas_height = 8;
   int canvas_width = 8;
   char canvas[8][8];

   int zoom = 4;

   int i;
   int j;

   for (i = 0; i < canvas_height-1; i++) {
      for (j = 0; j < canvas_width-1; j++) {
         canvas[i][j] = COLOR_BLACK;
      }
   }

   canvas[0][0] = makeColor(255, 100, 0);
   canvas[0][7] = makeColor(255, 100, 0);
   canvas[7][0] = makeColor(255, 100, 0);
   canvas[7][7] = makeColor(255, 100, 0);

   /* MAIN LOOP, NEVER BREAK */
   while (1) {
      /* GETKEY */
      if (PRGM_GetKey()==KEY_PRGM_MENU) {
         // handle menu
         GetKey(&key_dump);
      }
      // move cursor
      if (PRGM_GetKey()==KEY_PRGM_UP && cursor[0]>0) {
            cursor[0]--;
      }
      if (PRGM_GetKey()==KEY_PRGM_DOWN && cursor[0]<canvas_height) {
            cursor[0]++;
      }
      if (PRGM_GetKey()==KEY_PRGM_LEFT && cursor[1]>0) {
            cursor[1]--;
      }
      if (PRGM_GetKey()==KEY_PRGM_RIGHT && cursor[1]<canvas_width) {
            cursor[1]++;
      }

      // display the canvas
      dispCanvas(origin[0], origin[1], canvas_width, canvas_height, zoom, &canvas);

      // display the cursor
      dispCursor(origin[0], origin[1], cursor[0], cursor[1], zoom);
   }


   return 1;
}


No errors, just this:


Code:

/home/flyingfisch/Desktop/PrizmSDK-0.3/projects/paint/src/main.c:77,71 - Warning - incompatible pointer types passing 'char (*)[8][8]' to parameter of type 'char **' [Disable with -Wno-incompatible-pointer-types]


When running this addin the calc does a system error.

Now, I know I have something going wrong with my pointers, and my question is what is wrong, and an explanation.
Your first problem is that you're using a canvas made of chars, which are 1 byte each, but color_ts are shorts. You should make your canvas either color_t canvas[8][8] or unsigned short canvas[8][8]. The former is preferable. Your second problem is that you're taking canvas, which is a char[][] == char**, and taking its address via the & operator, which gives you a char***. You're indirecting too much again; just pass in canvas. And don't forget to change dispCanvas to take a color_t** instead.
Thanks Kerm Smile

Now I need to know why this code is not making a square canvas filled with black pixels:


Code:

#include <color.h>
#include <display.h>
#include <display_syscalls.h>
#include <keyboard.hpp>
#include <keyboard_syscalls.h>
/* USEFUL ROUTINES */
#include "routines.h"


/* FUNCTIONS */
void dispCanvas(int x, int y, int width, int height, int zoom, color_t **canvas) {
   int i;
   int j;
   for (i = 0; i < width+1; i++) {
      for (j = 0; j < height+1; j++) {
         if (canvas[i][j]) {
            fillArea(i*zoom+x, j*zoom+y, zoom, zoom, canvas[(color_t)i][(color_t)j]);
         }
      }
   }
}

void dispCursor(int origin_x, int origin_y, int x, int y, int zoom) {
   fillArea(x*zoom+origin_x, y*zoom+origin_y, zoom, zoom, COLOR_RED);
}

/* MAIN FUNCTION */
int main() {
   /* SETUP */
   // enable fullcolor
   Bdisp_EnableColor(1);
   /* VARS */
   char buffer[10];

   int key;
   int key_dump;

   int cursor[2] = {0,0};
   int origin[2] = {1,1};

   int canvas_height = 7;
   int canvas_width = 7;
   color_t canvas[8][8];

   int zoom = 4;

   int i;
   int j;

   for (i = 0; i < canvas_height-1; i++) {
      for (j = 0; j < canvas_width-1; j++) {
         canvas[i][j] = 0x0000;
      }
   }

   /* MAIN LOOP, NEVER BREAK */
   while (1) {
      // clear screen
      Bdisp_AllClr_VRAM();

      /* GETKEY */
      if (PRGM_GetKey()==KEY_PRGM_MENU) {
         // handle menu
         GetKey(&key_dump);
      }

      // move cursor
      if ((PRGM_GetKey()==KEY_PRGM_UP) && (cursor[1]>0)) {
         cursor[1]--;
      }

      if ((PRGM_GetKey()==KEY_PRGM_DOWN) && (cursor[1]<canvas_height)) {
         cursor[1]++;
      }

      if ((PRGM_GetKey()==KEY_PRGM_LEFT) && (cursor[0]>0)) {
            cursor[0]--;
      }

      if ((PRGM_GetKey()==KEY_PRGM_RIGHT) && (cursor[0]<canvas_width)) {
            cursor[0]++;
      }

      // display the canvas
      dispCanvas(origin[0], origin[1], canvas_width, canvas_height, zoom, canvas);

      // display the cursor
      dispCursor(origin[0], origin[1], cursor[0], cursor[1], zoom);

      // debug
      strcpy(buffer, "  ");
      itoa(cursor[1], buffer+2);
      PrintXY(1, 7, buffer, TEXT_MODE_NORMAL, TEXT_COLOR_BLACK);

      // refresh screen
      Bdisp_PutDisp_DD();
   }


   return 1;
}


Instead its making 8 rows, all different colors (to be exact, top to bottom: off-white, purple, green, purple, orange, purple, gold, purple).
Variables i and j are integers; why are you suddently casting them to color_ts?

Code:
fillArea(i*zoom+x, j*zoom+y, zoom, zoom, canvas[(color_t)i][(color_t)j]);
KermMartian wrote:
Variables i and j are integers; why are you suddently casting them to color_ts?

Code:
fillArea(i*zoom+x, j*zoom+y, zoom, zoom, canvas[(color_t)i][(color_t)j]);



Oh, I did that as a debug thing, it didn't change anything. this code does exactly the same thing:


Code:

#include <color.h>
#include <display.h>
#include <display_syscalls.h>
#include <keyboard.hpp>
#include <keyboard_syscalls.h>
/* USEFUL ROUTINES */
#include "routines.h"


/* FUNCTIONS */
void dispCanvas(int x, int y, int width, int height, int zoom, color_t **canvas) {
   int i;
   int j;
   for (i = 0; i < width+1; i++) {
      for (j = 0; j < height+1; j++) {
         if (canvas[i][j]) {
            fillArea(i*zoom+x, j*zoom+y, zoom, zoom, canvas[i][j]);
         }
      }
   }
}

void dispCursor(int origin_x, int origin_y, int x, int y, int zoom) {
   fillArea(x*zoom+origin_x, y*zoom+origin_y, zoom, zoom, COLOR_RED);
}

/* MAIN FUNCTION */
int main() {
   /* SETUP */
   // enable fullcolor
   Bdisp_EnableColor(1);
   /* VARS */
   char buffer[10];

   int key;
   int key_dump;

   int cursor[2] = {0,0};
   int origin[2] = {1,1};

   int canvas_height = 7;
   int canvas_width = 7;
   color_t canvas[8][8];

   int zoom = 4;

   int i;
   int j;

   for (i = 0; i < canvas_height-1; i++) {
      for (j = 0; j < canvas_width-1; j++) {
         canvas[i][j] = 0x0000;
      }
   }

   /* MAIN LOOP, NEVER BREAK */
   while (1) {
      // clear screen
      Bdisp_AllClr_VRAM();

      /* GETKEY */
      if (PRGM_GetKey()==KEY_PRGM_MENU) {
         // handle menu
         GetKey(&key_dump);
      }

      // move cursor
      if ((PRGM_GetKey()==KEY_PRGM_UP) && (cursor[1]>0)) {
         cursor[1]--;
      }

      if ((PRGM_GetKey()==KEY_PRGM_DOWN) && (cursor[1]<canvas_height)) {
         cursor[1]++;
      }

      if ((PRGM_GetKey()==KEY_PRGM_LEFT) && (cursor[0]>0)) {
            cursor[0]--;
      }

      if ((PRGM_GetKey()==KEY_PRGM_RIGHT) && (cursor[0]<canvas_width)) {
            cursor[0]++;
      }

      // display the canvas
      dispCanvas(origin[0], origin[1], canvas_width, canvas_height, zoom, canvas);

      // display the cursor
      dispCursor(origin[0], origin[1], cursor[0], cursor[1], zoom);

      // debug
      strcpy(buffer, "  ");
      itoa(cursor[1], buffer+2);
      PrintXY(1, 7, buffer, TEXT_MODE_NORMAL, TEXT_COLOR_BLACK);

      // refresh screen
      Bdisp_PutDisp_DD();
   }


   return 1;
}
bump.


EDIT:

Soooooooooo... any ideas?
Where should it fill the canvas exactly?
Casimo wrote:
Where should it fill the canvas exactly?


What do you mean, exactly? canvas is just a variable name I picked for the image canvas. It is being drawn at the top left of the screen.

That part works fine. My problem is that I cannot get it to display the colors correctly. Wink
If the canvas is 8*8, why are you storing into 0-6 which is only 7 values? Wouldn't you need to do 0-7 by making the canvas width and height 8 instead of 7?
Oh, I didn't even realize that. I will check that when I get home. Wink
Yeah, you have some off-by-one errors all over the place:


Code:
   for (i = 0; i < width+1; i++) { // should just be width
      for (j = 0; j < height+1; j++) { // should just be height
[...]
   int canvas_height = 7; // should be 8
   int canvas_width = 7;  // should be 8
[...]
   for (i = 0; i < canvas_height-1; i++) { // should just be canvas_height
      for (j = 0; j < canvas_width-1; j++) { // should just be canvas_width
why should it be 8? 0-7 is 8 cells...
flyingfisch wrote:
why should it be 8? 0-7 is 8 cells...
You should represent the width and height everywhere as 8, because that's what it is. Then, your for() loops always loop from i=0 to i<width or height, which means, 0, 1, 2, 3, 4, 5, 6, 7. It stops at 7, because 7 is the last number less than 8.
Oh, ok, I see. OK, as soon as I get home I'll take care of that. Wink
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 2
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement