Noob question thread

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.
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Noob question thread

Post by lillapojkenpåön » Tue Sep 17, 2019 8:29 am

Hello, I'm new to DC programming, installed DreamSDK, but when I try to compile and run the source it creates automaticly,
it says "The selected target is a Debug target, please select the Release target if you want to run the project"
What am I suppose to change?

Is there any super simple code examples that just generate a display and not much more? I just want to compile something and start playing with it and add stuff.

Thanks!
User avatar
ThePerfectK
DCEmu Freak
DCEmu Freak
Posts: 94
Joined: Thu Apr 27, 2006 10:15 am
Has liked: 6 times
Been liked: 13 times

Re: Noob question thread

Post by ThePerfectK » Tue Sep 17, 2019 5:23 pm

I don't use DreamSDK to develop with nor do I use code::blocks as my IDE so I might be wrong with the specifics here, but I can explain what that means regardless. Build targets describe a set of options your IDE uses when compiling and running your program. This includes environment variables, like #define flags you might use within your code as compile-time branches, as well as scripts to run during the building process. In the case above, it sounds like there are two target configurations provided with DreamSDK, one called debug, and one called release. You have code::blocks set to the debug target. Apparently, the release target includes a script which, I'm guessing, launches your application with redream after you compile it into an elf. You could probably manually launch your application through a command line, but that might be harder to do.

A quick google search says the place where you change the build target is here:

Image

Within whatever IDE you're using, you can usually define your own build targets in some sort of menu. Typically more fleshed out IDEs will come with templates to let you design your build target so you can more easily integrate scripts or select between them. For example, in QT Creator, my custom build targets:

Image

As for your question, I'm not sure where DreamSDK puts its KOS folder, but if you can find that, there's a folder inside called examples. "Hello" is just about the most simple project you can work with, try building that.
These users liked the author ThePerfectK for the post:
lillapojkenpåön
Still Thinking!~~
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Tue Sep 17, 2019 8:26 pm

Thank you! Can redream play the .elf? redream launches but just to a welcome screen,
in the DreamSDK manager under the emulator path I put the path to the .elf as argument, is that correct?

If I want a cdi file, do I have to do it manually with discjuggler?
User avatar
ThePerfectK
DCEmu Freak
DCEmu Freak
Posts: 94
Joined: Thu Apr 27, 2006 10:15 am
Has liked: 6 times
Been liked: 13 times

Re: Noob question thread

Post by ThePerfectK » Wed Sep 18, 2019 12:19 pm

lillapojkenpåön wrote:
Tue Sep 17, 2019 8:26 pm
Thank you! Can redream play the .elf? redream launches but just to a welcome screen,
in the DreamSDK manager under the emulator path I put the path to the .elf as argument, is that correct?

If I want a cdi file, do I have to do it manually with discjuggler?
No, Redream AFAIK cannot play elfs directly as you are asking, it seems to only be able to load cdi and gdi files. You can turn your elf into a cdi file using command line tools, but I don't use windows and thus don't really know what options exist there. You could setup something like cygwin or a virtual machine and install the kos toolchain in a unix-like environment and use them there, but I'm guessing that would be way too complex for you. If you do go that route, what you'll need to do is convert your elf into a binary, then scramble that binary as the Dreamcast reads mcd binaries out of order as a form of copy protection. Then turn that scrambled binary into a cdi file.

You can, however, use redream to load elf files through an emulated serial connection, but again, I have no idea how to set up something like that in windows. The gist is that you load dc-load-ser as a cdi file in redream, which was opened using command line options to create an emulated serial port, then communicate from your host PC through dc-tool-ser as though it were talking to a real dreamcast.

Again, I'm pretty sure the DreamSDK will do almost all of this for you in some way through it's release build target. Select that and it should produce something you can run in redream without having to fiddle with CLIs. Just checking -- you have read the documentation for DreamSDK, right?
These users liked the author ThePerfectK for the post:
lillapojkenpåön
Still Thinking!~~
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Wed Sep 18, 2019 9:52 pm

No I had not read it, I found some commands I'm suppose to enter in the DreamSDK shell

1 Converting the ELF file to a scrambled binary.
2 Generate the scrambled binary, usually called 1ST_READ.BIN.
3 Making a bootstrap file (usually called IP.BIN).
4 Making the selfboot image.

