Hi.
I'm working on my game engine again, and I have performance problems when it runs on stock A600 (whithout acceleration) with Kickstart 2.0. For this system the double buffer is implemented doubling the height of screen and performing a ScrollVPort to the actual frame. When I use this trick, the frame rate drops to the 50%, 25 fps only.
Any idea about why this problem occurs? If I don't use double buffering, I have tried also a basic example blitting a tilemap with vertical scroll from my engine, and there isn't enough time every frame to draw it using amigaos functions, and it only makes a few blittings every frame, it blit the next tile row meanwhile the scroll is running, not a complete row, I must forget something, it's a simple tilemap.
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <cybergraphx/cybergraphics.h>
#include <graphics/gfxbase.h>
#include <devices/timer.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/cybergraphics.h>
#include <proto/timer.h>
#define WIDTH 320
#define HEIGHT 256
#define DEPTH 5
extern struct ExecBase *SysBase;
struct GfxBase *GfxBase;
struct Library *CyberGfxBase= NULL;
struct Library *TimerBase; /* to get at the time comparison functions */
static struct IORequest timereq;
UWORD __chip EmptyPointer[] = {0, 0, 0, 0};
ULONG timer(void)
{
static struct timeval tt;
struct timeval a, b;
GetSysTime(&a);
b = a;
SubTime(&b, &tt);
tt = a;
return b.tv_secs*1000 + b.tv_micro/1000;
}
int main(void)
{
struct Screen *screen;
struct Window *window;
struct DimensionInfo dimsinfo;
ULONG mtimer = 0;
int elapsed=0;
WORD fps=0;
WORD fps_val=0;
LONG oscan_height,frame=0,frameOffset=0;
UBYTE numstr[16];
OpenDevice("timer.device", 0, &timereq, 0);
TimerBase = timereq.io_Device;
GfxBase = (struct GfxBase *) OpenLibrary( "graphics.library", 0 );
if (CyberGfxBase = OpenLibrary("cybergraphics.library",0))
{
CloseLibrary(CyberGfxBase);
}
GetDisplayInfoData(FindDisplayInfo(LORES_KEY), (UBYTE *)&dimsinfo,
sizeof(struct DimensionInfo), DTAG_DIMS,
NULL);
oscan_height = dimsinfo.MaxOScan.MaxY - dimsinfo.MaxOScan.MinY + 1;
screen = OpenScreenTags(NULL,
SA_DisplayID, PAL_MONITOR_ID|LORES_KEY,
SA_Width, WIDTH,
SA_Height, oscan_height<<1,
SA_Depth, DEPTH,
SA_Type, CUSTOMSCREEN,
SA_Quiet, TRUE,
SA_Draggable, FALSE,
SA_Exclusive, TRUE,
SA_Interleaved, TRUE,
SA_AutoScroll, FALSE,
TAG_DONE);
window = OpenWindowTags(NULL,
WA_CustomScreen, screen,
WA_Flags, WFLG_BORDERLESS | WFLG_ACTIVATE,
WA_IDCMP, 0,
TAG_DONE);
SetPointer(window, EmptyPointer, 1L, 1L, 0L, 0L);
elapsed = timer();
while((*(UBYTE *)0xBFE001) & 0x40)
{
frame ^= 1;
frameOffset = frame*oscan_height; // <--- Comment this line to disable double buffer
fps++;
elapsed = timer();
mtimer+=elapsed;
if (mtimer>1000)
{
fps_val = fps;
fps = 0;
mtimer=mtimer-1000;
}
sprintf(numstr, "%d fps", fps_val);
SetAPen(&screen->RastPort, 31);
Move(&screen->RastPort, 10, 10+frameOffset);
Text(&screen->RastPort, numstr, strlen(numstr));
screen->ViewPort.RasInfo->RyOffset = frameOffset; // <--- Comment this line to disable double buffer
ScrollVPort(&screen->ViewPort); // <--- Comment this line to disable double buffer
WaitTOF();
};
CloseWindow(window);
CloseScreen(screen);
CloseDevice(&timereq);
if(GfxBase)
CloseLibrary((struct Library *)GfxBase);
return 0;
}