Qwerty: from what I can tell, Color will always be == to 0, since you never seem to call a function that would get the current key Wink


And I have a few questions:

- Is there a way to copy VRAM to the LCD with no white borders, and in 16 bit color?
- How much RAM can be currently used by C programs with either a built in malloc() or a community-hacked version?
- How large can add-ins be and still work properly? If you have 15 MB left in storage and your Add-in is 13 MB, will it work correctly, or does it have to be of a certain max size?
1) Yes, I believe Bdisp_PutDisp_DD(); does that.
2) You can use 64k in C (up to 128k with Malloc). It's rather larger in ASM with z80man's routines.
3) I don't think there's a hard limit, but the OS will probably protest if it's larger than user flash or you try to malloc more memory than it's willing to give you.
I can't tell if that's causing the issue, but heart array is bugging me. It seems that the heart[4] command is overwriting the zero which terminates the string. try just writing it as char * heart = "your message here"
z80man wrote:
I can't tell if that's causing the issue, but heart array is bugging me. It seems that the heart[4] command is overwriting the zero which terminates the string. try just writing it as char * heart = "your message here"


You can do that, but I think he wants to reset it later, since he originally sets it to "----". What you need to do is change Heart[4] to Heart[3], since in C, like Axe, array indexes start at [0].
What do you mean about managing to get the MingW compiler working, Qwerty? Aren't you just using the PrizmSDK and Windows? Regarding array indexing, almost every language except TI-BASIC and Matlab uses 0-based indexing. Smile
KermMartian wrote:
What do you mean about managing to get the MingW compiler working, Qwerty? Aren't you just using the PrizmSDK and Windows? Regarding array indexing, almost every language except TI-BASIC and Matlab uses 0-based indexing. Smile


And Lua Wink
Ashbad wrote:
KermMartian wrote:
What do you mean about managing to get the MingW compiler working, Qwerty? Aren't you just using the PrizmSDK and Windows? Regarding array indexing, almost every language except TI-BASIC and Matlab uses 0-based indexing. Smile


And Lua Wink
Oh, really? That's a shame. Sad But anyway, let's stay focused. Actually, perhaps Qwerty needs his own C/C++ thread?
perhaps Razz

I have a few more questions, more focused on C itself rather than just Prizm C in general, and all of these assume I'm using C99:


1. how can structs be treated, when used with with a typedef declaration? Can you do things like make an array of structs in typedef form, or would you have to do something like make a struct of structs? Would this work?


Code:
typedef struct {
  int health;
  int magic;
} enemy;

enemy[] Bestiary = {enemy = {2,4}, enemy = {3,6}}



2. how much can I butcher the #define system? Would this setup be possible?


Code:

#define byte[] unsigned char[]
#define new_string(name,value) byte[] name = value


I made this for myself for easy string declaration, and it obviously just would turn something like "new_string(NAME, "Lekens");" to "unsigned char[] NAME = "Lekens";" would it work?


3. within a struct declaration, can you access "members" of the struct inside of it, in a way someway like this.member? While I truly doubt it would work like this, is there a form of it that would work like this?


Code:
typedef struct {
  int health;
  int health = this.health;
} enemy;


while it's not the greatest example, I think it shows what I mean Razz

help? tia.
To access members inside a code, try this:


Code:
struct point {
   int x;
   int y;
} my_point;
 
struct point *p = &my_point;  // To declare p as a pointer of type struct point
 
(*p).x = 8;                   // To access the first member of the struct
p->x = 8;                     // Another way to access the first member of the struct
well, yeah, but what I meant is like accessing a member of a struct inside the declaration of the struct. Like so:


Code:
struct point {
   int x;
   int y = this.x;
} my_point;
Why don't just use the variable name? It will work from within the struct, I'm pretty sure.
oh, okay, that's perfect Smile that answers number 3, number 1 I finally found was true online (I can make an array of structs) and #2 seems okay and was probably stupid to ask about Razz
Your array syntax is way out of whack.

Code:
// Wrong
int[] foo;
// Right
int foo[];


Ashbad wrote:
1. how can structs be treated, when used with with a typedef declaration? Can you do things like make an array of structs in typedef form, or would you have to do something like make a struct of structs? Would this work?


Code:
typedef struct {
  int health;
  int magic;
} enemy;

enemy[] Bestiary = {enemy = {2,4}, enemy = {3,6}}

Yes, but the syntax is cleaner than that:

Code:
// snipped typedef
enemy Bestiary[] = {{2, 4}, {3,6}};


Ashbad wrote:
2. how much can I butcher the #define system? Would this setup be possible?


Code:

#define byte[] unsigned char[]
#define new_string(name,value) byte[] name = value

Legal, but there are some syntax problems here again, and several conventions that you're murdering with such a construct. Fixed version:

Code:
// #define works too, but typedef makes more sense for that
typedef unsigned char byte;
// ## to concatenate tokens
// All-caps macro name, since constants and macros are usually all-caps by convention
// (new_string() looks too much like a function, and it's good to know what gets parsed at
//  compile-time only)
#define STRDEF(name, value) byte name##[] = value


