English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 28 May 2014, 17:37   #1
balrogsoft
Registered User
 
Join Date: May 2006
Location: Spain
Age: 42
Posts: 76
ScrollVPort double buffer problem with garbage pixels

Hello.

I'm working on a system friendly game engine for Amiga, from AmigaOS 2.0 to the new gen. compatible systems, I have tested my engine on MorphOS, EUAE and my Amiga 600. But I have a problem with my double buffer implementation, it uses ScrollVPort trick with a doubled screen height, it show some garbage pixels at the end of one of the buffers on real Amiga or emulators. I think that it could be related with overscan, but I figure out where is the problem, I can't find the reason, maybe someone can help me with my problem, this is a simple code showing my problem (compiled with SAS/C 6.58):

Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <libraries/lowlevel.h> 
#include <libraries/asl.h>
#include <proto/asl.h>
#include <proto/lowlevel.h> 
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/dos.h>
#include <exec/memory.h>    

#define DEPTH   8

struct Library *AslBase =NULL;
						
UWORD__chip EmptyPointer[] = {0, 0, 0, 0};	

int main(void)
{
	struct ScreenModeRequester *screenReq;
	struct Screen *screen;
	struct Window *window;
	LONG width = 0, height = 0, frame = 0, frameOffset = 0, key = 0, x, y, n;
	AslBase =OpenLibrary("asl.library",38);
	if (AslBase)
	{
		
		screenReq = AllocAslRequest(ASL_ScreenModeRequest, NULL);
	
		AslRequestTags(screenReq, NULL); 
		
		width = screenReq->sm_DisplayWidth;
		height=screenReq->sm_DisplayHeight;
		
		screen= OpenScreenTags(NULL,
					   SA_DisplayID, screenReq->sm_DisplayID,
					   SA_Left,		 0,
					   SA_Top,		 0,
					   SA_Width,     width,
					   SA_Height,    height<<1,
					   SA_Depth,     DEPTH,
					  // SA_Type,	     CUSTOMSCREEN, 
					   SA_Quiet,     TRUE,
					   SA_Overscan,  OSCAN_STANDARD,
					   SA_AutoScroll, FALSE,
					   TAG_DONE);
					   
		window =OpenWindowTags(NULL,
									WA_CustomScreen, screen,
									WA_Title, NULL,
									WA_Flags, WFLG_BORDERLESS | WFLG_REPORTMOUSE | WFLG_ACTIVATE,
									WA_IDCMP, 0,
									TAG_DONE);
									
		FreeAslRequest(screenReq);         
				
		CloseLibrary(AslBase);
	}
	if (screen && window)
	{	
		SetPointer(window, EmptyPointer, 1L, 1L, 0L, 0L);

		do
		{   
			key = GetKey();
			
			RectFill(&screen->RastPort, 0, frameOffset, width, frameOffset+height);
			
			
			frame ^= 1;
			frameOffset = frame*height;
			screen->ViewPort.RasInfo->RyOffset = frameOffset;
			
			ScrollVPort(&screen->ViewPort);
			WaitBOVP(&screen->ViewPort);
			
		} while (key != 69);
		
		CloseWindow(window);
		CloseScreen(screen);
	}

	return RETURN_OK;
}
This is a screenshot of EUAE showing this problem, it appears at the end of one buffer, on the last 5-6 rows of pixels.


Last edited by balrogsoft; 28 May 2014 at 20:04.
balrogsoft is offline  
Old 28 May 2014, 22:08   #2
balrogsoft
Registered User
 
Join Date: May 2006
Location: Spain
Age: 42
Posts: 76
I have found the solution on CyberAnim13.lha from aminet, it uses a ScrollVPort double buffer, and overscan was the problem, here is the correct source for a ScrollVPort, it works on MorphOS, EUAE, and my Amiga 600.

Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <libraries/lowlevel.h> 
#include <libraries/asl.h>

#include <proto/asl.h>
#include <proto/lowlevel.h> 
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/dos.h>

#include <exec/memory.h>    

#define DEPTH   5

struct Library *AslBase =NULL;
						
UWORD__chip EmptyPointer[] = {0, 0, 0, 0};	

int main(void)
{
	struct ScreenModeRequester *screenReq;
	struct Screen *screen;
	struct Window *window;
	LONG width = 0, height = 0, frame = 0, frameOffset = 0, key = 0, x, y, n;
	AslBase =OpenLibrary("asl.library",38);
	if (AslBase)
	{
		struct DimensionInfo dimsinfo;
		LONG oscan_height;
		void *handle;
		
		screenReq = AllocAslRequest(ASL_ScreenModeRequest, NULL);
		
		AslRequestTags(screenReq, NULL); 
		
		width = screenReq->sm_DisplayWidth;
		height= screenReq->sm_DisplayHeight;

		handle = FindDisplayInfo (screenReq->sm_DisplayID);
		GetDisplayInfoData (handle, (UBYTE *)&dimsinfo,
                                   sizeof(struct DimensionInfo), DTAG_DIMS,
                                   NULL);
		
		oscan_height =  dimsinfo.MaxOScan.MaxY - dimsinfo.MaxOScan.MinY + 1;
		
		if (oscan_height > height)
			height =oscan_height;
		
		screen= OpenScreenTags(NULL,
					   SA_DisplayID, screenReq->sm_DisplayID,
					   SA_Left,		 0,
					   SA_Top,		 0,
					   SA_Width,     width,
					   SA_Height,    height<<1,
					   SA_Depth,     DEPTH,
					   SA_Type,	     CUSTOMSCREEN,
					   SA_Draggable, FALSE,
					   SA_Exclusive, TRUE,
					   SA_AutoScroll,FALSE,
					   TAG_DONE);
					   
		window =OpenWindowTags(NULL,
									WA_CustomScreen, screen,
									WA_Title, NULL,
									WA_Flags, WFLG_BORDERLESS | WFLG_REPORTMOUSE | WFLG_ACTIVATE,
									WA_IDCMP, 0,
									TAG_DONE);
									
		FreeAslRequest(screenReq);         
				
		CloseLibrary(AslBase);
	}
	if (screen && window)
	{	
		SetPointer(window, EmptyPointer, 1L, 1L, 0L, 0L);

		do
		{   
			key = GetKey();
				
			RectFill(&screen->RastPort, 0, frameOffset, width, frameOffset+height);
			
			ScrollVPort(&screen->ViewPort);
			WaitBOVP(&screen->ViewPort);
			
			frame ^= 1;
			frameOffset = frame*height;
			screen->ViewPort.RasInfo->RyOffset = frameOffset;
		
			
		} while (key != 69);
		
		CloseWindow(window);
		CloseScreen(screen);
	}

	return RETURN_OK;
}
balrogsoft is offline  
Old 29 May 2014, 02:24   #3
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,796
You should get rid of WaitBOVP, because it uses busy waiting. Better to setup a copper list that generates a copper interrupt at the bottom of the screen, and have an interrupt server signal your program.
Thorham is offline  
Old 29 May 2014, 08:18   #4
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,534
If you don't want to bother with user copperlists and chipset specific stuff, just use WaitTOF(), it does not busy wait and difference between WaitTOF() and WaitBOVP() will be only few scanlines in overscan modes. (and probably there is no difference in RTG modes)
Toni Wilen is offline  
Old 29 May 2014, 11:51   #5
balrogsoft
Registered User
 
