English Amiga Board Amiga Lore


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 10 June 2017, 15:22   #1
chocsplease
Registered User

 
Join Date: Dec 2016
Location: london
Posts: 145
Trying the get bold, italic and coloured text out to the shell window.

Hi,

I am currently trying to see how the Amiga changes its text decoration (bold, italic, underline etc) and text colour in the shell window.

I had hoped it would simply be a matter of selecting a pen colour, or issuing a simple command - but I was wrong on all counts. I found the following example on the internet -

Code:
/*
 * Console.c
 *
 * Example of opening a window and using the console device
 * to send text and control sequences to it.  The example can be
 * easily modified to do additional control sequences.
 *
 * Compile with SAS C 5.10: LC -b1 -cfistq -v -y -L
 *
 * Run from CLI only.
 */

#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <devices/console.h>

#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>

#include <stdio.h>

#ifdef LATTICE
int CXBRK(void) { return(0); }     /* Disable Lattice CTRL/C handling */
int chkabort(void) { return(0); }  /* really */
#endif


/* Note - using two character <CSI> ESC[.  Hex 9B could be used instead */
#define RESETCON  "\033c"
#define CURSOFF   "\033[0 p"
#define CURSON    "\033[ p"
#define DELCHAR   "\033[P"

/* SGR (set graphic rendition) */
#define COLOR02   "\033[32m"
#define COLOR03   "\033[33m"
#define ITALICS   "\033[3m"
#define BOLD      "\033[1m"
#define UNDERLINE "\033[4m"
#define NORMAL    "\033[0m"


/* our functions */
void cleanexit(UBYTE *,LONG);
void cleanup(void);
BYTE OpenConsole(struct IOStdReq *,struct IOStdReq *, struct Window *);
void CloseConsole(struct IOStdReq *);
void QueueRead(struct IOStdReq *, UBYTE *);
UBYTE ConGetChar(struct MsgPort *, UBYTE *);
LONG ConMayGetChar(struct MsgPort *, UBYTE *);
void ConPuts(struct IOStdReq *, UBYTE *);
void ConWrite(struct IOStdReq *, UBYTE *, LONG);
void ConPutChar(struct IOStdReq *, UBYTE);
void main(int argc, char **argv);
struct NewWindow nw =
    {
    10, 10,                           /* starting position (left,top) */
    620,180,                          /* width, height */
    -1,-1,                            /* detailpen, blockpen */
    CLOSEWINDOW,                      /* flags for idcmp */
    WINDOWDEPTH|WINDOWSIZING|
    WINDOWDRAG|WINDOWCLOSE|
    SMART_REFRESH|ACTIVATE,           /* window flags */
    NULL,                             /* no user gadgets */
    NULL,                             /* no user checkmark */
    "Console Test",                   /* title */
    NULL,                             /* pointer to window screen */
    NULL,                             /* pointer to super bitmap */
    100,45,                           /* min width, height */
    640,200,                          /* max width, height */
    WBENCHSCREEN                      /* open on workbench screen */
    };


/* Opens/allocations we'll need to clean up */
struct Library  *IntuitionBase = NULL;
struct Window   *win = NULL;
struct IOStdReq *writeReq = NULL;    /* IORequest block pointer */
struct MsgPort  *writePort = NULL;   /* replyport for writes      */
struct IOStdReq *readReq = NULL;     /* IORequest block pointer */
struct MsgPort  *readPort = NULL;    /* replyport for reads       */
BOOL OpenedConsole = FALSE;

BOOL FromWb;

