PALETTE in SCREEN 13 - I goof up

DOS specific questions.
Post Reply
darryl seamans
Posts: 14
Joined: Nov 14, 2008 5:58
Location: USA

PALETTE in SCREEN 13 - I goof up

Post by darryl seamans »

I wrote this program around 1993 to sample the colors possible in SCREEN 13. By setting the red/green/blue value mix one can display all 64^3 possible colors in mode 13. Basically it draws a rectangle on the screen and allows the user to change the RGB values determining the color of the rectangle using Up/Down Arrow and +/- to select the color component and increase/decrease it accordingly (0-63). It accomplishes this using the PALETTE statement. I compile it with the -lang qb option using FreeBASIC 0.20.0 for DOS and I find at runtime, before a key is pressed, the rectangle appears as I expect (off-white), but when I try to modify the colors or move around (invoking PALLETTE a second time) the rectangle disappears. I compiled this same program with Linux (FreeBASIC 0.20.0, under Slackware 12.1, using -lang qb) and it works as expected. (Under Linux it works in a window of course). I'm goofing something up, something I should have read about in the docs probably. Here's the code, and I apologize for the lack of comments:

Code: Select all

 '$lang: "qb"
 DEFLNG A-Z
 SCREEN 13: CLS

 LINE (5, 5)-(160, 100), 1, BF

 Sel = 1
 Red = 32: Green = 32: Blue = 32

 COLOR 3: LOCATE 24, 1: PRINT "+ Increment - Decrement ESC-Quit";

 DO

        ColorN = 65536 * Blue + 256 * Green + Red

        PALETTE 1, ColorN

        COLOR 7: LOCATE 18, 10: PRINT USING "PalValue: ####### "; ColorN

        LOCATE 5, 26: COLOR 9: PRINT USING "Blue    : ##"; Blue
        LOCATE 6, 26: COLOR 10: PRINT USING "Green   : ##"; Green
        LOCATE 7, 26: COLOR 12: PRINT USING "Red     : ##"; Red

        LOCATE 5, 25: PRINT " "
        LOCATE 6, 25: PRINT " "
        LOCATE 7, 25: PRINT " "
        LOCATE 4 + Sel, 25: COLOR 7: PRINT ">";

        DO
                x$ = INKEY$
        LOOP WHILE x$ = ""

        SELECT CASE x$
                CASE CHR$(0) + "H":
                        Sel = Sel - 1
                        IF Sel < 1 THEN Sel = 3
                CASE CHR$(0) + "P"
                        Sel = Sel + 1
                        IF Sel > 3 THEN Sel = 1
                CASE "+"
                        SELECT CASE Sel
                                CASE 1: IF Blue < 63 THEN Blue = Blue + 1
                                CASE 3: IF Red < 63 THEN Red = Red + 1
                                CASE 2: IF Green < 63 THEN Green = Green + 1
                        END SELECT
                CASE "-"
                        SELECT CASE Sel
                                CASE 1: IF Blue > 0 THEN Blue = Blue - 1
                                CASE 3: IF Red > 0 THEN Red = Red - 1
                                CASE 2: IF Green > 0 THEN Green = Green - 1
                        END SELECT

        END SELECT

 LOOP WHILE x$ <> CHR$(27)


END

If someone could point me in the right direction I'd appreciate it. When I find my error I will likely have a good chuckle at myself. FreeBASIC is great -- keep up the good work everyone!

(Forgot to mention I am using FreeDOS 1.0 under DOSEmu 1.4.0, under Slackware 12.1. Maybe that's the problem)
monty
Posts: 2
Joined: Sep 04, 2008 5:40

the problem may be in the FREEDOS kernel

Post by monty »

Hi, I had a problem similar to yours using FREEDOS (although not emulated) When tested the same app under MSDOS v.7 it worked as expected so I think the problem may be in FREEDOS and not in FB. Just my two cents.
darryl seamans
Posts: 14
Joined: Nov 14, 2008 5:58
Location: USA

Post by darryl seamans »

It does sound like a FreeDOS problem. Thanks Monty for the feedback! :)
DOS386
Posts: 798
Joined: Jul 02, 2005 20:55

bug

Post by DOS386 »

Why such a bloat to test a simple and obvious bug ?
darryl seamans wrote:It does sound like a FreeDOS problem.
Same bug on EDR-DOS. It does sound like a FreeBASIC bug with PALETTE command for DOS target. BTW, windows target works either perfectly (changes to red as supposed) or not at all (Page Fault).

I haven't submitted it into the tracker yet ... but I will later if this thread won't get any further attention.

EDIT : code deleted, see below
Last edited by DOS386 on Dec 04, 2008 2:06, edited 1 time in total.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Post by counting_pine »

I had a quick experiment in Windows 2000 - where it worked OK - and DOSBox - where it didn't.

One oddity I noticed was that the mouse cursor turned black when the color was set to 3F3F3F. Perhaps because it singled out color index 1 as the first "white" color?
Speculatively, I'd guess that's a side effect of an algorithm used for choosing the mouse colors, but it does indicate that the algorithm thinks the color has turned white...

