[NXC] SCR_File_Lib for game makers!

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

[NXC] SCR_File_Lib for game makers!

Post by muntoo »

Has anyone ever tried my SCR_File_Lib? Part of it allows you to draw on a buffer (using the native drawing primitives API!), then copy that buffer onto the screen. The other part allows you to save what's on the screen to a file (described here).

You can use it to draw frames very "smoothly" in your games. The buffer to screen copying function (DisplayScreenMem(buffer);) is pretty fast - only 22ms/render. It'll take 22% of the processing time in your 10FPS game, but it's worth it, IMHO. I'll look at making it faster with my newly acquired NBC skills. :)
EDIT: Nevermind, Spiller's idea is much easier, faster, and versatile.

Here's the repository.

If you have any questions (you don't understand how to use it), just ask! :)
Last edited by muntoo on 24 Jul 2011, 03:37, edited 5 times in total.
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
nxtboyiii
Posts: 366
Joined: 02 Oct 2010, 07:08
Location: Everywhere

Re: [NXC] SCR_File_Lib for game makers!

Post by nxtboyiii »

Yes!
Thanks muntoo!
Could you possibly make a brief tutorial on it?

EDIT: What would we use this in games for?

Thanks, and have a nice day,
nxtboy III
Thanks, and have a nice day,
nxtboy III

programnxt.com
spillerrec
Posts: 358
Joined: 01 Oct 2010, 06:37
Location: Denmark
Contact:

Re: [NXC] SCR_File_Lib for game makers!

Post by spillerrec »

It is a pretty neat way of making a buffer, however those inline functions will add a lot of overhead...

I haven't played around with it that much, but this seems to do the same:

Code: Select all

task main(){
   ClearScreen();
   
   Wait(20);
   SetDisplayFlags( DISPLAY_REFRESH_DISABLED );
   LineOut(0,0,10,10);
   Wait( 2000 );
   SetDisplayFlags( DISPLAY_ON | DISPLAY_REFRESH );

   Wait(20);
   SetDisplayFlags( DISPLAY_REFRESH_DISABLED );
   LineOut(10,10,20,0);
   Wait( 2000 );
   SetDisplayFlags( DISPLAY_ON | DISPLAY_REFRESH );

   for(;;);
}
I have currently only used it in NXT RPG which didn't really have that much flicker anyway... While making that test program I found out that you should wait a little before disabling the display, as it might stop the display before refreshing the latest changes.
My blog: http://spillerrec.dk/category/lego/
RICcreator, an alternative to nxtRICeditV2: http://riccreator.sourceforge.net/
nxtboyiii
Posts: 366
Joined: 02 Oct 2010, 07:08
Location: Everywhere

Re: [NXC] SCR_File_Lib for game makers!

Post by nxtboyiii »

Wow! That is really good! That is neat! Thanks!
Thanks, and have a nice day,
nxtboy III

programnxt.com
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

Re: [NXC] SCR_File_Lib for game makers!

Post by muntoo »

nxtboyiii wrote:Could you possibly make a brief tutorial on it?

EDIT: What would we use this in games for?
OK, forget what I said about the games, because Spiller's example does the "same thing" but better (thanks Spiller!): change the screen memory, but only copy it to the real screen once you tell it to.

What I was talking about earlier:

Code: Select all

byte buffer[];
ArrayInit(buffer, 0, 800);

// PointOut(99, 63, DRAW_OPT_NORMAL);
DrawPointScreenMem(ScreenMem, 99, 63, DRAW_OPT_NORMAL);

// Display buffer on screen.
DisplayScreenMem(buffer);
Unfortunately, last I checked (a year ago), you can't use DrawGraphicScreenMem(), DrawFontTextScreenMem(), or anything RIC-file-related.

Actual point of SCR_File_Lib
Of course, my SCR_File_Lib has other abilities too - you can save what's on the screen to a file:

Code: Select all

// Read NXT screen memory into buffer.
GetScreenMem(buffer);

// Save buffer into test.scrmem file.
SaveSCRMEM("test.scrmem", buffer);
And open the file and draw on the screen again!:

Code: Select all

// Read test.scrmem file into buffer.
OpenSCRMEM("test.scrmem", buffer);

// Display buffer on screen.
DisplayScreenMem(buffer);
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
spillerrec
Posts: 358
Joined: 01 Oct 2010, 06:37
Location: Denmark
Contact:

Re: [NXC] SCR_File_Lib for game makers!

Post by spillerrec »

Why does GetScreenMen and DisplayScreenMen use loops? This seems to work just as well in your demo program:

Code: Select all

#define GetScreenMem( ScreenMem ) ArrayInit(ScreenMem, 0, 800); GetDisplayNormal(0, TEXTLINE_1, 800, ScreenMem);
#define DisplayScreenMem( ScreenMem ) SetDisplayNormal(0, TEXTLINE_1, 800, ScreenMem);
I'm not sure if the memory structure is the same but that should only affect some of your file functions.
(I do just now realize that GetScreenMem() was never used in your demo program...)

You could use a structure like this instead:

Code: Select all

struct screen_mem{
   byte buffer[];
   unsigned long display_add;
   unsigned long buffer_add;
and then do

Code: Select all

#define DrawScreenMem(ScreenMem, FunctionName, args) { \
	SetDisplayDisplay( ScreenMem.buffer_add ); \
	FunctionName(args); \
	SetDisplayDisplay( ScreenMem.display_add ); \
}
(Does the "args" part work btw, shouldn't it be "..."?)
Use a init function to set display_add and buffer_add.

DisplayScreenMem is done by syscall and all parameters are therefore contained in a struct. I have noticed though that it appears that syscall doesn't check if the members of the struct is in the correct type. I could make SysRandom() use a struct which contained a unsigned word instead of a signed, automatically casting the variable.
I have absolutely no idea, but I could imagine that it might not check the amount of members. Or rather, I hope it does not. (I haven't yet to test it.)
Consider the SetDisplayNormal struct:

Code: Select all

__IOMWBIArgs_def	struct
Result	sbyte
ModuleID	dword
Offset	word
Buffer	byte[]
__IOMWBIArgs_def	ends
ModuleID and Offset are constant for this function. What if we could merge this with our earlier ScreenMem structure?

Code: Select all

struct ScreenMem{
   byte Result;
   long ModuleID;
   int Offset;
   byte Buffer[];
   unsigned long display_add;
   unsigned long buffer_add;
};
This is surely pure speculation but if it doesn't perform a check on the amount of members (and therefore doesn't reject our struct) it should never notice our two extra members and thus work exactly like we would expect. However we don't need to copy the buffer into the other struct and we keep everything nicely contained so it is easy to use multiple buffers.
My blog: http://spillerrec.dk/category/lego/
RICcreator, an alternative to nxtRICeditV2: http://riccreator.sourceforge.net/
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

Re: [NXC] SCR_File_Lib for game makers!

Post by muntoo »

Oddly, this causes my program to crash in some cases:

Code: Select all

inline void GetScreenMem(byte &ScreenMem[])
{
    ArrayInit(ScreenMem, 0, 800);
    GetDisplayNormal(0, 0, 800, ScreenMem);
}
But the SetDisplayNormal(0, 0, 800, ScreenMem); works fine. (It's >50% faster. :))


Regarding the ..., look here.
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
nxtboyiii
Posts: 366
Joined: 02 Oct 2010, 07:08
Location: Everywhere

Re: [NXC] SCR_File_Lib for game makers!

Post by nxtboyiii »

Thank you so much muntoo!
This helps me a lot for my games. :)
Thanks, and have a nice day,
nxtboy III

programnxt.com
nxtboyiii
Posts: 366
Joined: 02 Oct 2010, 07:08
Location: Everywhere

Re: [NXC] SCR_File_Lib for game makers!

Post by nxtboyiii »

Can I have multiple Screenmem's? What would be their memory address?
Thanks, and have a nice day,
nxtboy III

programnxt.com
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: [NXC] SCR_File_Lib for game makers!

Post by mattallen37 »

You can grab and place data from and to the real screen buffer, so yes you could have multiple screens. Each screen is 800 bytes, so according to RAM limits, you could have up to about 40 screens (if you didn't use RAM for much of anything else).
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest