Author |
Topic: RISC OS Sprite reader (Read 1305 times) |
|
hellomike
Junior Member
member is offline


Gender: 
Posts: 55
|
 |
Re: RISC OS Sprite reader
« Reply #4 on: Jun 20th, 2017, 08:07am » |
|
Ah, OK. Sorry for the confusion. I mentioned VirtualRPC to clarify why I would have a bunch of RISC OS sprite files.
Although those sprite files are created and maintained under RISC OS, I need to access them in Windows using BB4W.
Thanks for the link to the post, it might be useful.
The Acorn sprites I need to handle are simple ones in which I don't need to consider masks and <100k. Shouldn't be too difficult to convert although I'm not yet familiar with the BMP format. I assume BMP is the most logical (documented) format to convert to as it can be discarded after displaying it in a window.
Maybe its even possible to read a pixel from the sprite file and then PLOT 69 it to the screen!
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 803
|
 |
Re: RISC OS Sprite reader
« Reply #5 on: Jun 20th, 2017, 08:35am » |
|
on Jun 20th, 2017, 08:07am, hellomike wrote:| Although those sprite files are created and maintained under RISC OS, I need to access them in Windows using BB4W. |
|
Let me see if I have understood properly. You could convert them to BMP format in RISC OS but you prefer not to because they are actively maintained so you would need to repeat the conversion after every alteration, is that right?
In that case would it not be possible to create the RISC OS equivalent of a 'batch' or 'command' file that converts all your sprites into BMP in an automated way? Then all you would need to do is to run that process whenever you need the BMP versions of the sprites.
Quote:| The Acorn sprites I need to handle are simple ones in which I don't need to consider masks |
|
BMP format doesn't support masks (except for non-standard extensions using 32-bit ARGB pixels); in the Windows world you need to use an icon (.ICO) or cursor (.CUR) file for that.
Writing your own conversion routine from scratch would, I fear, be a lot of work, especially if you want it to handle the full range of options for size, colour depth etc. I would find it difficult myself, and I have years of experience of creating and working with BMP files.
Richard.
|
|
Logged
|
|
|
|
hellomike
Junior Member
member is offline


Gender: 
Posts: 55
|
 |
Re: RISC OS Sprite reader
« Reply #6 on: Jun 20th, 2017, 8:24pm » |
|
Quote:| You could convert them to BMP format in RISC OS but you prefer not to because they are actively maintained |
|
That's correct.
Let me be more specific. - believe it or not but I still maintain my vinyl and CD collection data, like title, price, date purchased etc, in !MultiStor in RISC OS (via VirtualRPC) - this data includes a cover art picture which !MultiStor stores as a path where the sprite is located on the hard disk - with a BASIC V program I once made, which sequentially reads the !MultiStor database and copies all the data to one big flat ASCII file (currently just 750Kb) and I run this program after each edit in the !MultiStor database (takes only a few seconds) - now, when I want to see the data, for a certain album title in Windows, I just read that data from the ASCII flat file
However when entering the album title in Windows, in addition to date purchased etc I also want to see what cover art is used for that title. From the ASCII file I can get the path to the sprite file but.... how to display that cover art from that sprite file in Windows?
Quote:| I would find it difficult myself |
|
Coming from someone who wrote a full blown very powerful interpreter all is assembly language and a lot of image processing code, that means I won't have a chance....
Then again, those sprite files are of the simplest form because !MultiStor is rather primitive in what it can handle. The most complex ones are 221 by 221, Mode 21, 48Kb, no palette, no mask, x90, y90. That's it! So I have no need for covering the full range like any size, colour depth etc. None of that.
That's why I feel that it's doable to write real-time conversion when I want to display the sprite using BB4W.
I just started this thread to see if maybe someone already covered this.
Do you think even simple sprites like I mentioned are difficult to encipher?
Thanks
Mike
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 803
|
 |