I don't know how to fix this, and I'm guessing it's not an obvious solution if it works OK on some platforms, but someone else might...

If someone like DrV doesn't post here, by all means post a bug report.

Feel free also to dip into the source code at FreeBASIC/src/gfxlib2/dos, and see if you can spot anything that looks like it might be causing the problem.
DOS386
Posts: 798
Joined: Jul 02, 2005 20:55

Post by DOS386 »

There is no problem that couldn't be solved using inline ASM ;-) Obviously, the bug in FB isn't fixed that way.
counting_pine wrote:One oddity I noticed was that the mouse cursor turned black when the color was set to 3F3F3F. Perhaps because it singled out color index 1 as the first "white" color?
My mouse arrow gets red with color index 15 set to red using VGA ports.
side effect of an algorithm used for choosing the mouse colors, but it does indicate that the algorithm thinks the color has turned white
Funny. So the algorithm is supposed to find the most white and most black colors within the palette and use those 2 ?
counting_pine wrote:Feel free also to dip into the source code at FreeBASIC/src/gfxlib2/dos, and see if you can spot anything that looks like it might be causing the problem.
OK ... I don't see anything obvious for now, except that it's a bit less straightforward than my code above. And of course it writes to VGA ports, so it's unlikely that "buggy FreeDOS" could be source of the problem.

EDIT new code below
Last edited by DOS386 on Dec 06, 2008 8:13, edited 1 time in total.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Post by counting_pine »

I'd guess that when you use the asm method, FB doesn't realise when you change the palette, so I wouldn't expect the mouse cursor color to change from 15.
I haven't tested, but I expect Palette Get will return the original color. Similarly, if you set the color using Palette (not PALETE), then I expect Palette Get will return the color you set it to, rather then the color that appears on screen.
(At least I hope so, because I can't imagine what would be implied by any other behavior...)

By the way, on a semi-related note, I found the color choosing algorithm for the cursor - it's fb_hSoftCursorPaletteChanged(), and it can be found in gfxlib2/libfb_gfx_softcursor.c. It confirms my earlier musings about how the colors are chosen.
[EDIT] link: https://github.com/freebasic/fbc/blob/0 ... sor.c#L185

I think understanding the DOS code that writes the screen palette is going to be out of my depth though...
DrV
Site Admin
Posts: 2116
Joined: May 27, 2005 18:39
Location: Midwestern USA
Contact:

Post by DrV »

I assume the problem is the VESA palette set (src/gfxlib2/dos/libfb_gfx_vesa_core.c - fb_dos_vesa_set_palette_int10); using FBGFX=vga makes it work correctly. The code in that area is a definite mess already; probably something simple overlooked...
DOS386
Posts: 798
Joined: Jul 02, 2005 20:55

Post by DOS386 »

Code: Select all

'' Palette [get] [index, color]
'' Palette [get] [index, r, g, b]
'' Palette [get] Using arrayname(idx)

#DEFINE CO 14

type UINT32  as UINTEGER
type UINT8   as UBYTE

'' Note the horrible "tt"-typo below :-(
SUB PALETE (BYVAL AA AS UINT8, BYVAL BB AS UINT32)
  ASM
    mov  dl, 0xC8
    mov  dh, 3     '' MOV DX, 0x03C8
    mov  al, [AA]
    out  dx, al    '' Index
    inc  edx       '' MOV DX, 0x03C9
    mov  eax, [BB]
    out  dx, al    '' R
    shr  eax, 8
    out  dx, al    '' G
    shr  eax, 8
    out  dx, al    '' B
  END ASM
END SUB

SUB PALGET
  DIM AS UINT32 CC, DD, EE, FF
  PALETTE GET CO, CC '' Peek RBG into CC
  DD=0
  DO
    EE = CC AND 7 : CC = CC SHR 4 : FF = 650-DD*100
    CIRCLE (FF,100), 42, 3, , , , F
    CIRCLE (FF,100), 40, 0, , , , F
    CIRCLE (FF,100), (EE*2), 2, , , , F
    DD = DD + 1 : IF (DD=6) THEN EXIT DO
  LOOP
END SUB

'' Note: color 15 is the while of mouse arrow
SCREENRES 800, 600, 8
CIRCLE (400,300), 200, 1 , , , , F
LOCATE 34, 26 : COLOR CO
PRINT "Press any key to change my color W->R->Gr-!>Gy-!>B"
PALGET : SLEEP
PALETE CO, &H00003F '' Now change color "CO" to bright red using VGA
PALGET : SLEEP
PALETE CO, &H003F00 '' Now change color "CO" to bright green using VGA
PALGET : SLEEP
PALETTE CO, &H1F1F1F '' Now change color "CO" to grey using FB
PALGET : SLEEP
PALETTE CO, &H3F0000 '' Now change color "CO" to bright blue using FB
PALGET : SLEEP

END
Post Reply