Sprites file being loaded instead of Sprites22
Andrew Rawnsley (492) 1445 posts |
In several of our apps, we include both Sprites and Sprites22 files (not to be confused with Sprites22). In OS versions up to 5.20 and (I assume) 5.21 until alpha-sprites, the Sprites22 file was used for sprites on square pixel screenmodes. All well and good. In recent releases these programs are opting for “Sprites” over “Sprites22”. This, of course, looks nasty, as “Sprites” is designed for rectangular pixel modes. The solution seems to be to include “SpritesA2”, which is certainly possible for actively developed software. However, surely it must be a bug for “Sprites” to be preferred to “Sprites22” in square pixel modes? I like the idea of SpritesA2, but surely only when alpha sprites are being used. It shouldn’t break the functionality of existing apps which supply (in this case, Sprites, Sprites11 and Sprites22). |
Andrew Rawnsley (492) 1445 posts |
Further to previous report, this can easily be demonstrated by running !Patience in diversion. This has Sprites and Sprites22 files. Sprites will be used, resulting in poor quality graphics. Copying the Sprites22 file to SpritesA2 restores the higher quality playing card visuals. |
David Pitt (102) 743 posts |
!Patience has the advantage of being in uncrunched BASIC so it is easy to see what is going on. “Wimp_ReadSysInfo”,2 is returning “A2”, the decision making on which Sprite file is made by the program itself, a Reporter command has been added to see what that is. b$="<Patience$Dir>.Sprites":a$=b$ SYS"XWimp_ReadSysInfo",2 TO R0;V:IF(V AND 1)=0 a$+=CHR$?R0+CHR$R0?1 *report a$ S%=OPENINa$:IFS%=0 a$=b$:S%=OPENINa$ T%=EXT#S%+16:CLOSE#S% a$="<Patience$Dir>.SpritesA2" *iconsprites might automatically find the appropriate !Sprites suffix but should the above OPENIN also do so? |
Andrew Rawnsley (492) 1445 posts |
Thanks for checking into that, David – much appreciated. This would suggest to me that Wimp_ReadSysInfo 2 should probably have been modified a little differently, returning traditional values in R0 and alpha values in R1, much as Wimp_ReadSysInfo 16, 23, 24 etc do. This would ensure correct operation of legacy applications, whereas new applications using alpha sprites would be able to take advantage of the R1 suffix (if available). This would also fit as the ability to display alpha sprites is a property of the OS version, not of the wimp mode. |
Colin (478) 2433 posts |
Unfortunately r1 is undefined for Wimp_ReadSysInfo 2 so a program which read r1 would have undefined behaviour if used on a different os version. You could use a new wimp_readsysinfo number which presumably would fail with an error if the OS didn’t understand it. |
Colin (478) 2433 posts |
Duplicated |
Rick Murray (539) 13840 posts |
Mmm, the law of unintended consequences? Seems to me that programs will have one of two specific failure modes:
Maybe the ReadSysInfo call should have a “magic value” to select advanced (A2) or regular (22) behaviour? |
Andrew Rawnsley (492) 1445 posts |
Good point Colin. However, I’d suggest it may not matter. If the programmer’s note for R1 in the online PRM points this out, it could make it clear that the only valid return values begin with A (eg. A or A2 etc). It seems extremely unlikely that a previous OS would thus return a valid string in R1. If the programmer’s note went on to suggest a graceful fallback if such a file didn’t exist, then a person coding for alpha sprites could pseudo code: Wimp_ReadSysInfo 2; Sanity check(R1); if(file_exists(R1) && R1!=0 ) use R1; else if(file_exists(R0)) use R0; else error, exit;If not using R1, then old code would be unaffected, so pseudo code would be Wimp_ReadSysInfo 2; if(file_exists(R0)) use R0; else error, exit;I can’t think of a cleaner method, other than some magic character prefixing R1, but there’s always the small possibility that random leftovers could match the magic character/string so you’ll always need some kind of “if there” wrapper on using the result anyway. I’m open to better suggestions, obviously. But the status quo demonstratably breaks existing software, which cannot be preferable. Edit – sorry, for some reason the board is running together my pseudo-code lines, despite me putting two newlines between them. I hope the semi-colons make it a bit readable. |
Rick Murray (539) 13840 posts |
I’m not sure there are so many chances of a string matching “ALFA” (well, it’s got to be four characters, right?). The Wimp seems quite happy to use “TASK” as a magic value in other places… To be honest, the most workable solution, ultimately, is likely to be to restore Wimp_ReadSysInfo 2 to its expected behaviour, and to create a new code for the alpha sprites version. [maybe not – see below] Reason 1: To quote the PRM (PDF p226) – “(When loading sprite files containing icons, the suffix should be tried; if the file does not exist, try the original filename.)” – which means scores of things will be looking for a non-existent sprites file and reverting to the non-suffixed (low-res) version. Reason 2: The SWI call documentation states that R0 takes a value and a result is returned in R0. It does not mention that any other registers are involved or are corrupted, with the specific exception of R1 if R0 on entry is #5. There is a slim chance that software using this SWI will not have preserved R1; so redefining the API to include R1 is liable to cause problems for some software. [it’s the same reason why we can’t just whack mouse scroll wheel states into OS_Mouse] Actually, having thought about this for a few moments while writing this – how about the following: Since the filename suffix is a pointer (not the data itself); how about returning something like “22<null>!A2<null><null>”? |
Andrew Rawnsley (492) 1445 posts |
That sounds like a possibility, Rick :) Perhaps slightly fiddlier to code, but I grant you it may be the best solution. Certainly your suggestion is much better than the status quo. My reasoning behind R1 was that a quick look at the ROOL docs showed a number of other Wimp_ReadSysInfo calls using R1 (5, 8, 23, 24, 25 and 26), but equally I don’t know if the R1 usage has ever been added after-the-fact before. I’m not sure what you meant by “Some software may not be preserving R1… so may cause some problems” – surely if they’re not preserving it, they won’t be accessing it, so it wouldn’t matter either way? The only time you’d access R1 for ReadSysInfo2 would be in a modern program looking for confirmation to use Alpha. Since you would be checking R1, you’d preserve it. If you weren’t going to check it, it wouldn’t matter… would it? Perhaps I’m being thick here (I’m feeling quite sleepy – it’s time for bed). |
Rick Murray (539) 13840 posts |
When you call a SWI call known to use or corrupt registers, you should save those registers – if they are important to you – on the stack, do the SWI call stuff – then retrieve your originals. This is what I mean by preserving. It isn’t a contrived example. One of my programs does almost exactly the same thing. It would not consequently fail to work with A2 sprites and revert to low resolution; it would instead probably crash because the sprites pointer in R1 would become corrupted by something unexpected.
What concerns me, in addition to the breakage of older programs, is the fact that we risk a lot of contemporary software being hardwired with assumptions. If the returned sprite suffix is A2, then this will downgrade to 22. However we should never be hardcoding this into our programs. What if some future version of RISC OS presents an “A3” or maybe a “B2” (for alpha overlay on a different video plane)? What do those degrade to? To extend the data returned by the call would seem to be the simplest way to address the problem, and for future proofing, we could even specify that the protocol is: |
Rick Murray (539) 13840 posts |
To clarify, in Edit style, the data back from ReadSysInfo would look like this today : One day in the future, it might become this: For reference, programs currently expect this: |
Steve Fryatt (216) 2105 posts |
The problem is that the RISC OS way is to define which registers are corrupted on return from a SWI, and allow the programmer to assume that others will not be. The very fact that R1 has not been changed up to now means that — particularly in hand-written stuff — it’s likely that a value which needs to be remembered across the call will be stuffed into R1 so that it doesn’t get lost. If the SWI now starts returning a value in R1, that won’t work any more — and software will break when the values put into R1 for safe keeping don’t remain intact. |
Sprow (202) 1158 posts |
Take a look at Wimp_Extend 13, that takes a path to a (base) sprite filename and applies the same hunting algorithm to select the best suffix as *ICONSPRITES does. If Wimp_Extend 13 isn’t available you can fall back to Wimp_ReadSysInfo 2. That probably implies Wimp_ReadSysInfo 2 should return the non ‘A’ variation on the suffix, since Wimp_Extend 13 was introduced for RISC OS 5.00 and that predates the alpha support in RISC OS 5.21. Wimp_Extend 13 is also available back to RISC OS 3.10 if you’ve got a recent !Boot, which includes a softloaded Wimp. |
Jeffrey Lee (213) 6048 posts |
Changing Wimp_ReadSysInfo 2 to not return ‘A’ strings sounds OK to me. I’ll make the change sometime in the next day or two, unless someone objects. |
Jeffrey Lee (213) 6048 posts |
Now done. I’ve also added Wimp_ReadSysInfo 29 which will return a flag in R0 to indicate whether the Wimp will try and use alpha sprites or not, so software which needs to work out whether alpha sprites are supported can just check that flag instead of implementing its own checks. I’ve also added an implementation of ROL’s Wimp_Extend 257, which is basically the same as our Wimp_Extend 13, so is a good choice if you’re writing software targeting both OS versions. |