1
cd <your_program_dir>
mkdir cd_root
make
make dist
elf2bin <prog.elf>
Image
2
scramble <prog.bin> cd_root/1ST_READ.BIN
3
ipcreate -silent
4
makedisc <prog.cdi> cd_root IP.BIN [PROG_NAME]
Image

I will try it tomorrow and probably ask more questions.
User avatar
ThePerfectK
DCEmu Freak
DCEmu Freak
Posts: 94
Joined: Thu Apr 27, 2006 10:15 am
Has liked: 6 times
Been liked: 13 times

Re: Noob question thread

Post by ThePerfectK » Thu Sep 19, 2019 12:13 pm

Looks like you are well on your way, please keep the topic informed! Best of luck!

One other thing to note, iirc the "hello" example uses the debug font to display "hello world" on the screen. This font resides in the bios, and redream will hang at a black screen if the bios isn't present when you call the bios font command. So make sure you have a bios binary configured for redream.
These users liked the author ThePerfectK for the post:
lillapojkenpåön
Still Thinking!~~
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Thu Sep 19, 2019 1:53 pm

That probably explains why I only got a black screen on that one,
I'm just trying to draw a colored pixel on the screen now but vid_set_mode gives an error, indented or not,
and if I remove it it's a black screen in redream.

Code: Select all

#define PACK_PIXEL(r, g, b) ( ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3) )

#include <kos.h>
#include <stdio.h>

KOS_INIT_FLAGS(INIT_DEFAULT | INIT_MALLOCSTATS);
 vid_set_mode(DM_640x480, PM_RGB565);
  int x=1;
  int y=1;

/* Your program's main entry point */
int main(int argc, char **argv) {


 			vram_s[x + (y * 640)] = PACK_PIXEL(60, 30, 255);


    return 0;
}
User avatar
ThePerfectK
DCEmu Freak
DCEmu Freak
Posts: 94
Joined: Thu Apr 27, 2006 10:15 am
Has liked: 6 times
Been liked: 13 times

Re: Noob question thread

Post by ThePerfectK » Thu Sep 19, 2019 2:23 pm

Your kos init and vid mode code need to go inside main they are calls to be executed.

Also, your program doesn't loop, so it'll draw a pixel for one frame then end.

Try this:

Code: Select all

#define PACK_PIXEL(r, g, b) ( ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3) )

#include <kos.h>
#include <stdio.h>

int main(int argc, char **argv) {
	KOS_INIT_FLAGS(INIT_DEFAULT | INIT_MALLOCSTATS);
	vid_set_mode(DM_640x480, PM_RGB565);
	
	int x=1;
	int y=1;
	
	while(1)
	{
		vram_s[x + (y * 640)] = PACK_PIXEL(60, 30, 255);
	}

	return 0;
}
I'm not at my PC right now but that should do what you want it to do.

General tip, you really need to read the errors your compiler gives you, those are your clues on how to fix your code. If you don't understand the error it's given you, copy the error and google it. If the error includes some specific info about your program, i.e. it's saying there is an undefined variable in "your_program.c," where "your_program" is a name you came up with that you couldn't reasonably expect others to use, just omit that from your search results. You can find lots of people talking on forums and such about similar errors you are getting, which should help you understand how to fix it.
These users liked the author ThePerfectK for the post:
lillapojkenpåön
Still Thinking!~~
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Thu Sep 19, 2019 4:55 pm

Yes I do read them and google them.
kos init is before main in the codeblocks template when starting a new dreamcast project, and if I put it inside I get a warning
warning: unused variable '__kos_init_flags' [-Wunused-variable]
Are you sure? Seems weird if the template is wrong.
vid_set_mode obviously belonged there tho.

EDIT:
Wohoo got a 10x10 square! :)
User avatar
ThePerfectK
DCEmu Freak
DCEmu Freak
Posts: 94
Joined: Thu Apr 27, 2006 10:15 am
Has liked: 6 times
Been liked: 13 times

Re: Noob question thread

Post by ThePerfectK » Thu Sep 19, 2019 8:26 pm

Congrats on getting something drawn to the screen.

That warning is just saying you're not actually using the flags you define. That command is a macro which returns a variable that can be passed to KOS to setup the environment. What you are doing is directly manipulating the framebuffer, without working with KOS at all. You'll probably very quickly run into a wall, as drawing to the framebuffer like this is extremely slow. You'll eventually need to use KOS to more closely talk to the Dreamcast's video hardware, and when you do that you'll use the flags you defined to setup KOS. As you actually aren't using KOS, that's why the variable goes unused.
These users liked the author ThePerfectK for the post:
lillapojkenpåön
Still Thinking!~~
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Fri Sep 20, 2019 9:56 am

Thanks, I just noticed that the tutorial I'm looking at has stuff like

Code: Select all

if((x >= 0) && (x < 640) && (y >= 0) && (y < 480))
	vram_s[x + (y * 640)] = PACK_PIXEL(r, g, b);
but it never mentions x and y being anything other than regular integers I think, so why check if they are smaller than those big numbers?
I made a version with 16-bit integers that works (I think)
It's suppose to draw the 10x10 square in the nested loops, then move over 10 pixels to the right for the next frame, and when it reaches the right edge the y position increments by 10 so the next line is colored in, until the whole screen is blue.
It turns blue but I wanted to slow it down to see if it works as I think, but it doesn't, it colors half the screen, then the next half?

Code: Select all

#define PACK_PIXEL(r, g, b) ( ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3) )

#include <kos.h>
#include <stdio.h>

int main(void) {
     KOS_INIT_FLAGS(INIT_DEFAULT | INIT_MALLOCSTATS);
	 vid_set_mode(DM_640x480, PM_RGB565);

	uint16_t x;
	uint16_t y;

        int x2;
	int y2;

    x=0; y=0; x2=0; y2=0;
    uint16_t slowdown = 0; // 65535



	while(1) {
   for(x2 = 0; x2< 10; x2++)
   {
       for(y2 = 0; y2 <10; y2++)
       {
             vram_s[ (x + x2) + ((y + y2) * 640)] = PACK_PIXEL(0, 0, 255);
       }
   }

  slowdown++;
  if (slowdown<255) goto contin;
     slowdown=0;
     
  if (x<630) {x+=10;} else {x=0; y+=10;}

  if (y!=480) goto contin;
      y=0;


  contin:;
}



	return 0;
}

I started learning c++ when I downloaded DreamSDK if you're wondering how I can't get these basic things :)
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Fri Sep 20, 2019 2:22 pm

I've tried everything :( does the while loop loop once a frame?
User avatar
SiZiOUS
DC Developer
DC Developer
Posts: 386
Joined: Fri Mar 05, 2004 2:22 pm
Location: France
Has liked: 13 times
Been liked: 10 times
Contact:

Re: Noob question thread

Post by SiZiOUS » Mon Sep 23, 2019 7:03 am

lillapojkenpåön wrote:
Tue Sep 17, 2019 8:29 am
Hello, I'm new to DC programming, installed DreamSDK, but when I try to compile and run the source it creates automaticly,
it says "The selected target is a Debug target, please select the Release target if you want to run the project"
What am I suppose to change?
Just for information I explained this point here.

You will need either a Serial Coders Cable or a Broadband/LAN Adapter to run/debug the programs from the Code::Blocks IDE. Dreamcast emulators aren't supported yet. But you can make a selfboot disc with your program with the tutorial explained in the DreamSDK Help (Useful information and tutorials > How to release your Sega Dreamcast program) then run the produced disc image in the emulator.
These users liked the author SiZiOUS for the post:
lillapojkenpåön
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Tue Oct 01, 2019 10:22 pm

Ok, as I said I'm a noob, but now I know that the size of int and other types depends on the cpu and aren't 8 bits like I thought.
I gave it another try and now trying to control the square with the d-pad, but it moves at the speed of light and when it hits my boundary it goes another direction like a snake, do I need to slow down the ticks or is the code being read at 60 fps allready?
This is how i check the d-pad, excuse my formatting.

Code: Select all

    cont_state_t* controllerState = (cont_state_t*) maple_dev_status(controller);
    if (controllerState->buttons & CONT_DPAD_UP){
      if (y>0) {y-=1;}
    }

    if (controllerState->buttons & CONT_DPAD_DOWN){
      if (y<470) {y+=1;}
    }

    if (controllerState->buttons & CONT_DPAD_LEFT){
      if (x>0) {x-=1;}
    }

    if (controllerState->buttons & CONT_DPAD_RIGHT){
      if (x<630) {x+=1;}
    }
Full code:

Code: Select all

#include <kos.h>
#include <stdio.h>
//The first file is kos.h, which is necessary to access KallistiOS.
//The second is the standard input/output library that we use for console output.

