pixelmischief Posted February 20, 2015 Share Posted February 20, 2015 (edited) I'm reading the API reference for the graphics library that comes with Pure C and I'm a little confused. The "setpalette" function takes a color index from 0 to 15 and a hardware color value from 0 to 63. Does this mean that the Pure C libraries simply can not support the Falcon 256 color modes? Edited February 20, 2015 by pixelmischief Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted February 20, 2015 Author Share Posted February 20, 2015 Nevermind. Found the XBIOS calls and they provide an entry point for Falcon extensions. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted February 20, 2015 Author Share Posted February 20, 2015 Ok. I'm lost. I've tried XBIOS calls to set the screen mode. I've tried the BGI libraries to set the screen mode. I can't even get the damn screen to blank, let alone draw a box; the graphical equivalent of "Hello, World!". Are there any "purists" out there who can give me a quick boost with Pure C shipped libs? Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted February 20, 2015 Author Share Posted February 20, 2015 Well, I got a little further. The documentation is loopy, but I happened upon the preferred VsetScreen #define instead of Vsetmode. I can get the screen to blank, but it looks like getchar() is still preventing anything graphical from being possible. Quote Link to comment Share on other sites More sharing options...
calimero Posted February 20, 2015 Share Posted February 20, 2015 I have no experience with C but Mr. Pink from Reservoir Gods wrote C library especial for games called GODLIB! Many people praise it. Download it from here: http://rg.atari.org/source.htm There you will find simple examples Quote Link to comment Share on other sites More sharing options...
lp060 Posted February 20, 2015 Share Posted February 20, 2015 If you want to draw any gfx like boxes, circles, and such, first open a virtual work station with v_opnvwk(). You have to request a VDI handle before you can draw anything on the screen with the VDI gfx commands. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted February 20, 2015 Author Share Posted February 20, 2015 I have no experience with C but Mr. Pink from Reservoir Gods wrote C library especial for games called GODLIB! There is no question that the RG library is absolutely brilliant; and it is certainly my fallback position. The challenge with it, however, is that it is TOO brilliant. The learning curve to effectively use the RG library is as steep as learning to do simple things with native libraries. I'd like to crawl before I fly and the RG library is certainly the stuff that wings are made of. Also, using the RG library will mean accepting a great many assumptions concerning software design; like naming conventions and templating strategies. I'd like to take crack at developing something on my own terms, making the design decisions that I find elegant. Quote Link to comment Share on other sites More sharing options...
calimero Posted February 20, 2015 Share Posted February 20, 2015 ^ I only later saw another thread where you already did discus about GODLIB Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted February 20, 2015 Author Share Posted February 20, 2015 If you want to draw any gfx like boxes, circles, and such, first open a virtual work station with v_opnvwk(). You have to request a VDI handle before you can draw anything on the screen with the VDI gfx commands. Yes! Right before I went to bed last night, my brain lit on a pattern that I think will cover it. - create a mode integer from bit pattern - get a screen size (long) from getscreensize() - malloc() a drawing surface - malloc() a display surface - setscreen mode passing the drawing and display surfaces and mode integer - get a VDI handle - draw something in a while loop terminating on getchar() Does that sound about right? Quote Link to comment Share on other sites More sharing options...
lp060 Posted February 20, 2015 Share Posted February 20, 2015 (edited) Yes! Right before I went to bed last night, my brain lit on a pattern that I think will cover it. - create a mode integer from bit pattern - get a screen size (long) from getscreensize() - malloc() a drawing surface - malloc() a display surface - setscreen mode passing the drawing and display surfaces and mode integer - get a VDI handle - draw something in a while loop terminating on getchar() Does that sound about right? If you are attempting to do off-screen bitmaps + VDI calls you will have to use NVDI calls. The standard Atari VDI doesn't support off screen drawing. Alternately, you could draw everything yourself, as it looks like you are not attempting to write something GEM friendly anyway. Edited February 20, 2015 by lp060 Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted February 20, 2015 Author Share Posted February 20, 2015 If you are attempting to do off-screen bitmaps + VDI calls you will have to use NVDI calls. The standard Atari VDI doesn't support off screen drawing. Alternately, you could draw everything yourself, as it looks like you are not attempting to write something GEM friendly anyway. No, GEM friendliness is not an issue. The intended application is fullscreen 320x240x8BPP. Except for maybe some clearing routines, everything will be bitmapped graphics, not primitives. The reason my pseudo-code includes pointers to a drawing surface and a display surface is that the API for VsetScreen() explicitly requires each. Am I barking up the wrong tree on this? Quote Link to comment Share on other sites More sharing options...
lp060 Posted February 21, 2015 Share Posted February 21, 2015 Ah, I was not sure initially what you were trying to do, it looked like some sort of double buffering technique. Just allocate one buffer for your screen and point both VsetScreen() pointers at it. Then the standard VDI will be ok drawing to it. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted February 21, 2015 Author Share Posted February 21, 2015 Ah, I was not sure initially what you were trying to do, it looked like some sort of double buffering technique. Just allocate one buffer for your screen and point both VsetScreen() pointers at it. Then the standard VDI will be ok drawing to it. Ok, But doesn't that defeat the function of the blitter? I've never coded graphics on the Atari (obviously), but back in the day, DOS ModeX coding was done by drawing to a back buffer and then, on sync, blitting it to the display surface. When I read the prototype for VsetScreen(), my brain matched it up with the blitter concept and assumed that was what was needed. I am going to follow your suggestion now, just to try to get something on the screen. BUt could you think about and maybe explore the concept I discussed? Quote Link to comment Share on other sites More sharing options...
lp060 Posted February 21, 2015 Share Posted February 21, 2015 Ok, But doesn't that defeat the function of the blitter? I've never coded graphics on the Atari (obviously), but back in the day, DOS ModeX coding was done by drawing to a back buffer and then, on sync, blitting it to the display surface. When I read the prototype for VsetScreen(), my brain matched it up with the blitter concept and assumed that was what was needed. I am going to follow your suggestion now, just to try to get something on the screen. BUt could you think about and maybe explore the concept I discussed? Probably that will work, physical versus logical addresses. However, the VDI isn't exactly the most efficient way to get the gfx drawn. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted February 21, 2015 Author Share Posted February 21, 2015 Probably that will work, physical versus logical addresses. However, the VDI isn't exactly the most efficient way to get the gfx drawn. What is? Quote Link to comment Share on other sites More sharing options...
lp060 Posted February 21, 2015 Share Posted February 21, 2015 The Line-A interface, but that will limit you to modes with 16 colors or less. The other way would be to write your own drawing code in assembler. Quote Link to comment Share on other sites More sharing options...
dml Posted February 24, 2015 Share Posted February 24, 2015 Yes! Right before I went to bed last night, my brain lit on a pattern that I think will cover it. - create a mode integer from bit pattern - get a screen size (long) from getscreensize() - malloc() a drawing surface - malloc() a display surface - setscreen mode passing the drawing and display surfaces and mode integer - get a VDI handle - draw something in a while loop terminating on getchar() Does that sound about right? Yes this is approximately what you want, if you want exclusive control over the display / framebuffer on a Falcon. Particularly important that you allocate the right amount of space in advance of changing the displaymode otherwise you'll trash memory. You should make sure the buffers are aligned to at least 4 bytes (on an ST, it would need 256 bytes - I usually prefer it as a rule of thumb). 4 byte alignment probably happens automatically with malloc but easy enough to make sure... char *palloc = malloc(size+256); pframebuf= (char*)(((int)palloc + 255) & ~255); ... ... do something, then exit ... free(palloc); // not pframebuf! When creating the modecode from the bitpattern, it's usually sufficient (at least to start with) to just get the old mode and mask off the unwanted bits, combining new ones for resolution and colour depth. This helps keep things happy on both VGA and RGB since those flags remain untouched. Be aware that RGB and VGA modes can be different sizes (200 lines vs 240 lines) for what amounts to the same 'mode' and that other software (BlowUp, Videlity etc.) can change this as well - making it even more important to ask TOS how much memory needs alloc'd. Better not hardcode it to TOS resolution defaults - otherwise boom! You'll also need to save the old display info and put it back on exiting, particularly if you're using a real machine Painful to have to reboot just to open the compiler editor again You'll probably find it infinitely easier (more effort, but be less confused, and learn more) to just write directly to the framebuffer rather than go via the VDI, at least in chunky pixel truecolour mode. 1 word = 1 pixel. bytes per line = screen width * 2. easy! Bitplane modes are much more work to get used to coding for, but in the end its the same as an ST, just more planes... VDI isn't hard to use at all - but depending on what level you fiddle with display settings it may not understand what changes you've made and results can be wrong or just crash. Same situation if VDI is not initialized properly. Learning curve there... most coders using exclusive access to the screen on a Falcon for performance graphics won't bother with the VDI stuff at all... Hope that helps. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted February 24, 2015 Author Share Posted February 24, 2015 @dml: You are a motherf%&king rockstar. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted February 24, 2015 Author Share Posted February 24, 2015 You'll probably find it infinitely easier (more effort, but be less confused, and learn more) to just write directly to the framebuffer rather than go via the VDI, at least in chunky pixel truecolour mode. Yeah, I think this is definitely the route I want to take. So, just to verify, I pass a back buffer and a display buffer to the mode setter, draw to the back, and blit. And the blit will automatically copy the frame from the back to the display. Am I right? Quote Link to comment Share on other sites More sharing options...
dml Posted February 25, 2015 Share Posted February 25, 2015 Yeah, I think this is definitely the route I want to take. So, just to verify, I pass a back buffer and a display buffer to the mode setter, draw to the back, and blit. And the blit will automatically copy the frame from the back to the display. Am I right? You can blit (or use a memcpy() to do the same job) and it will work, but these are old machines and moving that much memory takes ages - has to be done physically by the CPU or blitter, over the same 16bit bus. The Ataris are better set up to perform a page flipping / surface flipping which is also a common method on PC in exclusive mode. Your physbase/logbase are your pages - the hardware shows you the contents of physbase and hides logbase. Change those pointers over and you'll see the other buffer. There are several ways to set the pointers - Vsetscreen is one of several XBios display calls available. Writing direct to the display HW registers is another way. Really logbase is only needed by TOS/VDI if you're using those to draw to the backbuffer. If not, only physbase matters. You can write to the backbuffer yourself without informing TOS. But beware things like printf which go through TOS and will corrupt memory if logbase and VDI are not aware of whats happening. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted February 25, 2015 Author Share Posted February 25, 2015 You can blit (or use a memcpy() to do the same job) and it will work, but these are old machines and moving that much memory takes ages - has to be done physically by the CPU or blitter, over the same 16bit bus. The Ataris are better set up to perform a page flipping / surface flipping which is also a common method on PC in exclusive mode. Your physbase/logbase are your pages - the hardware shows you the contents of physbase and hides logbase. Change those pointers over and you'll see the other buffer. There are several ways to set the pointers - Vsetscreen is one of several XBios display calls available. Writing direct to the display HW registers is another way. Really logbase is only needed by TOS/VDI if you're using those to draw to the backbuffer. If not, only physbase matters. You can write to the backbuffer yourself without informing TOS. But beware things like printf which go through TOS and will corrupt memory if logbase and VDI are not aware of whats happening. Aaaaaaah. So just keep swapping the pointers between physbase and logbase. Yes, ok. Thanks! Quote Link to comment Share on other sites More sharing options...
+poobah Posted February 27, 2015 Share Posted February 27, 2015 ... and don't try to paint the whole screen in one frame. you don't have enough time to do it. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted March 1, 2015 Author Share Posted March 1, 2015 (edited) I think I'm pretty close to the most rudimentary construct from which to begin working, but it's not there yet. Please look at the code below and how it crashes and offer me some pointers (pun most definitely intended). #include<stdio.h> #include<stdlib.h> #include<tos.h> #define VsetScreen(laddr,paddr,mode) xbios(5,laddr,paddr,3,mode) #define SCREEN_MODE_340X240X65536 276 void main() { int previousScreenMode; int *previousLogicalBase; int *previousPhysicalBase; long newScreenSize; int *newSharedBase; char pressedKey; int videoMemoryLocationOffset; previousLogicalBase = Logbase(); previousPhysicalBase = Physbase(); newScreenSize = VgetSize( SCREEN_MODE_340X240X65536 ); newSharedBase = malloc( newScreenSize ); previousScreenMode = VsetScreen( newSharedBase, newSharedBase, SCREEN_MODE_340X240X65536 ); for ( videoMemoryLocationOffset = 0 ; videoMemoryLocationOffset < newScreenSize ; ++videoMemoryLocationOffset ) { *( newSharedBase + videoMemoryLocationOffset ) = 255; } while ( ( pressedKey = getchar() ) != 'q' ) { Vsync(); } VsetScreen( previousLogicalBase, previousPhysicalBase, previousScreenMode ); } Edited March 1, 2015 by pixelmischief Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted March 1, 2015 Author Share Posted March 1, 2015 I laid down to go to sleep and immediately realized the problem. Please do not respond to this until I ask for assistance again. I want to take another crack at it. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted March 1, 2015 Author Share Posted March 1, 2015 (edited) Much, much, much better. This code sets each pixel location's color to whatever the offset iterator is (0 to 76800). Now I'm trying to figure out how to convert the RGB 5:6:5 bit format into a 16-bit integer. Any help would be hot. #include<stdio.h> #include<stdlib.h> #include<tos.h> #define VsetScreen(laddr,paddr,mode) xbios(5,laddr,paddr,3,mode) #define SCREEN_MODE_340X240X65536 276 void main() { int previousScreenMode; long *previousLogicalBase; long *previousPhysicalBase; long newScreenSize; int *newSharedBase; char pressedKey; long pixelCount; long currentPixelOffset; previousLogicalBase = Logbase(); previousPhysicalBase = Physbase(); newScreenSize = VgetSize( SCREEN_MODE_340X240X65536 ); newSharedBase = malloc( newScreenSize ); previousScreenMode = VsetScreen( newSharedBase, newSharedBase, SCREEN_MODE_340X240X65536 ); pixelCount = 76800; pressedKey = 0; while ( pressedKey != '\n' ) { for ( currentPixelOffset = 0 ; currentPixelOffset < pixelCount ; ++currentPixelOffset ) { *( newSharedBase + currentPixelOffset ) = currentPixelOffset; } Vsync(); pressedKey = getchar(); } VsetScreen( previousLogicalBase, previousPhysicalBase, previousScreenMode ); } Edited March 1, 2015 by pixelmischief Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.