Hi. I tried to compile the example in the RKM libraries to see if it looked how I expected it. After one or two error corrections (VBCC seems to be more types resctrict than SAS) it worked et voila... Then decided to change it a bit to push the Copper resolution to the maximum (4HirRes pixels if I remember correctly, and eventhough that was for ECS, AGA's the same I think...). I made it change various successive pixels to see the result. You know what ? It was visisble on the screen that for color change it took more than eight lowres pixels (probably 16 HiRes ones or more :-o :-o :-x ) .
My question is, is this an AmigaOS restriction on Copper lists?
Is there any way of achieving the maximum resolution without banging directly the hardware? :-(
Bellow is on of the the example versions (just modified the WAIT instruction values, and the colors used to make them more different from one another, so that I can see how many pixels it takes to change between them):
/* The example program below shows the use of user Copper lists
under Intuition.
UserCopperExample.c
User Copper List Example
For SAS/C 5.10a,
compile with: LC -b1 -cfist -L -v -y UserCopperExample.c
link with lc.lib and amiga.lib
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/copper.h>
#include <graphics/videocontrol.h>
#include <intuition/intuition.h>
#include <intuition/preferences.h>
#include <hardware/custom.h>
#include <libraries/dos.h>
#include <clib/exec_protos.h> /* Prototypes. */
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/dos_protos.h>
#include <stdlib.h>
/* Use this structure to gain access to the custom registers. */
extern struct Custom far, custom;
/* Global variables. */
struct GfxBase *GfxBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Screen *screen = NULL;
struct Window *window = NULL;
int main( VOID ), cleanExit( WORD );
WORD openAll( VOID ), loadCopper( VOID );
/*
* The main() routine -- just calls subroutines
*/
int main( VOID )
{
WORD ret_val;
struct IntuiMessage *intuiMessage;
/* Open the libraries, a screen and a window. */
ret_val = openAll();
if (RETURN_OK == ret_val)
{
/* Create and attach the user Copper list. */
ret_val = loadCopper();
if (RETURN_OK == ret_val)
{
/* Wait until the user clicks in the close gadget. */
(VOID) Wait(1<<window->UserPort->mp_SigBit);
while (intuiMessage = (struct IntuiMessage *)GetMsg(window->UserPort))
ReplyMsg((struct Message *)intuiMessage);
}
}
cleanExit(ret_val);
}
/*
* openAll() -- opens the libraries, screen and window
*/
WORD openAll( VOID )
{
#define MY_WA_WIDTH 270 /* Width of window. */
WORD ret_val = RETURN_OK;
/* Prepare to explicitly request Topaz 60 as the screen font. */
struct TextAttr topaz60 =
{
(STRPTR)"topaz.font",
(UWORD)TOPAZ_SIXTY, (UBYTE)0, (UBYTE)0
};
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37L);
if (GfxBase == NULL)
ret_val = ERROR_INVALID_RESIDENT_LIBRARY;
else
{
IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 37L);
if (IntuitionBase == NULL)
ret_val = ERROR_INVALID_RESIDENT_LIBRARY;
else
{
screen = OpenScreenTags( NULL,
SA_Overscan, OSCAN_STANDARD,
SA_Title, "User Copper List Example",
SA_Font, (ULONG)&topaz60,
TAG_DONE);
if (NULL == screen)
ret_val = ERROR_NO_FREE_STORE;
else
{
window = OpenWindowTags( NULL,
WA_CustomScreen, screen,
WA_Title, "<- Click here to quit.",
WA_IDCMP, CLOSEWINDOW,
WA_Flags, WINDOWDRAG|WINDOWCLOSE|INACTIVEWINDOW,
WA_Left, (screen->Width-MY_WA_WIDTH)/2,
WA_Top, screen->Height/2,
WA_Height, screen->Font->ta_YSize + 3,
WA_Width, MY_WA_WIDTH,
TAG_DONE);
if (NULL == window)
ret_val = ERROR_NO_FREE_STORE;
}
}
}
return(ret_val);
}
/*
* loadCopper() -- creates a Copper list program and adds it to the system
*/
WORD loadCopper( VOID )
{
register USHORT i, scanlines_per_color;
WORD ret_val = RETURN_OK;
struct ViewPort *viewPort;
struct UCopList *uCopList = NULL;
struct TagItem uCopTags[] =
{
(LONG)VTAG_USERCLIP_SET, (LONG)NULL,
(LONG)VTAG_END_CM,(LONG) NULL
};
UWORD spectrum[] =
{
0x0000, 0x0705, 0x1006, 0x1006, 0x1006, 0x1006, 0x1006,
0x0000, 0x0612, 0x0613, 0x0614, 0x0615, 0x0616, 0x0617,
0x0000, 0x0619, 0x0620, 0x0621, 0x0622, 0x0623, 0x0624,
0x0000, 0x0626, 0x0627, 0x0628, 0x0629, 0x0630, 0x0631,
0x0000, 0x0633, 0x0734, 0x0835
};
#define NUMCOLORS 4
/* Allocate memory for the Copper list. */
/* Make certain that the initial memory is cleared. */
uCopList = (struct UCopList *)
AllocMem(sizeof(struct UCopList), MEMF_PUBLIC|MEMF_CLEAR);
if (NULL == uCopList)
ret_val = ERROR_NO_FREE_STORE;
else
{
/* Initialize the Copper list buffer. */
CINIT(uCopList, NUMCOLORS);
scanlines_per_color = screen->Height/NUMCOLORS;
/* Load in each color. */
for (i=1; i<NUMCOLORS; i++)
{
CWAIT(uCopList, 100,(((BYTE)(100+i))));
CMOVE(uCopList, custom.color[0], spectrum[i]);
}
CEND(uCopList); /* End the Copper list */
viewPort = ViewPortAddress(window); /* Get a pointer to the ViewPort. */
Forbid(); /* Forbid task switching while changing the Copper list. */
viewPort->UCopIns=uCopList;
Permit(); /* Permit task switching again. */
/* Enable user copper list clipping for this ViewPort. */
(VOID) VideoControl( viewPort->ColorMap, uCopTags );
RethinkDisplay(); /* Display the new Copper list. */
return(ret_val);
}
}
/*
* cleanExit() -- returns all resources that were used.
*/
VOID cleanExit( WORD retval )
{
struct ViewPort *viewPort;
if (NULL != IntuitionBase)
{
if (NULL != screen)
{
if (NULL != window)
{
viewPort = ViewPortAddress(window);
if (NULL != viewPort->UCopIns)
{
/* Free the memory allocated for the Copper. */
FreeVPortCopLists(viewPort);
RemakeDisplay();
}
CloseWindow(window);
}
CloseScreen(screen);
}
CloseLibrary((struct Library *)IntuitionBase);
}
if (NULL != GfxBase)
CloseLibrary((struct Library *)GfxBase);
exit((int)retval);
}