#define PROJECT_NAME "newTry"



#define PACK_PIXEL(r, g, b) ( ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3) )


//#include <stdio.h>

/* Declaration of the romdisk
   You can access the files inside it by using the "/rd" mounting point. */
//extern uint8 romdisk[];
//KOS_INIT_ROMDISK(romdisk);

/* Your program's main entry point */
int main(int argc, char *argv[]) {

// The usual initialization
     KOS_INIT_FLAGS(INIT_DEFAULT | INIT_MALLOCSTATS);
	 vid_set_mode(DM_640x480, PM_RGB565);
	   maple_device_t* controller = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);

	  //init kos
 pvr_init_defaults(); //no output without this

	int x;
	int y;

    int x2;
	int y2;

     x2=0; y2=0;
     x=50; y=50;





	while(1) {



    cont_state_t* controllerState = (cont_state_t*) maple_dev_status(controller);
    if (controllerState->buttons & CONT_DPAD_UP){
      if (y>0){y-=1;}
    }

    if (controllerState->buttons & CONT_DPAD_DOWN){
      if (y<470){y+=1;}
    }

    if (controllerState->buttons & CONT_DPAD_LEFT){
      if (x>0){x-=1;}
    }

    if (controllerState->buttons & CONT_DPAD_RIGHT){
      if (x<630){x+=1;}
    }




   for(x2 = 0; x2< 10; x2++)
   {
       for(y2 = 0; y2 <10; y2++)
       {
             vram_s[ (x + x2) + ((y + y2) * 640)] = PACK_PIXEL(0, 0, 255);
       }
   }


} //main loop end



	return 0;
}
I want to start with making a simple 2D game, animated sprites, and a picture as background, If you know of any good tutorials, examples or libraries then please point me in the right direction. Would SDL be a good way? I read that something was wrong with it but it was an old comment and maybe it has been worked on?
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Wed Oct 02, 2019 5:56 am

nevermind the last question, I've read the forum for several hours and gonna try simulant, since I can't even get this square to do what I want I feel like that is the only logical next step :P
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Fri Oct 04, 2019 9:27 am

After googeling and searching this site for delay, timer, framerate, timer_ms_gettime64 and looking at
http://gamedev.allusion.net/docs/kos-2. ... 611d557a6e
and trying to find sources or examples that uses timer_ms_gettime64 to slow things down I found very little.
But I watched an SDL tutorial on youtube and just replaced the functions..

Code: Select all

  uint64 frameStart;
  int frameTime;

  const int FPS = 60;
  const int frameDelay = 1000 / FPS;


	while (1)
	{

	    frameStart = timer_ms_gettime64();

            //CODE

            frameTime = timer_ms_gettime64() - frameStart;

              if (frameDelay > frameTime) 
              {
              timer_spin_sleep(frameDelay - frameTime);
              }
         }
Is that a good way? I guess I would put..
pvr_wait_ready();
pvr_scene_begin();
pvr_scene_finish();
..after that? that makes my square dissapear so I removed it, but redream shows 60fps with or without my delay code that I don't even know if it's working, I just want my mainloop to be processed every 1/60th of a second and then draw the screen.
And what if I don't use pvr, is there some other way of saying it's time to draw the screen? or is timing the loop with the framerate all you have to do?
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Sat Oct 05, 2019 1:55 am

I start by placing the square at x 50 and y 50, it's suppose to move and change color but it's just one color and doesn't move..
bandicam 2019-10-05 08-22-37-427.jpg
..Until after 20 seconds when suddenly
bandicam 2019-10-05 08-23-00-668.jpg
and after another 20 seconds
bandicam 2019-10-05 08-23-24-057.jpg

It's like the processor is sleeping for 20 seconds, it's the same without vid_waitvbl(); and everything else I've tried, why?

Code: Select all

#define PACK_PIXEL(r,g,b) ( ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3) );

#include <kos.h>
 int x1,y1,x,y;

void drawSquare(unsigned short int c) {

     vid_waitvbl();


    if (x1<630) {x1=x1+10;} else {x1=0; y1=y1+10;} // MOVE THE SQUARE
    if (y1==480) {y1=0;} // MOVE THE SQUARE

	for(x=0;x<10;x++) {
		for(y=0;y<10;y++)

			vram_s[ (x1 + x) + ((y1 + y) * 640)] = c;


	}
}



int main(int argc, char **argv) {


	unsigned short int red=PACK_PIXEL(255,0,0);
	unsigned short int yellow=PACK_PIXEL(255,255,0);
	unsigned short int green=PACK_PIXEL(0,255,0);
	unsigned short int cyan=PACK_PIXEL(0,255,255);
	unsigned short int blue=PACK_PIXEL(0,0,255);
	unsigned short int magenta=PACK_PIXEL(255,0,255);

	KOS_INIT_FLAGS(INIT_DEFAULT);
    pvr_init_defaults();
    vid_set_mode(DM_640x480, PM_RGB565);

	while(1) {

		drawSquare(red);

		drawSquare(yellow);

		drawSquare(green);

		drawSquare(cyan);

		drawSquare(blue);

		drawSquare(magenta);
	}

	return 0;
}
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Sun Oct 06, 2019 12:18 am

I downloaded nullDC to get console output, and everything works perfect, so apparently I've been trying to solve something for 20 days that the redream devs should solve... And the timer/sleep code I posted is even more stable than using vid_waitvbl();

I'm a little confused now tho, since redream showed 60fps no matter what, I assumed vid_set_mode or something decided the framerate, but in nullDC if I don't use the delay routine or vid_waitvbl(); the framerate seems to be so fast it just shows 0, So which is right? What decides the framerate? me?
User avatar
ThePerfectK
DCEmu Freak
DCEmu Freak
Posts: 94
Joined: Thu Apr 27, 2006 10:15 am
Has liked: 6 times
Been liked: 13 times

Re: Noob question thread

Post by ThePerfectK » Sun Oct 06, 2019 10:00 pm

you have a fundamental misunderstanding of how video technology works for these kinds of old systems which is why you're having trouble with your project. I don't want to spend too much time retreading a topic I cover much more detail in a large guide I've been working on for years now (that's right around the corner) so forgive me for being succinct.

First up, you need to understand how old televisions worked, and how consoles interfaced with them back in the day. The television runs independently of the game console as a form of 1-way communication, there is no way for the console to tell the television it's ready to draw, it's the other way around. Televisions draw in a sweeping pattern as the raster gun paints the image on screen, from left to right, top to bottom. In the US, it used to do this 60 times per second, aka 60 hz. Once it reaches the bottom of the screen, it takes physical time to move back to the top left corner of the screen to begin drawing again. When it does this, it sends a signal to the console which is called VBlank to let it know it's moving back to the top corner of the screen.

Game consoles work in that they're a collection of multiple chips running in parallel, kind of like a bunch of tiny computers on one board. When you write and execute your code above, you are running it on the SH4 processor. The SH4 processor doesn't interface with the television directly. Rather, inside a chip called Holly is another core called the PVR2. Holly, and the PVR2, are what talk to the television, independent of the SH4. The SH4, and thus our code, talks to Holly and the PVR2 core through a small area of shared memory called VRAM.

The PVR2 has many dedicated buffers for programmers to talk to the television with. SDKs like KOS, Katana SDK, WinCE, and graphics APIs like SDL, GLdc, etc, all communicate through these buffers. That's what the graphics syntax of KOS actually is, in fact, it's a bunch of wrappers around hardware calls that obfuscates the nature of the code you're writing, to make it more human readable. When you do things like use the KOS command to wait for vblank, you're putting your code into a spinlock until it gets the signal that the raster gun is at the top of the frame, then continuing with your code the vblank wait. When you "wait for VBlank," you are making your SH4 code stop executing, and wait for the VBlank signal. The idea with this is that the code immediately following should be stuff that tells the PVR2 core how to draw, ideally through higher level commands.

What you're doing above, however, isn't this. See, one of the buffers exposed to the SH4 is a buffer that represents the ultimate resultant output onto the screen, called the frame buffer. That's what you're manipulating directly. Now, this isn't optimal for many reasons. For one, when you talk to the framebuffer like this, you ignore all sorts of controls regarding tv timing. Your SH4 code just runs as fast as it can, manipulating the framebuffer, without consideration regarding what the PVR2 core has to do with the television. Your code might begun running mid frame, or it might actually take too long to complete in one frame, or worse. It just runs, without consideration for the television. Additionally, talking directly to VRAM like this from the SH4 is super slow, that's one of the slowest busses on the Dreamcast. So even with very tight timing, you're very unlikely to be able to plot a lot of pixels on screen fast enough per frame, even if you could ensure that your drawing code started at the beginning of each frame. Direct Framebuffer manipulation like that is actually intended for things like the Debug font in the bios that the dreamcast uses, i.e. emergencies when you can't be sure what output options are available.

