How to use 24-bit colours in the Wimp
Terje Slettebø (285) 275 posts |
Update: I found the problem: When calling “ColourTrans_SetGCOL”, you must make sure that R3 and R4 are set to 0, or you risk random effects. The following must seem like quite a newbie question, but I’m confused about the colour handling in RISC OS 5. I grew up with RISC OS on the Archimedes, and colour handling there was simple: You used a “colour number” which mapped to a palette entry, or you used a “Wimp colour”. However, having searched both the PRMs (including 5a), as well as the documentation on this site, I’m unable to figure out how to specify a 24-bit colour (either to be used directly, or to be converted to the nearest available colour) for the Wimp. I’d think that Wimp_SetColour would be the most appropriate call to use, but in the documentation, it has no provision for specifying a 24-bit colour, so I’ve tried ColourTrans_SetGCOL instead. Here’s a small test program, assuming a 24-bit mode: SYS “ColourTrans_SetGCOL”,&0000FF00: REM &BBGGRR00 When using StrongED and running this in the desktop, I get a black filled circle on a white background. However, if I run it outside the desktop, I get a red filled circle, as expected. When I run the same code in my application, in response to a redraw request, I get a grey (!) filled circle. I’m at a loss to understand what is going on here, any help appreciated. |
Charles Ferguson (8243) 427 posts |
a) Deleting posts when you’ve found the answer is unhelpful to others in the future – you had a problem and you found a solution… so don’t erase its existance. Someone else might find it useful in the future. b) I do not believe that your reasoning was actually correct, or at least the statement of what the problem was is not quite correct. In BASIC, all SYS calls set registers which have not been supplied to 0, so your comment about the reason that you had problems is incorrect, I believe – but this is assuming that you were using BASIC as that was the example you supplied. You haven’t stated how you were running the test code, but I shall guess that you were running it by having a BASIC program that you were either double clicking on, or invoking through *Filer_Run or WimpTask within StrongEd, and those instances were when you were seeing the black circle. The instances when you ran it outside the desktop, I will guess are when you dropped to the command line, and executed something like `/mytestprog’. In the latter case, there is nothing to get in the way of you, so everything works fine. In the former case, there is a pending Wimp_CommandWindow. The Wimp_CommandWindow is marked as pending when a new environment has been created by the WindowManager (through WimpTask or Wimp_StartTask) before the execution of the *Command that was passed. Its job is to ensure that should you not start a Wimp task by calling Wimp_Initialise, a window appears with the content of your output in, hopefully without any interaction problems. It cannot do this perfectly. The result is that you should clear the pending Wimp_CommandWindow flag with SWI Wimp_CommandWindow (I forget which number it is in R0; I’m going to have a stab at -1 as I’m pretty sure that is ‘close if it was open, ignore otherwise, never prompt’). If you do this at the start of your program, you will see that the shape becomes red. So…. why does the existance of the pending command window cause this to fail? The command window is implemented by trapping the VDU vector. If it sees any output happening, it jumps in and creates the representation of a desktop window using the current environment as the title, sets up the text window to be within its bounds, and then removes itself from the vector. The pending window flag is cleared and vector released if you change mode and (I think) a couple of other things. So… again, why does this cause the colour to fail? The sequence of your code is…
So that explains the black shape, and how to avoid it, and why the out-of-desktop case works. It doesn’t explain the grey circle. Given your comment about having to set the registers as described in the PRM, rather than leaving them randomised, I’m going to guess that you were actually writing your application code in C, not in BASIC, as in BASIC the registers would always have been set. And that would (potentially) explain the grey filled circle (if the colour being selected ended up actually being the background colour, not the foreground colour, so you got whatever was left behind, OR the action ended up being an odd one), and why setting those registers to 0 fixed it. PS. Can’t the Wimp preserve this state before it messes with things? Possibly, but it’s much more ugly behind the scenes than I’ve described here, and … in just trying to work out how I’d do it, I’m a few layers deep in the problems with the output system before I decide I give up. |
Rick Murray (539) 13840 posts |
Yeah, my OLED module has a nasty hack where it calls WimpInit, then sets up the display panel, then calls WimpCloseDown. Why? Because the OLED driver makes VDU calls to a redirected sprite and the Wimp notices. At least doing it like that gets a simple redraw rather than a prompt requiring user input (which is useless if it’s booting an unattended machine). Kind of wish the Wimp would notice the VDU being redirected and retract its tentacles, but, c’est la vie… |
André Timmermans (100) 655 posts |
Yup, the absence of VDU contexts at system level brings in al kinds of bugs and side effects: |
Charles Ferguson (8243) 427 posts |
Just use `Wimp_CommandWindow, -1` to disable the pending window? |