void main(argc, argv)
int argc;
char **argv;
    {
    struct IntuiMessage *winmsg;
    ULONG signals, conreadsig, windowsig;
    LONG lch;
    SHORT InControl = 0;
    BOOL Done = FALSE;
    UBYTE ch, ibuf;
    UBYTE obuf[200];
    BYTE error;

    FromWb = (argc==0L) ? TRUE : FALSE;

    if(!(IntuitionBase=OpenLibrary("intuition.library",0)))
         cleanexit("Can't open intuition\n",RETURN_FAIL);

    /* Create reply port and io block for writing to console */
    if(!(writePort = CreatePort("RKM.console.write",0)))
         cleanexit("Can't create write port\n",RETURN_FAIL);

    if(!(writeReq = (struct IOStdReq *)
                    CreateExtIO(writePort,(LONG)sizeof(struct IOStdReq))))
         cleanexit("Can't create write request\n",RETURN_FAIL);

    /* Create reply port and io block for reading from console */
    if(!(readPort = CreatePort("RKM.console.read",0)))
         cleanexit("Can't create read port\n",RETURN_FAIL);

    if(!(readReq = (struct IOStdReq *)
                   CreateExtIO(readPort,(LONG)sizeof(struct IOStdReq))))
         cleanexit("Can't create read request\n",RETURN_FAIL);

    /* Open a window */
    if(!(win = OpenWindow(&nw)))
         cleanexit("Can't open window\n",RETURN_FAIL);

    /* Now, attach a console to the window */
    if(error = OpenConsole(writeReq,readReq,win))
         cleanexit("Can't open console.device\n",RETURN_FAIL);
    else OpenedConsole = TRUE;

    /* Demonstrate some console escape sequences */
    ConPuts(writeReq,"Here's some normal text\n");
    sprintf(obuf,"%s%sHere's text in color 3 & italics\n",COLOR03,ITALICS);
    ConPuts(writeReq,obuf);
    ConPuts(writeReq,NORMAL);
    Delay(50);      /* Delay for dramatic demo effect */
    ConPuts(writeReq,"We will now delete this asterisk =*=");
    Delay(50);
    ConPuts(writeReq,"\b\b");  /* backspace twice */
    Delay(50);
    ConPuts(writeReq,DELCHAR); /* delete the character */
    Delay(50);

    QueueRead(readReq,&ibuf); /* send the first console read request */

    ConPuts(writeReq,"\n\nNow reading console\n");
    ConPuts(writeReq,"Type some keys.  Close window when done.\n\n");

    conreadsig = 1 << readPort->mp_SigBit;
    windowsig = 1 << win->UserPort->mp_SigBit;

    while(!Done)
        {
        /* A character, or an IDCMP msg, or both could wake us up */
        signals = Wait(conreadsig|windowsig);

        /* If a console signal was received, get the character */
        if (signals & conreadsig)
            {
            if((lch = ConMayGetChar(readPort,&ibuf)) != -1)
                {
                ch = lch;
                /* Show hex and ascii (if printable) for char we got.
                 * If you want to parse received control sequences, such as
                 * function or Help keys,you would buffer control sequences
                 * as you receive them, starting to buffer whenever you
                 * receive 0x9B (or 0x1B[ for user-typed sequences) and
                 * ending when you receive a valid terminating character
                 * for the type of control sequence you are receiving.
                 * For CSI sequences, valid terminating characters
                 * are generally 0x40 through 0x7E.
                 * In our example, InControl has the following values:
                 * 0 = no, 1 = have 0x1B, 2 = have 0x9B OR 0x1B and [,
                 * 3 = now inside control sequence, -1 = normal end esc,
                 * -2 = non-CSI(no [) 0x1B end esc
                 * NOTE - a more complex parser is required to recognize
                 *  other types of control sequences.
                 */

                /* 0x1B ESC not followed by '[', is not CSI seq */
                if (InControl==1)
                    {
                    if(ch=='[') InControl = 2;
                    else InControl = -2;
                    }

                if ((ch==0x9B)||(ch==0x1B))  /* Control seq starting */
                    {
                    InControl = (ch==0x1B) ? 1 : 2;
                    ConPuts(writeReq,"=== Control Seq ===\n");
                    }

                /* We'll show value of this char we received */
                if (((ch >= 0x1F)&&(ch <= 0x7E))||(ch >= 0xA0))
                   sprintf(obuf,"Received: hex %02x = %c\n",ch,ch);
                else sprintf(obuf,"Received: hex %02x\n",ch);
                ConPuts(writeReq,obuf);

                /* Valid ESC sequence terminator ends an ESC seq */
                if ((InControl==3)&&((ch >= 0x40) && (ch <= 0x7E)))
                    {
                    InControl = -1;
                    }
                if (InControl==2) InControl = 3;
                /* ESC sequence finished (-1 if OK, -2 if bogus) */
                if (InControl < 0)
                    {
                    InControl = 0;
                    ConPuts(writeReq,"=== End Control ===\n");
                    }
                }
            }

        /* If IDCMP messages received, handle them */
        if (signals & windowsig)
            {
            /* We have to ReplyMsg these when done with them */
            while (winmsg = (struct IntuiMessage *)GetMsg(win->UserPort))
                {
                switch(winmsg->Class)
                    {
                    case CLOSEWINDOW:
                      Done = TRUE;
                      break;
                    default:
                      break;
                     }
                ReplyMsg((struct Message *)winmsg);
                }
            }
        }

    /* We always have an outstanding queued read request
     * so we must abort it if it hasn't completed,
     * and we must remove it.
     */
    if(!(CheckIO(readReq)))  AbortIO(readReq);
    WaitIO(readReq);     /* clear it from our replyport */

    cleanup();
    exit(RETURN_OK);
    }

