Project Works on Emulators; Black Screen on Hardware

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
Post Reply
KingCrazy
DCEmu Fast Newbie
DCEmu Fast Newbie
Posts: 24
Joined: Sat Aug 04, 2018 11:36 am

Project Works on Emulators; Black Screen on Hardware

Post by KingCrazy » Sat Sep 22, 2018 12:21 pm

I finally got my hands on an actual Dreamcast! Let me preface this issue by saying that the Dreamcast is 100% functional. I play games on it all the time. There's no defects with the Dreamcast itself, just my code somewhere along the line.

I'm currently just trying to get my sample project to display on my Dreamcast. The project mounts a Romdisk, loads in some MD2 files, and then draws the objects on the screen, allowing the user to provide input to move the camera around.

Everything works perfectly in NullDC and Demul. However, once I started trying it on real hardware, I started getting issues. The disc never really loads. It goes past the Dreamcast boot screen, the "SEGA" screen, and then I get a black screen. I've tried burning other sample projects, such as the PNG sample and the Lerabot01 GLdc sample, and both of those work perfectly, it's just my project that won't load.

I can't show all my code, because it's scattered between a ton of different files, but I've narrowed it down to loading the files. It's not the Romdisk, it's not OpenGL/GLdc, it's somewhere in my load functions. What I do is load in the MD2 file into memory, then convert that over to another generic "model" object I've created, and render that on the screen (this way I can create support for multiple model file types in the future, if I so choose, and draw from my generic model struct instead of having to write rendering algorithms for each type of file).

Before loading anything in, though, I first init OpenGL. During that, I set the screen to grey. I noticed if I comment out my loading functions, the screen will turn grey on the Dreamcast hardware. However, if I keep the loading functions, the screen will remain black and nothing will appear on the screen.

Please keep in mind I'm not going for optimization right now, I'm just trying to get this to work. I know my code is a nightmare.

Reading the MD2 file:

Code: Select all

void FileManager::ReadMD2(const char* path, model_t* m){
  FILE* fp;
  int i;

  md2_model_t* mdl = (md2_model_t*)malloc(sizeof(md2_model_t));

  printf("Opening file: %s\n", path);

  fp = fopen(path,"rb");
  if (!fp){
    printf("Error: Couldn't open %s\n",path);
    return;
  }

  fread(&mdl->header, 1, sizeof(md2_header_t), fp);
  if ((mdl->header.ident != 844121161) || (mdl->header.version != 8)){
    printf("Error: Bad version or identifier\n");
    fclose(fp);
    return;
  }

  mdl->skins = (md2_skin_t*) malloc(sizeof(md2_skin_t)*mdl->header.num_skins);
  mdl->texcoords = (md2_texCoord_t*) malloc(sizeof(md2_texCoord_t)*mdl->header.num_st);
  mdl->tris = (md2_triangle_t*) malloc(sizeof(md2_triangle_t)*mdl->header.num_tris);
  mdl->frames = (md2_frame_t*) malloc(sizeof(md2_frame_t)*mdl->header.num_frames);
  mdl->glcmds = (int*)malloc(sizeof(int)*mdl->header.num_glcmds);

  fseek(fp, mdl->header.offset_skins, SEEK_SET);
  fread (mdl->skins, sizeof(md2_skin_t), mdl->header.num_skins, fp);

  fseek(fp, mdl->header.offset_st, SEEK_SET);
  fread (mdl->texcoords,sizeof(md2_texCoord_t),mdl->header.num_st, fp);

  fseek(fp, mdl->header.offset_tris,SEEK_SET);
  fread(mdl->tris,sizeof(md2_triangle_t),mdl->header.num_tris,fp);

  fseek(fp, mdl->header.offset_glcmds,SEEK_SET);
  fread(mdl->glcmds, sizeof(int),mdl->header.num_glcmds,fp);

  fseek(fp,mdl->header.offset_frames,SEEK_SET);
  for(i=0;i<mdl->header.num_frames;i++){
    mdl->frames[i].verts = (md2_vertex_t*)malloc(sizeof(md2_vertex_t) * mdl->header.num_vertices);

    fread(&mdl->frames[i].scale,sizeof(Vector3f), 1, fp);
    fread(&mdl->frames[i].translate,sizeof(Vector3f),1, fp);
    fread(mdl->frames[i].name, sizeof(char),16, fp);
    fread(mdl->frames[i].verts,sizeof(md2_vertex_t),mdl->header.num_vertices,fp);
  }
    fclose (fp);
  fp = NULL;

  ConvertMD2Data(m, mdl);

  UnloadMD2(mdl);
}
Converting the MD2 data to my generic model struct:

Code: Select all

void FileManager::ConvertMD2Data(model_t* m, md2_model_t* mdl){
  int i;

  printf("Starting conversion\n");
  md2_frame_t* tFrame = &mdl->frames[0];

  m->num_verts = mdl->header.num_vertices;
  m->num_uvs = mdl->header.num_st;
  m->num_faces = mdl->header.num_tris;

  m->verts = (Vector3f*) malloc (sizeof(Vector3f) * m->num_verts);
  m->uvs = (uv_t*) malloc (sizeof(uv_t) * m->num_uvs);
  m->faces = (face_t*) malloc (sizeof(face_t) * m->num_faces);

  for (i = 0; i < m->num_verts; i++){
    m->verts[i].x = (tFrame->scale.x * (float) tFrame->verts[i].v[0]) + tFrame->translate.x;
    m->verts[i].y = (tFrame->scale.y * (float) tFrame->verts[i].v[1]) + tFrame->translate.y;
    m->verts[i].z = (tFrame->scale.z * (float) tFrame->verts[i].v[2]) + tFrame->translate.z;
  }

  printf("Verts converted\n");

  //free(tFrame->verts);

  for (i = 0; i < m->num_uvs; i++){
    m->uvs[i].u = (GLfloat) mdl->texcoords[i].s / (GLfloat) (mdl->header.skinwidth);
    m->uvs[i].v = (GLfloat) mdl->texcoords[i].t / (GLfloat) (mdl->header.skinheight);
    //printf("U: %f\n V: %f\n", m->uvs[i].u, m->uvs[i].v);
  }

  printf("UVs converted\n");

  //free (mdl->texcoords);

  for (i = 0; i < m->num_faces; i++){
    m->faces[i].vertIndex[0] = mdl->tris[i].vertex[0];
    m->faces[i].vertIndex[1] = mdl->tris[i].vertex[1];
    m->faces[i].vertIndex[2] = mdl->tris[i].vertex[2];

    m->faces[i].uvIndex[0] = mdl->tris[i].st[0];
    m->faces[i].uvIndex[1] = mdl->tris[i].st[1];
    m->faces[i].uvIndex[2] = mdl->tris[i].st[2];
  }

  printf("Faces converted\n");

  m->material = (material_t*) malloc(sizeof(material_t));

  m->material->filename = mdl->skins[0].name;
  m->material->uOffset = 0.0f;
  m->material->vOffset = 0.0f;

  //if (m->material->filename)
    //LoadBMP(m->material->filename,&m->material->texId);
}
Unloading the MD2 data:

Code: Select all

void FileManager::UnloadMD2(md2_model_t* mdl){
  int i;

  if (mdl->skins)
    free(mdl->skins);

  if (mdl->tris)
    free(mdl->tris);

  if (mdl->texcoords)
    free(mdl->texcoords);

  if (mdl->frames){
    for (i=0;i<mdl->header.num_frames;i++)
      if (mdl->frames[i].verts)
        free(mdl->frames[i].verts);
    free(mdl->frames);
  }

  if (mdl->glcmds)
    free(mdl->glcmds);

  if (mdl->indices)
    free(mdl->indices);

  if (mdl)
    free(mdl);
}
I have no clue why this isn't working on hardware. Has anyone else ever had this happen to them? And is there any way I could get more feedback from the hardware as to what went wrong?