Ashbad wrote:
3. within a struct declaration, can you access "members" of the struct inside of it, in a way someway like this.member? While I truly doubt it would work like this, is there a form of it that would work like this?


Code:
typedef struct {
  int health;
  int health = this.health;
} enemy;

No, and assignment in the typedef like that probably isn't legal either. Best option for that is to write a function to initialize such a struct, I think:

Code:
typedef struct {
    int max_hp;
    int hp;
} enemy;

enemy *new_enemy(int max_hp) {
    enemy *p = malloc(sizeof(enemy));
    p->max_hp = max_hp;
    p->hp = max_hp;
    return p;
}

// Alternate approach, where caller allocates
void init_enemy(enemy *p, int max_hp) {
    p->max_hp = max_hp;
    p->hp = max_hp;
}

// Invocations:
enemy *stede_bonnet = new_enemy(400);
// or...
enemy blackbeard;
init_enemy(&blackbeard, 401);


You all converse too fast, since there were no responses to that when I started composing this.
That's extremely helpful, tari Smile A few questions, to make sure I get everything. Here is part of the code for bestiary.c, where I create a struct enemy, make an initializing function, and make a const array of enemies called Bestiary:


Code:
#include "ROLAT_defs.h"
#include "stdlib.h"
#include "Enemies.c"
#include "string.h"

typedef struct {
     unsigned char name[9];
    void*sprite_data;
    unsigned short magic;
    unsigned char intelligence, hit, move_1, move_2, move_3;
    unsigned short attack, defense;
    unsigned int is_boss : 4;
    unsigned int can_heal : 4;
    unsigned int type : 4;
    unsigned int orb_held : 4;
    int width, height, gp, xp, hp, max_hp;
} enemy;
 
int ENEMY_SIZE = sizeof(enemy);
 
void CreateDynamicEnemy(enemy*p, int bestiary_num) {
    memcpy(p,&(Bestiary[bestiary_num]),ENEMY_SIZE);
}
 
 
const enemy Bestiary[] = {
{"Nomekati\0",Nomekati,0,0,0,200,15,5,50,50,75,25,30,0,0,0,0,64,64}
}


This setup SHOULD work, but I unfortunately am not at a stage where I can test it and actually see physical results :/ Is the CreateDynamicEnemy function set up correctly to copy the contents of an object in the array into the corresponding struct?
I truly need help, I've been going over this code for a few hours now, and I still don't get what's wrong with it. Here are my source files:

ROLAT_defs.h

Code:
/*
All definitions for everything needed for ROL:AT are included here,
sorted by type and meaning
*/


//-----------------------
//   TECHNICAL THINGS
//-----------------------

#define string(name, value) byte name##[] = value

#define clean_exit 0
#define error_exit 1


Main.c

Code:
#include "ROLAT_defs.h"
#include "battle_system.c"


int main() {
   battle_main();   
   return clean_exit;
}


useful.c

Code:
#include "keyboard_syscalls.h"
#include "keyboard.hpp"

#define LCD_WIDTH_PX 384
#define LCD_HEIGHT_PX 216
#define MASK_RED 0xf800

void CopySpriteMasked(const char*data, int x, int y, int width, int height, int maskcolor);
int PRGM_GetKey(void);

void CopySpriteMasked(const char*data, int x, int y, int width, int height, int maskcolor) {
   char* VRAM = (char*)0xA8000000;
   VRAM += 2*(LCD_WIDTH_PX*y + x);
   for(int j=y; j<y+height; j++) {
      for(int i=x; i<x+width;  i++) {
         if ((((((int)(*data))&0x000000FF)<<8) | ((((int)(*(data+1))))&0x000000FF)) != maskcolor) {
            *(VRAM++) = *(data++);
            *(VRAM++) = *(data++);
         } else { VRAM += 2; data += 2; }
      }
      VRAM += 2*(LCD_WIDTH_PX-width);
   }
}

int PRGM_GetKey(){
   unsigned char buffer[12];
   PRGM_GetKey_OS( buffer );
   return ( buffer[1] & 0x0F ) * 10 + ( ( buffer[2] & 0xF0 ) >> 4 );
}



Enemies.c