void cleanexit(UBYTE *s,LONG n)
    {
    if(*s & (!FromWb)) printf(s);
    cleanup();
    exit(n);
    }

void cleanup()
    {
    if(OpenedConsole) CloseConsole(writeReq);
    if(readReq)       DeleteExtIO(readReq);
    if(readPort)      DeletePort(readPort);
    if(writeReq)      DeleteExtIO(writeReq);
    if(writePort)     DeletePort(writePort);
    if(win)           CloseWindow(win);
    if(IntuitionBase) CloseLibrary(IntuitionBase);
    }


/* Attach console device to an open Intuition window.
 * This function returns a value of 0 if the console
 * device opened correctly and a nonzero value (the error
 * returned from OpenDevice) if there was an error.
 */
BYTE OpenConsole(writereq, readreq, window)
struct IOStdReq *writereq;
struct IOStdReq *readreq;
struct Window *window;
    {
    BYTE error;

    writereq->io_Data = (APTR) window;
    writereq->io_Length = sizeof(struct Window);
    error = OpenDevice("console.device", 0, writereq, 0);
    readreq->io_Device = writereq->io_Device; /* clone required parts */
    readreq->io_Unit   = writereq->io_Unit;
    return(error);
    }

void CloseConsole(struct IOStdReq *writereq)
    {
    CloseDevice(writereq);
    }

/* Output a single character to a specified console
 */
void ConPutChar(struct IOStdReq *writereq, UBYTE character)
    {
    writereq->io_Command = CMD_WRITE;
    writereq->io_Data = (APTR)&character;
    writereq->io_Length = 1;
    DoIO(writereq);
    /* command works because DoIO blocks until command is done
     * (otherwise ptr to the character could become invalid)
     */
    }


/* Output a stream of known length to a console
 */
void ConWrite(struct IOStdReq *writereq, UBYTE *string, LONG length)
    {
    writereq->io_Command = CMD_WRITE;
    writereq->io_Data = (APTR)string;
    writereq->io_Length = length;
    DoIO(writereq);
    /* command works because DoIO blocks until command is done
     * (otherwise ptr to string could become invalid in the meantime)
     */
    }


/* Output a NULL-terminated string of characters to a console
 */
void ConPuts(struct IOStdReq *writereq,UBYTE *string)
    {
    writereq->io_Command = CMD_WRITE;
    writereq->io_Data = (APTR)string;
    writereq->io_Length = -1;  /* means print till terminating null */
    DoIO(writereq);
    }