To talk a bit more about how framerates work, everything in an old console is timed to the television. Your frame loop almost always begins with a call to wait for VBlank to time it to the raster display. This is actually what causes framedrops. I don't want to get too into the weeds here regarding specifics, but that VBlank call can only occur if the system is ready, and it only occurs when the raster gun is at the top left corner of the television. If, for example, your code isn't ready when VBlank occurs, it'll continue doing what it did before and wait till the next vblank to move onto the next step you define. So if you can be ready every vblank, you get 60 fps. If you can only be ready every other vblank, then you get 60/2 = 30 fps. If you can only be ready every 3rd vblank, you get 60/3 = 20 fps. If you can only be ready every 4th vblank, you get 60/4 = 15 fps. And so forth. There is never a place where you define the framerate, framerate is defined by how your code interacts with the vblank period.

If you want to make a small game, I can't recommend enough you learn how to work with the PVR directly through KOS, or perhaps use an API like GLdc. All implementations of SDL are incomplete, and you'll run into a lot of brick walls with direct framebuffer manipulation, things which will just be out of your control (like screen tearing at best across the entire display).
These users liked the author ThePerfectK for the post (total 2):
lillapojkenpåönProtofall
Still Thinking!~~
lillapojkenpåön
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 16
Joined: Mon Sep 16, 2019 2:39 pm
Has liked: 7 times
Been liked: 0

Re: Noob question thread

Post by lillapojkenpåön » Mon Oct 07, 2019 12:54 am

ThePerfectK wrote:
Sun Oct 06, 2019 10:00 pm
First up, you need to understand how old televisions worked, and how consoles interfaced with them back in the day. The television runs independently of the game console as a form of 1-way communication, there is no way for the console to tell the television it's ready to draw, it's the other way around. Televisions draw in a sweeping pattern as the raster gun paints the image on screen, from left to right, top to bottom. In the US, it used to do this 60 times per second, aka 60 hz. Once it reaches the bottom of the screen, it takes physical time to move back to the top left corner of the screen to begin drawing again. When it does this, it sends a signal to the console which is called VBlank to let it know it's moving back to the top corner of the screen.
I do know how old televisions work, but not how the dreamcast works with it. I've programmed Atari 2600 games before, I think that's what's messing me up since then you program the entire kernel (vsync, vblank, how many scanlines, overscan, everything that generates the TV frame) yourself.

one scanline takes the TIA (2600's Holly/PVR2 I guess) 228 color clocks, 160 are used to draw the pixels on the screen, and 68 are consumed during the retrace/horizontal blank period.
The 6507 (2600's SH4) clock is derived from the TIA clock through a divide-by-three, so there are *exactly* 228/3 = 76 cycles of 6507 time per scanline.

Image

There's no vram or buffers. So you first program a kernel with 3 lines of vsync, followed by 37 of vblank period, followed by 192 (picture) followed by 30 (overscan). you set timers and loops that eat up time so that this is allways true to get a stable picture, then you put your logic in overscan and vblank, if the logic takes to long it doesn't go from 60 to 30 fps but instead the TV picture will jitter or roll.

So my way of thinking is to get a stable 60fps display first of all, and I don't know what instructions are inserted when I set video mode for example, it could wrap my logic with all the timers that's needed, that's what batari Basic does (high level atari 2600 compiler)
Or do something very small, It's hard for me to know.

But I think I'm getting an idea of what's going on now, I know this is slow and not recommended btw, but I gotta start somewhere and most tutorials are doing it this way. Since I'm just doing simple stuff like storing values directly into the frame buffer I don't need many more commands on how to display it, the stuff that's in there will be drawn 60fps, correct?

If I put the wait for vblank code at the end of my main loop, then my loop gets processed once every frame which is what I wanted, it just seemed like that couldn't be all compared to what I'm used to. when I start doing more complicated stuff I will need more commands on how to draw.

I really want to try the simulant engine, or GLdc atleast, but I'm not sure how to install it on windows, or how to only use GLdc? I think I read that it's a part of KOS now so do I have it available allready?

Thanks for the help! It clarified a lot!.
Hurry up with that guide!! :)
Post Reply