Undefined opcode

Stuck? This is the place to go to get and give help.

Undefined opcode

Postby kevman323 » January 8th, 2014, 8:24 am

I am currently working on a project that requires a LOT of variable storage, and I am running into some errors that I think may be caused buy the many arrays that I need for the game.

When I run the game through the DSGM emulator (it compiles fine), one of 3 things can happen: It can work completely fine, it can say "The rom image has crashed", or it can say "Undefined opcode - with no debug vector defined".

The part of the code that causes the problem is in the "createFloorObject" object, and in the "Set floor layouts" section. What this part of the code is doing is reading room layouts from a text document and inputing the info into several arrays, roomDatObject[7][7][50], roomDatX[7][7][50], and roomDatX[7][7][50]. There is a 7X7 grid of rooms, and each room contains 50 object type/x position/y position values.

By messing with the random numbers in my code, I found that loading room 3 repeatedly can cause a problem, but the code CAN load room 3, just doing it a lot causes an error. This is why I think it might be a memory issue.

My main question is what does the error message mean? I suspect it has something to do with memory management, but I really have no idea. Also, can you guys think of a better way to store all this data?

Thanks for reading all this,
kevman323
Attachments
IsaacRemade.dsgm
(36.39 KiB) Downloaded 46 times
kevman323
 
Posts: 28
Joined: January 14th, 2013, 2:11 am

Re: Undefined opcode

Postby Mint » January 8th, 2014, 8:48 am

All right, I tried your ROM, and you have confirmation that it isn't just you; I consecutively received all your errors.

I need to look more into this...will try tomorrow.
I have now lost track of the DSGM source code!
User avatar
Mint
 
Posts: 1036
Joined: May 23rd, 2011, 10:25 pm
Location: A la Escuela del Chocolate

Re: Undefined opcode

Postby YoshiInAVoid » January 8th, 2014, 7:26 pm

I don't have a compiler on me - It's been a while, but I opened up your project anyway and think I've caught it:

roomType is defined as:

Code: Select all
int roomType[7][7]


You set currentRoomX and currentRoomY to a random number between 0 and 6 here:

Code: Select all
currentRoomX=Random(0,6);
currentRoomY=Random(0,6);


And then try to access the data to what could potentially be out of bounds of the stack memory of roomType:

Code: Select all
roomType[currentRoomX][currentRoomY-1]


You may only access numbers 0 - 6 in the square brackets. But if currentRoomY is 0, then you are effectively dealing with:

Code: Select all
roomType[0][-1]


The compiler did not catch this and give a warning because it is generated at run time.

If you did:

Code: Select all
roomType[0][-1] = 0;


The compiler would give a warning that you are setting arbitrary stack memory.

Hope this helps.
YoshiInAVoid
Site Admin
 
Posts: 2111
Joined: December 30th, 2010, 11:53 am
Location: England

Re: Undefined opcode

Postby kevman323 » January 8th, 2014, 9:33 pm

I don't think this is the issue. Before "roomType[currentRoomX][currentRoomY-1]" I have "if currentRoomY>0", so that statement should not execute unless the values are within the valid range. Also, if I set the room generator to ONLY use room 1, it works 100% of the time,regardless of which rooms are being generated, but there are not specific rooms that cause this error.

The weird thing is on my previous version of this project, I had 48 arrays, 1 for each room, formatted as array[50][3], and it worked perfectly, but I should have pretty close to the same amount of variables in this new version, just in a different format.
kevman323
 
Posts: 28
Joined: January 14th, 2013, 2:11 am

Re: Undefined opcode

Postby YoshiInAVoid » January 8th, 2014, 10:45 pm

Sorry, I missed that line. I was just scanning through for obvious answers.

My next guess was going to be that:

Code: Select all
int randNum1;


Is used before it is assigned a value, but unfortunately that is not true either.

I'm not sure how many lines are in your text files, but just to be safe, I'd say that before dealing with them you should just check that the line was indeed copied. Foxi's library returns 0 (which should be NULL) if the line specified is more than there are lines in the text file:

Code: Select all
strcpy(AString,FAT_ParseTextFile("BasementNormalRooms.txt",(randNum1*4)));
        if (AString != NULL) {
          for (i = 0; i < (49 + 1); i++) {
            strncpy(LineString, &AString[4*i], 3);
            roomDatObject[j][k][i]=atoi(LineString);
          }
        }


Also, forgive me if I'm just extremely wrong here, but in Foxi's lib, he doesn't actually allocate the memory for the string, here's the basis of it:

Code: Select all
char* TextString=0;
if (CurrentLine==line){
  fgets (TextString,202,Readout);
  CurrentLine++;
}


Maybe this is the issue?
YoshiInAVoid
Site Admin
 
Posts: 2111
Joined: December 30th, 2010, 11:53 am
Location: England

Re: Undefined opcode

Postby YoshiInAVoid » January 8th, 2014, 11:05 pm

Reading from a text file every time you want a new piece of data isn't the greatest approach. You're better off reading the whole file, and manipulating it when you need it.

I wrote a function which will get a string at a certain line of another string for you:

Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *getTextAtLine(char *unparsed, unsigned int line) {
    char *parsed = NULL;
    unsigned int start = 0;
    unsigned int end = 0;
    const unsigned int unparsedLen = strlen(unparsed);
   
    line--;
    while(line > 0) {
        if(unparsed[start] == '\0') break;
        while(unparsed[start] != '\n') {
            start++;
        }
        start++;
        line--;
    }
   
    parsed = malloc(unparsedLen - start + 1);
    strcpy(parsed, unparsed + start);
   
    for(end = start; unparsed[end] != '\n' && unparsed[end] != '\0'; end++);
   
    parsed = realloc(parsed, end - start + 1);
   
    parsed[end - start] = '\0';
   
    return parsed;
}

int main(void) {
   
    char *unparsed = "line1\nline2\nline3\nline4\nline5";
    char *parsed = NULL;   
   
    parsed = getTextAtLine(unparsed, 3);
   
    printf("%s", parsed);
   
    free(parsed);
   
    return 0;
}


Since memory is allocated on the heap, just remember to free it like I did in the example.

There is probably a faster way to do this if you resorted to assembly or calculating the size of the string before hand, rather than having to reallocate, but this works fine and should be worth trying.

If this doesn't solve it we may have to analyse the compiled NDS file using Desmume Debugger.
Last edited by YoshiInAVoid on January 12th, 2014, 1:25 pm, edited 1 time in total.
YoshiInAVoid
Site Admin
 
Posts: 2111
Joined: December 30th, 2010, 11:53 am
Location: England

Re: Undefined opcode

Postby kevman323 » January 9th, 2014, 2:14 am

I solved the problem by declaring the two string variables, AString and LineString, in the global variables section of DSGM instead of in the code. I have no idea why it works now, but I guess DSGM handles a global string variable and "dim AString as string" differently.

I am not concerned about loading times, since the floor will be created at the start of each level, but I will look into implementing your solution if I need to change it in the future.

Thanks for all of your help
kevman323
 
Posts: 28
Joined: January 14th, 2013, 2:11 am


Return to Help

Who is online

Users browsing this forum: No registered users and 5 guests