/* Queue up a read request to console, passing it pointer
 * to a buffer into which it can read the character
 */
void QueueRead(struct IOStdReq *readreq, UBYTE *whereto)
   {
   readreq->io_Command = CMD_READ;
   readreq->io_Data = (APTR)whereto;
   readreq->io_Length = 1;
   SendIO(readreq);
   }


/* Check if a character has been received.
 * If none, return -1
 */
LONG ConMayGetChar(struct MsgPort *msgport, UBYTE *whereto)
    {
    register temp;
    struct IOStdReq *readreq;

    if (!(readreq = (struct IOStdReq *)GetMsg(msgport))) return(-1);
    temp = *whereto;                /* get the character */
    QueueRead(readreq,whereto);     /* then re-use the request block */
    return(temp);
    }

/* Wait for a character
 */
UBYTE ConGetChar(struct MsgPort *msgport, UBYTE *whereto)
    {
    register temp;
    struct IOStdReq *readreq;

    WaitPort(msgport);
    readreq = (struct IOStdReq *)GetMsg(msgport);
    temp = *whereto;               /* get the character */
    QueueRead(readreq,whereto);    /* then re-use the request block*/
    return((UBYTE)temp);
    }
However its written for Lattice c and I am using gcc so just cannot get it to compile cleanly - here's my (very long) error list