Join Date: May 2006
Location: Spain
Age: 42
Posts: 76
Quote:
Originally Posted by Thorham View Post
You should get rid of WaitBOVP, because it uses busy waiting. Better to setup a copper list that generates a copper interrupt at the bottom of the screen, and have an interrupt server signal your program.
I think that it won't work on new gen systems like MorphOS or AmigaOS4.

Quote:
Originally Posted by Toni Wilen View Post
If you don't want to bother with user copperlists and chipset specific stuff, just use WaitTOF(), it does not busy wait and difference between WaitTOF() and WaitBOVP() will be only few scanlines in overscan modes. (and probably there is no difference in RTG modes)
I will give a try, I have tested my engine with a vertical scroller with soft sprites and it works at very decent speed using WaitBOVP on my Amiga 600 with ACA 630@25mhz.

My engine is not aimed to low end Amigas, it uses system functions for drawing operations to make it compatible with new gen systems. Its features are:

Screen management (up to 8 bits depth only) with primitive gfx functions, chunky 2 planar support (via kalms c2p and WritePixelArray8 for CGFX).
Software sprites, with background restoration, and simple sprite mask generation for blitting.
Mod music support via ptreplay.library.
Joystick support via lowlevel.library.

I want to port my Engine to Android and other platforms, and develop games for Amiga and other platforms like Android and iPhone with the same source code.

This is one example for my engine, I think it is pretty easy to use:

Code:
    if (bitmap_init() & joy_init() & music_init())
    { 
        Bitmap *bm = bm_create(WIDTH,HEIGHT,DEPTH);
        FrameBuffer *fb = fb_init(320, 256, 8);
        GraphicContext *gc = gc_createWithFrameBuffer(fb);
        GraphicContext *bm_gc = gc_createWithBitmap(bm);
        int x = 100, y = 100, fr = 0, key = 0, i, m = 0, 
            cwidth = fb->width, cheight = fb->height;

        UBYTE *chunky = (UBYTE*)malloc(WIDTH*HEIGHT);

        for (y = 0; y < HEIGHT; y++) 
        {
            for (x=0; x < WIDTH; x++)
            {
                chunky[y*WIDTH+x] = (x-y)&63;
            }
        }
        
        m=0;
        do
        {     
            key = GetKey();
            // C2P to bitmap
            gc_c2p(bm_gc, chunky, 0, 0, WIDTH, HEIGHT, TRUE);
            // C2P to screen bitmap
            gc_c2p(gc, chunky, 100, 130, WIDTH, HEIGHT, TRUE);
            
            gc_drawBitmap(gc, bm, 0, 0, 0);
            
            gc_setColor(gc, 11);
            
            gc_fillRect(gc, 10+(m%64),20, 10, 10);
            m++;
            
            fb_flush(fb);
            
        } while (key != 69); 
        
        free(chunky);
        gc_dealloc(gc);
        gc_dealloc(bm_gc);
        fb_dealloc(fb);
        bm_dealloc(bm);
    }

    joy_dealloc();
    bitmap_dealloc();
    music_dealloc();
balrogsoft is offline  
Old 29 May 2014, 12:31   #6
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,796
Quote:
Originally Posted by balrogsoft View Post
I will give a try, I have tested my engine with a vertical scroller with soft sprites and it works at very decent speed using WaitBOVP on my Amiga 600 with ACA 630@25mhz.
Yeah, try it. WaitBOVP is a huge waste of CPU cycles, and should not ever be used on Amiga hardware.
Thorham is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Double PAL / Double NTSC, oficially supported by WHDLoad... Shoonay project.WHDLoad 3 15 May 2021 19:42
[PROBLEM] Amiga Forever 2012 R3 scales pixels weird - how do I adjust it? KidCupcake support.WinUAE 11 05 December 2012 22:39
Keyboard buffer problem Nut Coders. General 5 08 May 2012 15:53
Double buffer copper?? h0ffman Coders. General 8 19 July 2011 19:10
Vsync Fullscreen and Double Buffer, incorrect frame rate? rsn8887 support.WinUAE 1 07 April 2011 20:43

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 06:05.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.08394 seconds with 13 queries