Re: RISC OS Sprite reader
« Reply #7 on: Jun 21st, 2017, 11:35am » |
|
on Jun 20th, 2017, 8:24pm, hellomike wrote:| Coming from someone who wrote a full blown very powerful interpreter all is assembly language and a lot of image processing code... |
|
The interpreter you speak of was written in 1982, or thereabouts, in Z80 assembler code and has been semi-automatically translated since then - initially (in 1986) to 16-bit x86 code (with the help of Jeffrey Raynor and Brandon Butterworth, I should add) and then (in 2000) to IA-32 code for Windows. There's no way I could write anything like that now. 
Also, contrary to your comment, it contains no image processing code at all because everything is offloaded to the Windows GDI. All I had to write was a simple 'wrapper' to convert VDU commands to the appropriate calls to GDI32.DLL.
Quote:| Do you think even simple sprites like I mentioned are difficult to encipher? |
|
It's hard for me to say, not knowing anything about Acorn sprites. Judging by Jeroen's comments it was the mask he found most difficult, so if your images have no masks it should be easier.
Richard.
|
|
|
|
hellomike
Junior Member
member is offline


Gender: 
Posts: 55
|
 |
Re: RISC OS Sprite reader
« Reply #8 on: Jun 21st, 2017, 11:52am » |
|
With image processing code I was referring to something a read about you making software for converting B&W footage to colour. That must have involved some thorough knowledge of image processing.
Yeah, I know. It's pretty frustrating getting old(er) and realising many skills are fading. Turning 55 myself in a month.
At least you have quite an impressive legacy. For me it's just a 2048 clone
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 803
|
 |