Code:
In file included from console.c:43:
/gg/os-include/clib/dos_protos.h:128: warning: `struct ExAllControl' declared inside parameter list
/gg/os-include/clib/dos_protos.h:128: warning: its scope is only this definition or declaration, which is probably not what you want.
/gg/os-include/clib/dos_protos.h:128: warning: `struct ExAllData' declared inside parameter list
/gg/os-include/clib/dos_protos.h:243: warning: `struct ExAllControl' declared inside parameter list
/gg/os-include/clib/dos_protos.h:243: warning: `struct ExAllData' declared inside parameter list
console.c: In function `main':
console.c:479: warning: passing arg 1 of `CheckIO' from incompatible pointer type
console.c:479: warning: passing arg 1 of `AbortIO' from incompatible pointer type
console.c:481: warning: passing arg 1 of `WaitIO' from incompatible pointer type
console.c:183: warning: return type of `main' is not `int'
console.c: In function `cleanup':
console.c:513: warning: passing arg 1 of `DeleteExtIO' from incompatible pointer type
console.c:517: warning: passing arg 1 of `DeleteExtIO' from incompatible pointer type
console.c: In function `OpenConsole':
console.c:559: warning: passing arg 3 of `OpenDevice' from incompatible pointer type
console.c: In function `CloseConsole':
console.c:575: warning: passing arg 1 of `CloseDevice' from incompatible pointer type
console.c: In function `ConPutChar':
console.c:595: warning: passing arg 1 of `DoIO' from incompatible pointer type
console.c: In function `ConWrite':
console.c:623: warning: passing arg 1 of `DoIO' from incompatible pointer type
console.c: In function `ConPuts':
console.c:651: warning: passing arg 1 of `DoIO' from incompatible pointer type
console.c: In function `QueueRead':
console.c:673: warning: passing arg 1 of `SendIO' from incompatible pointer type
Since I am still re-learning C, never mind trying to work out how the Amiga does things I am at a complete loss as to how to get this example to compile, never mind how to get a simple Hello World onto the shell window!

Can someone point me at a simple example that I can play with?

Thanks in advance.

Last edited by chocsplease; 10 June 2017 at 15:47.
chocsplease is offline  
AdSense AdSense  
Old 10 June 2017, 16:03   #2
nogginthenog
Amigan

 
Join Date: Feb 2012
Location: London
Posts: 457
Change this:
Code:
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>
To this:
Code:
#include <proto/exec.h>
#include <proto/alib.h>
#include <proto/dos.h>
#include <proto/intuition.h>
Make sure you compile with the -noixemul flag. I'm using Bebbo's GCC 6.3.1b but older versions should work.
nogginthenog is offline  
Old 10 June 2017, 22:14   #3
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 2,483
Quote:
Originally Posted by chocsplease View Post
I had hoped it would simply be a matter of selecting a pen colour, or issuing a simple command - but I was wrong on all counts.
You're making things waaaay more complicated than they need to be.

You don't need to open your own window and use console.device directly. The CLI/Shell itself uses console.device, so you can use console.device "select graphic rendition" sequences when outputting text. See the ROM Kernel Manual: Devices page about that.

Taking the example from that page:
Code:
For example, to select bold face, with color 3 as the character color, and
color 0 as the character cell color and the background color, send the hex
sequence:

    9B 31 3B 33 33 3B 34 30 3B 3E 30 6D

representing the ASCII sequence:

    <CSI>1;33;40;>0m

where <CSI> is the control sequence introducer, here used as the single
character value 0x9B.
So all you need to do to print some text using that sequence is
Code:
printf("\x9B1;33;40;>0m OMG this is soooo easy.");
(Actually it's not quite that easy, because to be polite you should return the text style and colour to default before exiting your program, otherwise the user's Shell prompt and what they type will remain in that style.)
mark_k is offline  
Old 11 June 2017, 13:17   #4
chocsplease
Registered User

 
Join Date: Dec 2016
Location: london
Posts: 145
Quote:
Originally Posted by mark_k View Post
You're making things waaaay more complicated than they need to be.

You don't need to open your own window and use console.device directly. The CLI/Shell itself uses console.device, so you can use console.device "select graphic rendition" sequences when outputting text. See the ROM Kernel Manual: Devices page about that.

Taking the example from that page:
Code:
For example, to select bold face, with color 3 as the character color, and
color 0 as the character cell color and the background color, send the hex
sequence:

    9B 31 3B 33 33 3B 34 30 3B 3E 30 6D

representing the ASCII sequence:

    <CSI>1;33;40;>0m

where <CSI> is the control sequence introducer, here used as the single
character value 0x9B.
So all you need to do to print some text using that sequence is
Code:
printf("\x9B1;33;40;>0m OMG this is soooo easy.");
(Actually it's not quite that easy, because to be polite you should return the text style and colour to default before exiting your program, otherwise the user's Shell prompt and what they type will remain in that style.)
Hi and thanks for the reply,

Unfortunately I cannot get this -
Code:
printf("\x9B1;33;40;>0m OMG this is soooo easy.");
to work at all.

I get a Warning 'escape sequence out of range for character' and the output -

±;33;40;>0m OMG this is soooo easy.

So sorry it ain't

Anyone know why it's not working for me? I've tried in KingCon and the standard shell.

Noggin, I tried your suggestion and sadly it still won't compile - I'm getting the following -
Code:
gcc -s -lamiga -noixemul -O2 console2.c
console2.c:81: conflicting types for `IntuitionBase'
/gg/os-include/proto/intuition.h:17: previous declaration of `IntuitionBase'
console2.c: In function `main':
console2.c:240: warning: initialization from incompatible pointer type
console2.c:240: warning: initialization from incompatible pointer type
console2.c:241: warning: initialization from incompatible pointer type
console2.c:92: warning: return type of `main' is not `int'
console2.c: In function `cleanup':
console2.c:257: warning: passing arg 1 of `DeleteExtIO' from incompatible pointer type
console2.c:259: warning: passing arg 1 of `DeleteExtIO' from incompatible pointer type
console2.c: In function `OpenConsole':
console2.c:280: warning: initialization from incompatible pointer type
console2.c: In function `CloseConsole':
console2.c:288: warning: initialization from incompatible pointer type
console2.c: In function `ConPutChar':
console2.c:298: warning: initialization from incompatible pointer type
console2.c: In function `ConWrite':
console2.c:312: warning: initialization from incompatible pointer type
console2.c: In function `ConPuts':
console2.c:326: warning: initialization from incompatible pointer type
console2.c: In function `QueueRead':
console2.c:337: warning: initialization from incompatible pointer type
I can fix the warning for main (why GCC wants to return an int is beyond me) but beyond that I'm still stumped -

Last edited by chocsplease; 11 June 2017 at 13:33.
chocsplease is offline  
Old 11 June 2017, 13:38   #5
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 2,483
Quote:
Originally Posted by chocsplease View Post
Unfortunately I cannot get this -
Code:
printf("\x9B1;33;40;>0m OMG this is soooo easy.");
to work at all.

I get a Warning 'escape sequence out of range for character' and the output
Ah sorry about that. The error message was because the C compiler interpreted the sequence \x9B1 as meaning the number 0x9B1 (which is out of range for a character which has to fit in a byte, so it was truncated to 0xB1).

If you just split the string it should work fine:
Code:
printf("\x9B" "1;33;40;>0m OMG this is soooo easy.");
Or replace the 0x9B byte with (as in your example code above) \033[, so:
Code:
printf("\033[1;33;40;>0m OMG this is soooo easy.");
If you use the #defines from the example code, you could do something like:
Code:
printf(BOLD "This is bold text!\n" NORMAL);

Last edited by mark_k; 11 June 2017 at 13:43.
mark_k is offline  
Old 11 June 2017, 13:53   #6
nogginthenog
Amigan

 
Join Date: Feb 2012
Location: London
Posts: 457
Quote:
Originally Posted by chocsplease View Post
Noggin, I tried your suggestion and sadly it still won't compile - I'm getting the following -
Code:
gcc -s -lamiga -noixemul -O2 console2.c
console2.c:81: conflicting types for `IntuitionBase'
/gg/os-include/proto/intuition.h:17: previous declaration of `IntuitionBase'
I can fix the warning for main (why GCC wants to return an int is beyond me) but beyond that I'm still stumped -
Ah, sorry. I forgot I changed IntuitionBase too. Should be like this:

Quote:
struct IntuitionBase *IntuitionBase = NULL;
I will leave it to you to understand and then fix the warnings

main() should return an int as it's the result code for the OS. You can use this in a shell script for example.
nogginthenog is offline  
Old 11 June 2017, 18:04   #7
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 46
Posts: 359
ansi.c

Code:
#include <stdio.h>


/* Note - using two character <CSI> ESC[.  Hex 9B could be used instead */
#define RESETCON  "\033c"
#define CURSOFF   "\033[0 p"
#define CURSON    "\033[ p"
#define DELCHAR   "\033[P"

/* SGR (set graphic rendition) */
#define COLOR02   "\033[32m"
#define COLOR03   "\033[33m"
#define ITALICS   "\033[3m"
#define BOLD      "\033[1m"
#define UNDERLINE "\033[4m"
#define NORMAL    "\033[0m"

int main(int argc, char *argv[])
{
  printf(BOLD "This is bold text!\n" NORMAL);
  return 0;
}
compile with
Code:
m68k-amigaos-gcc -Os -s -noixemul -o ansi ansi.c
works for me.
alkis is offline  
Old 15 June 2017, 12:25   #8
chocsplease
Registered User

 
Join Date: Dec 2016
Location: london
Posts: 145
Many thanks for the replies - yes the compile works but I have really had to fiddle with it.

Anyway I have now hit a very odd problem to do with how the Amiga assigns colours on a screen with more than 4.

I'm running a 32 colour Workbench, but the Shell will only use 8 of these (0 - 7). I thought that it would simply use the first 8, since this would be the most obvious. HA! Wrong.

My WB Palette prefs are as follows -

Code:
Colour number  Red    Green    Blue
0                   155    155       155
1                   255    255       255
2                   0       0          0
3                   80     120       160
4                   238    68        68
5                   85      221      85
6                   0        68       221
7                   238     153     0
Now OK it does not actually number them but my code is reporting the following

Code:
Colour number  Red    Green    Blue
0                   155    155       155
1                   255    255       255
2                   0       0          0
3                   80     120       160
4                   120    120       120
5                   175    175       175
6                   170    145       125
7                   255    170       150
In short every colour from 4 onwards is different

Here's an exert of the code I'm using, not pretty but it should work (I think)

Code:
struct Screen *screen;
unsigned char screenName[] = "Workbench";
unsigned long colorTable[256 *3 ];
struct ViewPort *viewPort;
struct ColorMap *colorMap;
unsigned long red,green,blue;

screen = LockPubScreen(screenName);
	if (screen) /*locked the screen so we can now read info */
	{
		viewPort = &screen->ViewPort;
		colorMap = viewPort->ColorMap;
		GetRGB32(colorMap,0,colorMap->Count, colorTable);
		
		UnlockPubScreen(NULL,screen);
		numcolours=colorMap->Count;
	}
	if (numcolours>2) /*don't bother for failed or 2 colur screen*/	
	{
		for (i=0;i<numcolours;i++)
		{
			red = colorTable[i * 3 + 0] >> 24 ;
			green = colorTable[i * 3 +1] >> 24;
			blue = colorTable[i * 3 +2] >> 24;
		
			/*find reddest*/
			if ((red >= red_r) && ((green <= red_g) || (blue <= red_b))) 
			{
				colour_red=i;
				red_r=red;red_g=green;red_b=blue;
			}
			/*find greenest*/
			if ((green >= green_g) && ((red <= green_r) || (blue <= green_b)))
			{
				colour_green=i;
				green_r=red;green_g=green;green_b=blue;
			}
			/*find blueest - eventually yellow */
			if ((blue >= blue_b) && (red <= blue_r) && ((red <=blue_r) || (green <= blue_g)))
			{
				colour_blue=i;
				blue_r=red;blue_g=green;blue_b=blue;
			}
               }
	}
I wanted to have the code display the %used in a different colour depending on how full the disk was, green ish for less than 60%, yellowish for 61% to 90% and reddish for 90+%.

I worked out some code that finds the most red, green etc colour but it fails as its not seeing the same numbers as the system is actually using and I have no idea how to get it to do so.

Anyone got any ideas on this?

Last edited by chocsplease; 15 June 2017 at 12:36.
chocsplease is offline  
Old 15 June 2017, 14:28   #9
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 2,483
I think you might find console colours 4-7 are taken from the highest four palette entries (so for a 32-colour screen, colours 28-31).
mark_k is offline  
Old 15 June 2017, 15:47   #10
daxb
Registered User
 
Join Date: Oct 2009
Location: Germany
Posts: 1,711
Have you changed the first 4 (0-3) colors? If not they seem to not the usual what I guess are 0 to 3 = grey, black, white, blue (or similar). The colors 4 to 7 seems to be MagicWB colors what might be the last 4 colors of a palette. There are some tools/hacks that set/lock them.

Shell colors are the first 8 (0-7) and I`ve never heard that this is not the case. Do you use FullPalette to set/change/check your palette?
daxb is offline  
Old 17 June 2017, 00:29   #11
chocsplease
Registered User

 
Join Date: Dec 2016
Location: london
Posts: 145
Quote:
Originally Posted by daxb View Post
Have you changed the first 4 (0-3) colors? If not they seem to not the usual what I guess are 0 to 3 = grey, black, white, blue (or similar). The colors 4 to 7 seems to be MagicWB colors what might be the last 4 colors of a palette. There are some tools/hacks that set/lock them.

Shell colors are the first 8 (0-7) and I`ve never heard that this is not the case. Do you use FullPalette to set/change/check your palette?
Hi,

I didn't know that the colours are different to the default as the A1200 I am using is 2nd hand from EBay. It came with a lot of WB enhancements, but I don't think it is running MagicWB. In any case my code needs to allow for users to have changed the colours to whatever they wish - hence my feeble attempts to find the most red, green etc.

I don't use fullpalette (just Googled it - useful tool )just the stock prefs.

I basically have 2 problems here.

First my code is getting different colours from those I expect so I'll see if fullpaltte can show me where colours 4-7 are coming from.

Second its setting the most red to colour 6 (which is a sort of orange) and is very close in gamma to the grey background - making it almost impossible to read any figures using it. I think I'm going to have to work out how to calculate the grey equivalent of a colour so this does not happen but have no idea how to do this - I suspect finding the simple average of red,green and blue wont work.

Does anyone have any ideas how I can find the grey scale equivalent of a colour?
chocsplease is offline  
Old 17 June 2017, 01:15   #12
thomas
Registered User
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 5,510
Quote:
Does anyone have any ideas how I can find the grey scale equivalent of a colour?
(R + G + B) / 3


Palette prefs sets the first four and the last four pens of the screen. So if your screen has a depth of eight colours, you can define all eight pens. But if your screen has more colours, pens 4 - 7 are random.

If you don't want to dictate the screen's palette, then you should stick with
0 = background / transparent
1 = black
2 = white
3 = some color
thomas is offline  
Old 17 June 2017, 12:59   #13
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 2,483
Quote:
Originally Posted by thomas View Post
(R + G + B) / 3
A simple average isn't very good, because the human eye is much more sensitive to green than blue. A good-enough way to calculate the luminance is 3×red + 6×green + 1×blue
mark_k is offline  
Old 17 June 2017, 13:36   #14
chocsplease
Registered User

 
Join Date: Dec 2016
Location: london
Posts: 145
Many thanks for the replies.

Getting a nice looking output is proving a real mission.

Quote:
Originally Posted by mark_k View Post
A simple average isn't very good, because the human eye is much more sensitive to green than blue. A good-enough way to calculate the luminance is 3×red + 6×green + 1×blue
In the end I went for 0.21 R + 0.72 G + 0.07 B, though there are so many different suggestions on the net (should have googled first!) its kind of try it and see.

I suspect I'm either going to force the output background to be white (or as close to white as the user has) or force the percentage background to be white - playing around at present to see which looks best.
chocsplease is offline  
Old 18 June 2017, 03:17   #15
idrougge
Registered User
 
Join Date: Sep 2007
Location: Stockholm
Posts: 2,985
I think you're overstretching it. Do you really need that many colours?
idrougge is offline  
Old 22 June 2017, 13:21   #16
chocsplease
Registered User

 
Join Date: Dec 2016
Location: london
Posts: 145
Quote:
Originally Posted by idrougge View Post
I think you're overstretching it. Do you really need that many colours?
Hi,

Well part of the reason I am doing this is to learn how the Amiga does stuff, including colours, graphics windows etc. So to be blunt I don't but wanted to see if it was possible to display a disks percentage used in different colours depending on how much was actually used. So green for < 75% yellow for < 90% red for 90% plus.

When I started I assumed that the shell used the same colours that the workbench screen did - it does not. As a result the final code probably wont be that colourful at all, but I have improved my knowledge which is half the reason for doing this
chocsplease is offline  
Old 22 June 2017, 14:58   #17
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 2,483
If you don't mind having your program open a custom screen, you can set its palette to whatever you want.
mark_k is offline  
AdSense AdSense  
 


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

Similar Threads
Thread Thread Starter Forum Replies Last Post
Closing current Shell window programmatically? tygre Coders. General 5 06 September 2015 06:24
Snapshot Amiga Shell window? TenLeftFingers support.Apps 3 15 June 2015 16:38
Cannot configurate cd32 coloured buttons danny-666 support.WinUAE 2 15 June 2011 02:32
Clear background color for Shell window- Shell-StartUp fc.studio support.Apps 12 29 December 2009 14:21
Multi-coloured A500 Jim Nostalgia & memories 8 08 January 2002 22:56

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 00:03.


Powered by vBulletin® Version 3.8.8 Beta 1
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Page generated in 0.25529 seconds with 12 queries