Code:
const char Nomekati[] = {
   0xf8,0x00,0xf8 ... (you get it, though there's 3 colors: 0xf800 (RED), 0x0000 (white) and 0xFFFF (black)
   //goes on and on, it's a 64x64 image (troll face)
};


battle_system.c

Code:
#include "bestiary.c"
#include "display_syscalls.h"
#include "ROLAT_defs.h"
#include "useful.c"

#define endof_render_exit 2

int render_status = clean_exit;
int Current_Opponents_nums[] = {1,0,0,0,0,0};
enemy Current_Opponents[6];

int battle_main(void);
int renderloop_bs(void);

int battle_main() {
   for (int i=0;i<=5;i++) {
      if (Current_Opponents_nums[i] != 0) {
         CreateDynamicEnemy(&(Current_Opponents[i]), Current_Opponents_nums[i]);
      }
   }
   
   while (render_status == clean_exit) {
      render_status == renderloop_bs();
      if (PRGM_GetKey()) {
         render_status = endof_render_exit;
      }
   }
   return (render_status == endof_render_exit) ? clean_exit : error_exit;
}

int renderloop_bs() {
   Bdisp_AllCr_VRAM();
   CopySpriteMasked(Bestiary[1].sprite_data, 20, 20, Bestiary[1].width, Bestiary[1].height, MASK_RED);
   Bdisp_PutDisp_DD();
   return clean_exit;
}


bestiary.c

Code:
#include "ROLAT_defs.h"
#include "stdlib.h"
#include "Enemies.c"
#include "string.h"

typedef struct {
    unsigned char name[9];
    const void*sprite_data;
    unsigned short magic;
    unsigned char intelligence, hit, move_1, move_2, move_3;
    unsigned short attack, defense;
    unsigned char is_boss;
    unsigned char can_heal;
    unsigned char type;
    unsigned char orb_held;
    int width, height, gp, xp, hp, max_hp;
} enemy;
 
int ENEMY_SIZE = sizeof(enemy);
void CreateDynamicEnemy(enemy*p, int bestiary_num);

enemy Bestiary[] = {
{"/0",(const char*)0x00000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{"Nomekati\0",Nomekati,0,0,0,200,15,5,50,50,75,25,30,0,0,0,0,64,64}
};

 
void CreateDynamicEnemy(enemy*p, int bestiary_num) {
    memcpy(p,&(Bestiary[bestiary_num]),ENEMY_SIZE);
}




And yes, I do copy "ROLAT_defs.h" to the "include" header of the Prizm SDK, I use this Batch script I made in a few minutes to do that and more:


Code:
COPY /V /Y F:\ROLAT\Code F:\PrizmSDK\
COPY /V /Y F:\ROLAT\Code\Flibs F:\PrizmSDK\
COPY /V /Y F:\ROLAT\Code\Data F:\PrizmSDK\
COPY /V /Y F:\ROLAT\Code\Headers F:\PrizmSDK\include
COPY /V /Y F:\ROLAT\Graphics\Icons F:\PrizmSDK\icons

CD "F:\PrizmSDK"
DEL ROLAT.bin
DEL Main.bin
bin\make.exe %*

@ECHO off

IF NOT EXIST F:\PrizmSDK\ROLAT.g3a GOTO END

MOVE /Y F:\PrizmSDK\ROLAT.g3a F:\ROLAT\Builds\PlaceH.placeh
CD F:\ROLAT\Builds\
ECHO PlaceHold > ROLAT.g3a
COPY /Y PlaceH.placeh ROLAT.g3a
SET FileDate=%date:/=%_%time::=%
REN ROLAT.g3a "ROLAT_%FileDate%.g3a"
ECHO Build Version ROLAT_%FileDate%

:END
PAUSE
@ECHO on


What the problem is isn't that there's a problem getting things to compile alright -- I already fixed all the files so that it compiles with no errors whatsoever. The real problem is when I run the Add-in, I get this error:


Code:
System ERROR
 REBOOT    :[EXIT]
 INITIALIZE:[EXE]
  ADDRESS(W)
  TARGET=55555567
  PC    =0810000A


So, it's more of a problem with the actual code. The code is supposed to set up 6 enemies and run a battle system renderloop, in which for now I only render the first enemy (with an enemy index pointing to the "Nomekati" enemy in the bestiary) using the varibles not in the dynamic enemy variable, but rather in the const one in the Bestiary array (since those values aren't supposed to change anyways). I'm sorry for all of the boring code posted, but I really would sincerely love help figuring out what I did wrong here. TIA.
Can you try selectively commenting things out to figure out where the bug happens? It looks like a segfault to me. For example, first comment out your whole main() body and make sure the add-in runs and exits as expected. Then slowly comment it back in bit-by-bit. Off the top of my head, I'm pretty sure that CreateDynamicEnemy or some elements of Bestiary[] are at fault.
It looks like a segfault to me too, since the target address isn't one that's likely to have been paged in by the OS. However, an unmapped page should generate a TLB error, not a system error...
hmm, that's a good suggestion, Kerm Smile That would be an excellent way for me to test it out decently quickly. Most likely it is that area -- I'll try messing with it once I make sure it IS that area until it does generally what it's supposed to Wink
I'm concerned by the PC value. It shouldn't be trying to execute out at 810000A, since that's probably the .bss segment. (Sure would be nice if we knew what these error messages were really saying.) I hesitate to blame the toolchain for that, though.

When in doubt, I like to change the linker to ELF output (line 2 of prizm.ld -> OUTPUT_ARCH(sh-elf)) and examine the resultant file (main.bin IIRC) with objdump (maybe objdump -hs perhaps in addition to -d) to get a better feel for how the memory map looks.

There's a good chance you're smashing the stack, making one of your subroutines return to 810000A (likely where one of your arrays is placed) which, predictably, doesn't contain a sensible instruction so you get the access fault (seems that whatever's at that address attempts to do a word access to an odd address).
Ashbad, you should update your crt0.s while you're at it.

http://www.jonimoose.net/calcstuff/prizm/crt0.s
  
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 2 of 3
» 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