Re: RISC OS Sprite reader
« Reply #9 on: Jun 21st, 2017, 1:37pm » |
|
on Jun 21st, 2017, 11:52am, hellomike wrote:| With image processing code I was referring to something a read about you making software for converting B&W footage to colour. |
|
OK, but that was nine years ago, when I was approximately the same age as you are now (I've just turned 65)! The decline in my faculties in that period has been very marked.
Quote:| That must have involved some thorough knowledge of image processing. |
|
Not in a general sense, no. One of the things I specialised in during my career was filtering, and the Colour Recovery process consists of many filtering steps - some one-dimensional and some two-dimensional. You've also likely seen my online document on 'A Frequency Domain approach to Scaling'.
But ask me to do a more conventional image-processing task, such as tools like Photoshop, Gimp and ImageMagick do, and I wouldn't know where to start!
Richard.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 803
|
 |
Re: RISC OS Sprite reader
« Reply #11 on: Jun 22nd, 2017, 08:20am » |
|
on Jun 22nd, 2017, 07:54am, IanKings wrote:| A bit off BBC BASIC topic but here are two links that may assist you in writing a BBC BASIC version, both work well. |
|
A simpler alternative (hardly any work) would be to compile the linked C code to a Windows DLL and call that from BBC BASIC using SYS.
Richard.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 803
|
 |
Re: RISC OS Sprite reader
« Reply #12 on: Jun 22nd, 2017, 5:05pm » |
|
on Jun 22nd, 2017, 08:20am, Richard Russell wrote:A simpler alternative (hardly any work) would be to compile the linked C code to a Windows DLL |
|
Here you go. This file contains the compiled DLL (rosprite.dll) an example BBC BASIC program showing how to use it (rosprite.bbc) and a sample Acorn sprite file (sample.ff9, containing 40 icons) to test it.
I've not experimented with palettes or masks, but unless the 'librosprite' library has a fault they should work.
Please note that 'rosprite.bbc' is not compatible with lowercase keywords (and I don't care!).
Richard.
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 803
|
 |
Re: RISC OS Sprite reader
« Reply #13 on: Jun 22nd, 2017, 7:56pm » |
|
on Jun 22nd, 2017, 5:05pm, Richard Russell wrote:| an example BBC BASIC program showing how to use it (rosprite.bbc) |
|
Further, if you want to convert an Acorn sprite to a BMP file the above program could be adapted to do this very quickly (no per-pixel processing) but it wouldn't support masks properly. Let me know if you would like me to do that.
Richard.
|
|
Logged
|
|
|
|
hellomike
Junior Member
member is offline


Gender: 
Posts: 55
|
 |
Re: RISC OS Sprite reader
« Reply #14 on: Jun 23rd, 2017, 08:46am » |
|
Thanks to Ian for pointing out this useful source!
With the documentation at PRM 1-749, I managed to identify the Sprite Control Block format and wrote code for listing all the Sprite names in a sprite file. So far, so good.
Then after finding the link to the C-source I knew I had to change plans. Then, while thinking about that, Richard provides the DLL en BB4W example code! Now and then I play with C-code to speed things up, but noting more complex than compiling to an object file and then linking to get an executable. Wouldn't know how to compile to DLL and I'm very bad in using Project and/or make files. What did you compile it with Richard, GCC?
So, new approach again. I will check the DLL and its functionality.
Thanks to all.
Mike
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 803
|
 |
Re: RISC OS Sprite reader
« Reply #15 on: Jun 23rd, 2017, 1:19pm » |
|
on Jun 23rd, 2017, 08:46am, hellomike wrote:| Wouldn't know how to compile to DLL and I'm very bad in using Project and/or make files. |
|
It was trivial in this case, and I'm not a C programmer. I just added __attribute__ (dllexport) to the functions I wanted to be exported, and compiled it with the -shared switch, and it just worked: no warnings, no issues of any kind. I hadn't expected it to be that simple but fortunately the gods were kind to me on this occasion.
I wouldn't be surprised if the calling conventions (ABI) are not what you would normally expect for a DLL - I didn't add any stdcall directives - but BB4W is pretty tolerant and will call either stdcall or cdecl functions equally well.
Quote:| What did you compile it with Richard, GCC? |
|
Yes. The librosprite stuff looked to be primarily intended for use in Linux so that seemed to be the best bet, and so it proved.
You didn't react to my offer of adapting the program to convert the Acorn sprite to BMP files, but I've done it anyway! I thought it would be easier to do it whilst it's on my mind; my dreadful short-term memory means I might have had to start from scratch if I had waited. Here it is:
Code: REM Example code for loading an Acorn sprite using 'rosprite.dll' REM Richard Russell, http://www.rtrussell.co.uk/, 23rd June 2017 REM Based on 'example.c' Copyright 2008 James Shaw <js102@zepler.net> REM Constants: ROSPRITE_OK = 0 ROSPRITE_RGB = 0 ROSPRITE_CMYK = 1 BI_BITFIELDS = 3 REM Load rosprite.dll: SYS "LoadLibrary", "rosprite" TO rosprite% SYS "GetProcAddress", rosprite%, "rosprite_create_file_context" TO `rosprite_create_file_context` SYS "GetProcAddress", rosprite%, "rosprite_destroy_file_context" TO `rosprite_destroy_file_context` SYS "GetProcAddress", rosprite%, "rosprite_create_mem_context" TO `rosprite_create_mem_context` SYS "GetProcAddress", rosprite%, "rosprite_destroy_mem_context" TO `rosprite_destroy_mem_context` SYS "GetProcAddress", rosprite%, "rosprite_file_reader" TO `rosprite_file_reader` SYS "GetProcAddress", rosprite%, "rosprite_mem_reader" TO `rosprite_mem_reader` SYS "GetProcAddress", rosprite%, "rosprite_load" TO `rosprite_load` SYS "GetProcAddress", rosprite%, "rosprite_destroy_sprite_area" TO `rosprite_destroy_sprite_area` SYS "GetProcAddress", rosprite%, "rosprite_load_palette" TO `rosprite_load_palette` SYS "GetProcAddress", rosprite%, "rosprite_destroy_palette" TO `rosprite_destroy_palette` REM Define structures: DIM rosprite_area{extension_size%, extension_words%, sprite_count%, sprites%} DIM rosprite_mode{colorbpp%, maskbpp%, mask_width%, xdpi%, ydpi%, color_model%} DIM rosprite_palette{size%, palette%} DIM rosprite{name&(12), pad1&(2), mode{}=rosprite_mode{}, has_mask&, has_palette&, \ \ pad2&(1), palette{}=rosprite_palette{}, width%, height%, image%} DIM BMPfile{bfType{l&,h&}, bfSize%, bfReserved%, bfOffBits%, \ BITMAPFILEHEADER \ biSize%, biWidth%, biHeight%, biPlanes{l&,h&}, biBitCount{l&,h&}, \ \ biCompression%, biSizeImage%, biXPelsPerMeter%, biYPelsPerMeter%, \ \ biClrUsed%, biClrImportant%, dsBitfields%(2)} REM Sprite filename: sprite$ = @dir$ + "sample.ff9" PRINT "Loading "; sprite$ REM Load Acorn sprite file into memory: sprite% = OPENIN(sprite$) IF sprite% = 0 ERROR 100, "Couldn't open sprite file " + sprite$ size% = EXT#sprite% CLOSE #sprite% DIM memory% size% OSCLI "LOAD """ + sprite$ + """ " + STR$~memory% REM Get a memory context for the sprite file: SYS `rosprite_create_mem_context`, memory%, size%, ^ctx% REM Load the sprite file: SYS `rosprite_load`, `rosprite_mem_reader`, ctx%, ^sprite_area% TO res% IF res% <> ROSPRITE_OK ERROR 100, "Error loading spritefile" REM Print information about the sprite file: !(^rosprite_area{}+4) = sprite_area% PRINT "sprite_count = "; rosprite_area.sprite_count% PRINT "extension_size = "; rosprite_area.extension_size% REM Print information about and display each image: FOR I% = 0 TO rosprite_area.sprite_count%-1 PRINT '"Press a key to continue... " : IF GET CLS PRINT "Sprite "; I% ;":" !(^rosprite{}+4) = rosprite_area.sprites%!(I%*4) PRINT " name = "; rosprite.name&() CASE rosprite.mode.color_model% OF WHEN ROSPRITE_RGB: PRINT " color_model = RGB" WHEN ROSPRITE_CMYK: PRINT " color_model = CMYK" ENDCASE PRINT " colorbpp = "; ~rosprite.mode.colorbpp% PRINT " xdpi = "; rosprite.mode.xdpi% PRINT " ydpi = "; rosprite.mode.ydpi% PRINT " width = "; rosprite.width% PRINT " height = "; rosprite.height% PRINT " hasPalette = "; rosprite.has_palette& IF rosprite.has_palette& PRINT " palettesize = "; rosprite.palette.size% PRINT " hasMask = "; rosprite.has_mask& IF rosprite.has_mask& PRINT " mask_width = "; rosprite.mode.mask_width% IF rosprite.has_mask& PRINT " mask_bpp = "; rosprite.mode.maskbpp% REM Convert to BMP format and save: BMPfile.bfType.l& = ASC"B" BMPfile.bfType.h& = ASC"M" BMPfile.bfSize% = DIM(BMPfile{}) + 4 * rosprite.height% * rosprite.width% BMPfile.bfOffBits% = DIM(BMPfile{}) BMPfile.biSize% = 40 BMPfile.biWidth% = rosprite.width% BMPfile.biHeight% = rosprite.height% BMPfile.biPlanes.l& = 1 BMPfile.biBitCount.l& = 32 BMPfile.biCompression% = BI_BITFIELDS BMPfile.biSizeImage% = 4 * rosprite.height% * rosprite.width% BMPfile.biXPelsPerMeter% = rosprite.mode.xdpi% * 1000 / 25.4 + 0.5 BMPfile.biYPelsPerMeter% = rosprite.mode.ydpi% * 1000 / 25.4 + 0.5 BMPfile.dsBitfields%(0) = &FF000000 BMPfile.dsBitfields%(1) = &00FF0000 BMPfile.dsBitfields%(2) = &0000FF00 bmpfile$ = @tmp$ + rosprite.name&() + ".bmp" bmpfile% = OPENOUT(bmpfile$) SYS "WriteFile", @hfile%(bmpfile%), BMPfile{}, DIM(BMPfile{}), ^temp%, 0 span% = rosprite.width% * 4 FOR Y% = rosprite.height%-1 TO 0 STEP -1 SYS "WriteFile", @hfile%(bmpfile%), rosprite.image% + span% * Y%, span%, ^temp%, 0 NEXT CLOSE #bmpfile% OSCLI "DISPLAY """ + bmpfile$ + """" OSCLI "DISPLAY """ + bmpfile$ + """ 800,0," + STR$(rosprite.width% * 8) + \ \ "," + STR$(rosprite.height% * 8) NEXT I% REM Clean up: SYS `rosprite_destroy_mem_context`, ctx% SYS `rosprite_destroy_sprite_area`, sprite_area% END As discussed, BMPs don't support a mask (the 'alpha' values are present in the generated file, in the LS bytes of the 32-bit pixels, but no standard BMP reading software will take any notice of them).
Strictly speaking the sprite file should probably be converted not to a set of .BMPs but to a .ICO (which can hold multiple images and supports masks) but unfortunately the RGBA format in which librosprite returns the images is not at all convenient for that.
Richard.
|
|
|
|
hellomike
Junior Member
member is offline


Gender: 
Posts: 55
|
 |
Re: RISC OS Sprite reader
« Reply #16 on: Jun 24th, 2017, 09:22am » |
|
Quote:| I wouldn't be surprised if the calling conventions (ABI) are not what you would normally expect for a DLL - I didn't add any stdcall directives - but BB4W is pretty tolerant and will call either stdcall or cdecl functions equally well. |
|
Indeed that already would be one of my concerns if 'it' would compile and link with correct calling conventions. Also I'm unaware that something like "__attribute__ (dllexport)" would make it compile as DLL.
I didn't react to the offer yet as I was still trying to grasp the new info sofar. Filling the BMPfile{} structure the correct way is interesting as well.
All in all, the above was a nice exercise. Maybe nice for a Wiki article explaining how to turn a simple C-program into a DLL so that the code can be used in BB4W via SYS.
Thanks for all the new insights.
Mike
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 803
|
 |
Re: RISC OS Sprite reader
« Reply #17 on: Jun 24th, 2017, 1:17pm » |
|
on Jun 24th, 2017, 09:22am, hellomike wrote:| compile and link with correct calling conventions. |
|
I think your concern may be misplaced. It's not really a case of 'correct' or 'incorrect' calling conventions; I've come across several DLLs that have a 'non-standard' ABI but so long as they are used in the context of a specific application (as in this case being intended for use with BB4W) I don't see that as a problem.
The BOX2DBBC DLL uses an even less standard calling convention, one that even SYS cannot call straightforwardly, but since it is intended to be used only with the BB4W BOX2D library again I don't see that as an issue.
Quote:| Also I'm unaware that something like "__attribute__ (dllexport)" would make it compile as DLL. |
|
Google is your friend. Although I'd done it several times before, I couldn't remember anything about how to make a DLL, so I just looked it up. The only thing that makes my memory-loss manageable is Google - it's interesting (and slightly disconcerning) how often my searches find a reference that I myself have posted or published, but which I've subsequently completely forgotten about!
Quote:| Maybe nice for a Wiki article explaining how to turn a simple C-program into a DLL so that the code can be used in BB4W via SYS. |
|
I'm not too sure how that is different from "how to turn a simple C program into a DLL" which is something very easily found already. The "so that the code can be used in BB4W via SYS" doesn't really impose any extra constraints, other than the ABI issue; stdcall and cdecl are both fine.
But feel free to write such a BB4W Wiki article and copy/adapt the information you can find elsewhere, so long as Copyright restrictions permit you to do so.
Richard.
|
|
Logged
|
|
|
|
|