+CyranoJ Posted March 3, 2015 Share Posted March 3, 2015 16bitpixel = (RED<<11 | GREEN<< 6 | BLUE) Quote Link to comment Share on other sites More sharing options...
dml Posted March 3, 2015 Share Posted March 3, 2015 On Falcon the full pixel format is 5:6:5 or %RRRRRGGG:GGGBBBBB with << shifts of 11, 5, 0 respectively. But as CyranoJ indicates, the low green bit is often cleared e.g. %RRRRRGGG:GG0BBBBB because its inconvenient for realtime stuff, and can make images look muddy. In this case you can use consistent 5-bits per terms for RGB, with << shifts of 11, 6, 0 respectively. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted March 3, 2015 Author Share Posted March 3, 2015 @CyranoJ and dml: This is the key that fits the lock. Awesome. Thank you so much. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted March 6, 2015 Author Share Posted March 6, 2015 (edited) The desired effect is to paint a line down the left side of the screen. Why does this thing crash at x = 170 (or thereabouts) #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 #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 int getColor ( int R, int G, int B ); void main() { int previousScreenMode; void * previousLogicalBase; void * previousPhysicalBase; size_t newScreenSize; int * newSharedBase; char pressedKey = 0; int x; previousLogicalBase = Logbase(); previousPhysicalBase = Physbase(); newScreenSize = VgetSize( SCREEN_MODE_340X240X65536 ); newSharedBase = malloc( newScreenSize ); previousScreenMode = VsetScreen( newSharedBase, newSharedBase, SCREEN_MODE_340X240X65536 ); while ( pressedKey != '\n' ) { for ( x = 0 ; x < SCREEN_HEIGHT ; x++ ) { * ( newSharedBase + ( SCREEN_WIDTH * x ) ) = getColor( 128, 128, 128 ); } pressedKey = getchar(); Vsync(); } VsetScreen( previousLogicalBase, previousPhysicalBase, previousScreenMode ); } int getColor ( int R, int G, int B ) { return ( ( R << 11 ) | ( G << 6 ) | B ); } Edited March 6, 2015 by pixelmischief Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted March 6, 2015 Author Share Posted March 6, 2015 OK, I've figured out, at least partially, what's going wrong. I took the mode integer off a wiki page that said it was for 320x240x65535. When I pass that same integer into VgetSize(), I get back 153600, which makes sense: 320*240*16bits. But when I call VsetScreen() with the same mode integer, the Falcon actually sets the display to 640x480. Any ideas? Quote Link to comment Share on other sites More sharing options...
danwinslow Posted March 6, 2015 Share Posted March 6, 2015 I'd probably investigate the header files to find out exactly what the constants you are using are, and then research what those values would mean to VsetScreen. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted March 6, 2015 Author Share Posted March 6, 2015 All the constants are set by me. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted March 7, 2015 Author Share Posted March 7, 2015 (edited) There were several problems and, embarassingly, they have to do with the fact that I haven't written anything in C for years. Here's a version that works, with slightly different functionality. The lessons are: 1. Trust the API. If it says pointer to void, pointer to void 2. Cast your constants. #define does not infer type 3. Remember the limits on datatypes. An int cannot hold the product of 320 and 240 #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 #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 int getColor ( int R, int G, int B ); void main() { int previousScreenMode; void * previousLogicalBase; void * previousPhysicalBase; size_t newScreenSize; void * newSharedBase; char pressedKey = 0; long x; previousLogicalBase = Logbase(); previousPhysicalBase = Physbase(); newScreenSize = VgetSize( SCREEN_MODE_340X240X65536 ); newSharedBase = malloc( newScreenSize ); previousScreenMode = VsetScreen( newSharedBase, newSharedBase, SCREEN_MODE_340X240X65536 ); while ( pressedKey != '\n' ) { for ( x = 0 ; x < (long)SCREEN_WIDTH * (long)SCREEN_HEIGHT ; x++ ) { *((int*)newSharedBase + x ) = getColor( 255, 0, 0 ); } pressedKey = getchar(); Vsync(); } VsetScreen( previousLogicalBase, previousPhysicalBase, previousScreenMode ); } int getColor ( int R, int G, int B ) { return ( ( R << 11 ) | ( G << 6 ) | B ); } Edited March 7, 2015 by pixelmischief Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted March 7, 2015 Author Share Posted March 7, 2015 Next step: Implement page flipping. I seem to be able to create a pair of surfaces and swap their pointers, but the desired effect of a fully drawn screen just "popping" into view is not happening. I still see drawing. Please review and offer recommendations. #include<stdio.h> #include<stdlib.h> #include<tos.h> #include<ext.h> #define VsetScreen(laddr,paddr,mode) xbios(5,laddr,paddr,3,mode) #define SCREEN_MODE_340X240X65536 276 #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 int getColor ( int R, int G, int B ); void main() { int previousScreenMode; void * previousLogicalBase; void * previousPhysicalBase; size_t newScreenSize; void * frontBuffer; void * backBuffer; void * swapBuffer; char pressedKey = 0; long pixelOffset; previousLogicalBase = Logbase(); previousPhysicalBase = Physbase(); newScreenSize = VgetSize( SCREEN_MODE_340X240X65536 ); frontBuffer = malloc( newScreenSize ); backBuffer = malloc( newScreenSize ); previousScreenMode = VsetScreen( backBuffer, frontBuffer, (int)SCREEN_MODE_340X240X65536 ); while ( !kbhit() ) { for ( pixelOffset = 0 ; pixelOffset < (long)SCREEN_WIDTH * (long)SCREEN_HEIGHT ; pixelOffset++ ) { * ( ( int * ) backBuffer + pixelOffset ) = getColor( 255, 0, 0 ); } Vsync(); swapBuffer = frontBuffer; frontBuffer = backBuffer; backBuffer = swapBuffer; } VsetScreen( previousLogicalBase, previousPhysicalBase, previousScreenMode ); } int getColor ( int R, int G, int B ) { return ( ( R << 11 ) | ( G << 6 ) | B ); } Quote Link to comment Share on other sites More sharing options...
joyfulcoder Posted March 7, 2015 Share Posted March 7, 2015 Next step: Implement page flipping. I seem to be able to create a pair of surfaces and swap their pointers, but the desired effect of a fully drawn screen just "popping" into view is not happening. I still see drawing. Please review and offer recommendations. You need to call VsetScreen inside your 'while' loop after swapping your screen pointers. Also, since every screen is being filled red you won't see any change after the first red screen appears. Try filling with a random color to see the flipping taking place. Quote Link to comment Share on other sites More sharing options...
pixelmischief Posted March 7, 2015 Author Share Posted March 7, 2015 @joyfulcoder: Genius. Thank you. #include<stdio.h> #include<stdlib.h> #include<tos.h> #include<ext.h> #define VsetScreen(laddr,paddr,mode) xbios(5,laddr,paddr,3,mode) #define SCREEN_MODE_340X240X65536 276 #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 int getColor ( int R, int G, int B ); void main() { int previousScreenMode; void * previousLogicalBase; void * previousPhysicalBase; size_t newScreenSize; void * frontBuffer; void * backBuffer; void * swapBuffer; long pixelOffset; long color = 0; previousLogicalBase = Logbase(); previousPhysicalBase = Physbase(); newScreenSize = VgetSize( SCREEN_MODE_340X240X65536 ); frontBuffer = malloc( newScreenSize ); backBuffer = malloc( newScreenSize ); previousScreenMode = VsetScreen( backBuffer, frontBuffer, (int)SCREEN_MODE_340X240X65536 ); while ( !kbhit() ) { for ( pixelOffset = 0 ; pixelOffset < (long)SCREEN_WIDTH * (long)SCREEN_HEIGHT ; pixelOffset++ ) { * ( ( int * ) backBuffer + pixelOffset ) = (int)color; } swapBuffer = frontBuffer; frontBuffer = backBuffer; backBuffer = swapBuffer; VsetScreen( backBuffer, frontBuffer, -1 ); Vsync(); color++; } VsetScreen( previousLogicalBase, previousPhysicalBase, previousScreenMode ); } int getColor ( int R, int G, int B ) { return ( ( R << 11 ) | ( G << 6 ) | B ); } Quote Link to comment Share on other sites More sharing options...
mattlacey Posted May 13, 2020 Share Posted May 13, 2020 @pixelmischief Sorry for the thread resurrection - but did you ever have any luck running this in VGA mode on Hatari? I've put something similar together based on your code and it just hangs the emulated machine in VGA mode, but if I clear the VGA bit on the video mode and change Hatari to TV for the Atari screen it works. Quote Link to comment Share on other sites More sharing options...
mattlacey Posted May 14, 2020 Share Posted May 14, 2020 On 5/13/2020 at 10:52 AM, mattlacey said: Sorry for the thread resurrection - but did you ever have any luck running this in VGA mode on Hatari? I've put something similar together based on your code and it just hangs the emulated machine in VGA mode, but if I clear the VGA bit on the video mode and change Hatari to TV for the Atari screen it works. Disregard... somebody forgot to include stdlib.h so the compiler was assuming a 16-bit return type for malloc ? 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.