Thanks!
User avatar
mankrip
DCEmu Ex-Mod
DCEmu Ex-Mod
Posts: 3696
Joined: Sun Nov 04, 2001 5:12 pm
Contact:

Re: Project Works on Emulators; Black Screen on Hardware

Post by mankrip » Sat Sep 22, 2018 8:23 pm

Did you scramble the binary before making the CD image?

The DC only boots scrambled binaries. Boot discs such as DCHakker and emulators can boot both scrambled and unscrambled binaries.
Ph'nglui mglw'nafh mankrip Hell's end wgah'nagl fhtagn.
==-=-=-=-=-=-=-=-=-=-==
Dev blog / Twitter / YouTube
Image
KingCrazy
DCEmu Fast Newbie
DCEmu Fast Newbie
Posts: 24
Joined: Sat Aug 04, 2018 11:36 am

Re: Project Works on Emulators; Black Screen on Hardware

Post by KingCrazy » Sat Sep 22, 2018 8:48 pm

I'm pretty certain the binary is scrambled. As I said: the project boots on hardware if I remove the code that loads in the 3D models. I can tell because the screen will turn grey, indicating that OpenGL has initialized, since I'm clearing the screen and setting it to grey when I initialize OpenGL. If I keep the model loading code in, the hardware will stay on a black screen.

Also, I built the PNG and Lerabot01 GLdc binaries the exact same way that I built my own project, and both of those worked.
tonma
DCEmu Freak
DCEmu Freak
Posts: 82
Joined: Thu Mar 10, 2016 7:14 am

Re: Project Works on Emulators; Black Screen on Hardware

Post by tonma » Sun Sep 23, 2018 2:20 am

Can you try adding this to see if something is on screen : :
bfont_draw_str(vram_s + 32, 640, 0, "Hello");
You have printf value in your loading function. If you can't see this debug info on real hardware, can you put the value in temporary variable and show them with bfont_draw_str... Maybe it's just a file error.
KingCrazy
DCEmu Fast Newbie
DCEmu Fast Newbie
Posts: 24
Joined: Sat Aug 04, 2018 11:36 am

Re: Project Works on Emulators; Black Screen on Hardware

Post by KingCrazy » Sun Sep 23, 2018 5:46 pm

I put that bfont_draw_str right after I load files, as well as during the main loop, and neither of those showed up. They show up on emulators, and again: everything runs fine on both NullDC and Demul, but on actual hardware it never reaches that point.

I'll test this more thoroughly when/if I can get my hands on a coder's cable of some sort, or an SD card reader. Right now burning discs for each test isn't really an efficient method haha
User avatar
mankrip
DCEmu Ex-Mod
DCEmu Ex-Mod
Posts: 3696
Joined: Sun Nov 04, 2001 5:12 pm
Contact:

Re: Project Works on Emulators; Black Screen on Hardware

Post by mankrip » Mon Sep 24, 2018 2:19 pm

You could try outputting debug messages to a VMU save file.
Ph'nglui mglw'nafh mankrip Hell's end wgah'nagl fhtagn.
==-=-=-=-=-=-=-=-=-=-==
Dev blog / Twitter / YouTube
Image
User avatar
lerabot
Insane DCEmu
Insane DCEmu
Posts: 112
Joined: Sun Nov 01, 2015 8:25 pm

Re: Project Works on Emulators; Black Screen on Hardware

Post by lerabot » Thu Sep 27, 2018 9:55 am

JohnWick7 wrote:
Thu Sep 27, 2018 12:11 am
As I'm looking for information on Hardware stays fit
Beautiful.

Also OP, I was wondering, where are you loading the file from? Romdisk? CD? And could you try to run your loader fonction without the Convert and Unload function.
KingCrazy
DCEmu Fast Newbie
DCEmu Fast Newbie
Posts: 24
Joined: Sat Aug 04, 2018 11:36 am

Re: Project Works on Emulators; Black Screen on Hardware

Post by KingCrazy » Thu Sep 27, 2018 3:49 pm

lerabot wrote:
Thu Sep 27, 2018 9:55 am
JohnWick7 wrote:
Thu Sep 27, 2018 12:11 am
As I'm looking for information on Hardware stays fit
Beautiful.

Also OP, I was wondering, where are you loading the file from? Romdisk? CD? And could you try to run your loader fonction without the Convert and Unload function.
Romdisk! I'm actually using your tutorial for loading files from Romdisk, so I'm compressing the Romdisk as well. I've tried without any compression, but the result is the same. As I've said before, everything loads fine on emulator, so it should read the data correctly. I was going to try loading some vertices from a simple text file and see if I get the same result.

I could definitely try to remove the convert and unload functions next. Like I said, I don't currently have a coder's cable so my only way of testing is to re-burn a disk every time. Once I get my hands on a coder's cable of some fashion, I'll be able to get more concrete answers on what I've tested and what I haven't! Hopefully I should be able to put one together within the coming week or two.

Thanks for all the suggestions so far, everyone!
KingCrazy
DCEmu Fast Newbie
DCEmu Fast Newbie
Posts: 24
Joined: Sat Aug 04, 2018 11:36 am

Re: Project Works on Emulators; Black Screen on Hardware

Post by KingCrazy » Tue Oct 09, 2018 1:32 am

Finally got my hands on a homemade coder's cable and figured out the problem.
It was in my unload code.

When I ran the code via serial adapter, I got this error:

Code: Select all

Unhandled exception: PC 8c034ab6, code 1, evt 00e0
	R0-R7: 00002ed0 8c034aa0 0001ffff 8c08f94c fffffff7 8cffff57 8c103348 00000028
	R8-R15 8c08f918 8c0495e0 ffffffff 8c0354c0 8c1032e8 8c0ac98c 8c013bc0 8cffff70
	SR 40000100 PR 8c0354ec
Stack Trace: frame pointers not enabled!
kernel panic: unhandled IRQ/Exception
arch: aborting the system
Figured it was probably trying to free memory that it wasn't supposed to, lo-and-behold:

Code: Select all

if (mdl->indices)
    free(mdl->indices);
Guess checking if something is allocated doesn't work that way I was thinking it does, haha. Forgot I stopped allocating mdl->indices awhile ago when I gave up on trying to render using indices.
User avatar
lerabot
Insane DCEmu
Insane DCEmu
Posts: 112
Joined: Sun Nov 01, 2015 8:25 pm

Re: Project Works on Emulators; Black Screen on Hardware

Post by lerabot » Tue Oct 09, 2018 1:05 pm

Aaahh yeah, that good old null pointer issue.

Glad you figured that out!
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5357
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Contact:

Re: Project Works on Emulators; Black Screen on Hardware

Post by BlueCrab » Tue Oct 09, 2018 1:29 pm

Memory on real hardware (outside of your .text, .data, .rodata, and .bss sections) isn't initialized when the program starts. Emulators usually do start with memory completely zeroed out, which is why that would work out fine on an emulator but not on the real hardware.
User avatar
lerabot
Insane DCEmu
Insane DCEmu
Posts: 112
Joined: Sun Nov 01, 2015 8:25 pm

Re: Project Works on Emulators; Black Screen on Hardware

Post by lerabot » Wed Oct 10, 2018 10:36 am

That's good to know Bluecrab!
KingCrazy
DCEmu Fast Newbie
DCEmu Fast Newbie
Posts: 24
Joined: Sat Aug 04, 2018 11:36 am

Re: Project Works on Emulators; Black Screen on Hardware

Post by KingCrazy » Wed Oct 10, 2018 3:27 pm

BlueCrab wrote:
Tue Oct 09, 2018 1:29 pm
Memory on real hardware (outside of your .text, .data, .rodata, and .bss sections) isn't initialized when the program starts. Emulators usually do start with memory completely zeroed out, which is why that would work out fine on an emulator but not on the real hardware.
Ohh, gotchya! That makes a lot of sense as to why things weren't working, haha. Thank you very much! That's very useful to know for the future.
Post Reply