Jump to content
IGNORED

Pure C and Graphics on the Falcon


Recommended Posts

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.

Link to comment
Share on other sites

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 by pixelmischief
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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 by pixelmischief
Link to comment
Share on other sites

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 );
}

Link to comment
Share on other sites

 

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.

Link to comment
Share on other sites

@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 );
}

Link to comment
Share on other sites

  • 5 years later...

@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.

Link to comment
Share on other sites

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 ?

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...