BitMapScale
sonountalebanJunior Member
Posted 2 months agoHello,
I'm trying to use BitMapScale for my porting of System Shock and it doesn't look right what I got...

It seems it shows just the channel blue, discarding the red and the green. There is a lack of documentation of this function (by the way is it a genuine AmigaOS 3.1 function?) and the only one example I found for AROS didn't help me much.
The source bitmap has been created using AllocBitMap with these flags (BMF_CLEAR | BMF_INTERLEAVED | BMF_MINPLANES) and no "friend bitmap", while the dest bitmap is the one associated with the RastPort of the main window. All have 8 as depth.
I'm trying to use BitMapScale for my porting of System Shock and it doesn't look right what I got...

It seems it shows just the channel blue, discarding the red and the green. There is a lack of documentation of this function (by the way is it a genuine AmigaOS 3.1 function?) and the only one example I found for AROS didn't help me much.
Code Download source
struct BitScaleArgs bms_args;
bms_args.bsa_SrcBitMap = pMainScreenRastPort->BitMap;
bms_args.bsa_DestBitMap = pMainRastPort->BitMap;
bms_args.bsa_Flags = 0;
bms_args.bsa_SrcWidth = gWindowWidth;
bms_args.bsa_SrcHeight = gWindowHeight;
bms_args.bsa_SrcX = 0;
bms_args.bsa_SrcY = 0;
bms_args.bsa_DestX = 0;
bms_args.bsa_DestY = 0;
bms_args.bsa_XSrcFactor = gWindowWidth;
bms_args.bsa_XDestFactor = gScreenWidth;
bms_args.bsa_YSrcFactor = gWindowHeight;
bms_args.bsa_YDestFactor = gScreenHeight;
BitMapScale(&bms_args);
The source bitmap has been created using AllocBitMap with these flags (BMF_CLEAR | BMF_INTERLEAVED | BMF_MINPLANES) and no "friend bitmap", while the dest bitmap is the one associated with the RastPort of the main window. All have 8 as depth.
Edited by sonountaleban on 25-01-2026 06:17, 2 months ago
deadwoodAROS Dev
Posted 2 months agoHard to say what's wrong without debugging. I can be a driver-specific issues.
If you can provide the smallest possible usecase which just creates the bitmap, fills it with something and then scales, I could try debugging what is going on. Alternativelly I could guide you how to debug this yourself (since you are using hosted AROS anyhow).
If you can provide the smallest possible usecase which just creates the bitmap, fills it with something and then scales, I could try debugging what is going on. Alternativelly I could guide you how to debug this yourself (since you are using hosted AROS anyhow).
1 user reacted to this post
sonountaleban
sonountalebanJunior Member
Posted 2 months agoI tried on native AROS and it looks the same. The function I use to do rendering in window mode (BltBitMapRastPort) works well as usual. I've noticed that SetRGB32 calls seem are ignored, even I fill the palette with 256 whites, I already got blue images...
I'm opening screen/window in this way:
You said I could debug on host AROS, how could I do it? Thanks.
I'm opening screen/window in this way:
Code Download source
pMainScreen = OpenScreenTags(NULL,
SA_Left, 0, SA_Top, 0, SA_Width, width, SA_Height, height, SA_Depth, 8,
SA_Type, CUSTOMSCREEN,
SA_ShowTitle, FALSE,
SA_Quiet, TRUE,
SA_Exclusive, TRUE,
SA_SysFont, 1,
TAG_DONE);
if (!pMainScreen)
{
ERROR("Failed to create the main screen");
exit(1);
}
gScreenWidth = pMainScreen->Width;
gScreenHeight = pMainScreen->Height;
pMainWindow = OpenWindowTags(NULL,
WA_Left, 0, WA_Top, 0, WA_Width, gScreenWidth, WA_Height, gScreenHeight,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_RAWKEY,
WA_Flags, WFLG_ACTIVATE | WFLG_SMART_REFRESH | WFLG_REPORTMOUSE | WFLG_BORDERLESS,
WA_RMBTrap, TRUE,
WA_CustomScreen, pMainScreen,
TAG_DONE);
gWindowWidth = width;
gWindowHeight = height;
You said I could debug on host AROS, how could I do it? Thanks.
sonountalebanJunior Member
Posted 2 months agoI found the palette is ok, if I call after it shows correctly the original bitmap over the scaled version.

Code Download source
ClipBlit(pMainScreenRastPort, 0, 0, pMainRastPort, 0, 0, gScreenWidth, gScreenHeight, 0xc0);Code Download source
BitMapScale(&bms_args);
deadwoodAROS Dev
Posted 2 months agoHere is a short tutorial on debugging:
https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1201&pid=10891#post_10891
If there is something not covered by the tutorial let me know!
https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1201&pid=10891#post_10891
If there is something not covered by the tutorial let me know!
1 user reacted to this post
sonountaleban
aros-sgJunior Member
Posted 2 months agoDoes the game use software rendering like Doom? With 8 bit chunky framebuffer?
It normally makes no sense to use BitMaps for such games. Especially not planar bitmaps like you seem to allocate.
And never ever in AROS which may be super slow/unoptimized for such things. Btw bitmap->Depth for pre-RTG compatibility will never by bigger than 8 even if for example you check a bitmap of a hicolor/truecolor screen. One should use GetBitMapAttr(BMA_DEPTH) instead which returns real depth.
Typically games like this render by directly painting the game framebuffer with graphics.library/WriteChunkyPixels() or cybergraphics/WriteLUTPixelArray (if screen is hicolor/truecolor and for example game is running in window-mode on WB ).
For scaling, the games would typically themselves scale the game framebuffer into a temp buffer and then passing that to WriteChunkyPixels() or WriteLUTPixelArray().
For window mode on a public (like WB ) screen, if it is 8 bit (and not hicolor/truecolor), they would also do a on-the-fly color remap pass. It's bad idea to change palette of public screens. Instead obtain colors with ObtainBestPen(). On hicolor/truecolor this is not necessary as WriteLUTPixelArray() has palette/LUT param which is used to map 8 bit source bytes to RGB values for dest bitmap.
It normally makes no sense to use BitMaps for such games. Especially not planar bitmaps like you seem to allocate.
And never ever in AROS which may be super slow/unoptimized for such things. Btw bitmap->Depth for pre-RTG compatibility will never by bigger than 8 even if for example you check a bitmap of a hicolor/truecolor screen. One should use GetBitMapAttr(BMA_DEPTH) instead which returns real depth.
Typically games like this render by directly painting the game framebuffer with graphics.library/WriteChunkyPixels() or cybergraphics/WriteLUTPixelArray (if screen is hicolor/truecolor and for example game is running in window-mode on WB ).
For scaling, the games would typically themselves scale the game framebuffer into a temp buffer and then passing that to WriteChunkyPixels() or WriteLUTPixelArray().
For window mode on a public (like WB ) screen, if it is 8 bit (and not hicolor/truecolor), they would also do a on-the-fly color remap pass. It's bad idea to change palette of public screens. Instead obtain colors with ObtainBestPen(). On hicolor/truecolor this is not necessary as WriteLUTPixelArray() has palette/LUT param which is used to map 8 bit source bytes to RGB values for dest bitmap.
1 user reacted to this post
sonountaleban
deadwoodAROS Dev
Posted 2 months agoHere is a suggestion from another developer:
Use 3 bitmaps. Your original game bitmap(A), bitmap identical to you game bitmap but with the size of the screen(
and screen bitmap (C). BitMapScale from A to B, then then Blit from B to C. Essentially disconnect steps of scalling and blitting to screen.
Use 3 bitmaps. Your original game bitmap(A), bitmap identical to you game bitmap but with the size of the screen(
1 user reacted to this post
sonountaleban
sonountalebanJunior Member
Posted 2 months ago@deadwood - Here is a suggestion from another developer:
Use 3 bitmaps. Your original game bitmap(A), bitmap identical to you game bitmap but with the size of the screen(B) and screen bitmap (C). BitMapScale from A to B, then then Blit from B to C. Essentially disconnect steps of scalling and blitting to screen.
Thank you, now it's better. :)

However, while vertical scaling is absolutely fine, horizontally is buggy until XDestFactor is equal to XSrcFactor...
My code now looks like this:
Code Download source
bms_args.bsa_SrcBitMap = pMainScreenRastPort->BitMap;
bms_args.bsa_DestBitMap = pScaledMainScreenRastPort->BitMap;
bms_args.bsa_Flags = 0;
bms_args.bsa_SrcWidth = gWindowWidth;
bms_args.bsa_SrcHeight = gWindowHeight;
bms_args.bsa_SrcX = 0;
bms_args.bsa_SrcY = 0;
bms_args.bsa_DestX = 0;
bms_args.bsa_DestY = 0;
bms_args.bsa_XSrcFactor = gWindowWidth;
bms_args.bsa_XDestFactor = gScreenWidth;
bms_args.bsa_YSrcFactor = gWindowHeight;
bms_args.bsa_YDestFactor = gScreenHeight;
BitMapScale(&bms_args);
BltBitMapRastPort(pScaledMainScreenRastPort->BitMap, 0, 0, pMainRastPort, 0, 0, gScreenWidth, gScreenHeight, 0xc0);
sonountalebanJunior Member
Posted 2 months ago[quote name=aros-sg post=10893]@aros-sg - Does the game use software rendering like Doom? With 8 bit chunky framebuffer?
It normally makes no sense to use BitMaps for such games. Especially not planar bitmaps like you seem to allocate.
And never ever in AROS which may be super slow/unoptimized for such things. Btw bitmap->Depth for pre-RTG compatibility will never by bigger than 8 even if for example you check a bitmap of a hicolor/truecolor screen. One should use GetBitMapAttr(BMA_DEPTH) instead which returns real depth.
Typically games like this render by directly painting the game framebuffer with graphics.library/WriteChunkyPixels() or cybergraphics/WriteLUTPixelArray (if screen is hicolor/truecolor and for example game is running in window-mode on WB ).
For scaling, the games would typically themselves scale the game framebuffer into a temp buffer and then passing that to WriteChunkyPixels() or WriteLUTPixelArray().
For window mode on a public (like WB ) screen, if it is 8 bit (and not hicolor/truecolor), they would also do a on-the-fly color remap pass. It's bad idea to change palette of public screens. Instead obtain colors with ObtainBestPen(). On hicolor/truecolor this is not necessary as WriteLUTPixelArray() has palette/LUT param which is used to map 8 bit source bytes to RGB values for dest bitmap.[/quote]
Yes, obviously it uses a 8 bit chunky framebuffer and I'm going to stick on full screen as default mode for the next release. Users will be still able to switch to window mode only modifying a flag in the prefs.txt file. I think in the future I'll add support for RTG compatibility, just at the moment I'm using simple rendering stuff to see the game running natively on AROS.
It normally makes no sense to use BitMaps for such games. Especially not planar bitmaps like you seem to allocate.
And never ever in AROS which may be super slow/unoptimized for such things. Btw bitmap->Depth for pre-RTG compatibility will never by bigger than 8 even if for example you check a bitmap of a hicolor/truecolor screen. One should use GetBitMapAttr(BMA_DEPTH) instead which returns real depth.
Typically games like this render by directly painting the game framebuffer with graphics.library/WriteChunkyPixels() or cybergraphics/WriteLUTPixelArray (if screen is hicolor/truecolor and for example game is running in window-mode on WB ).
For scaling, the games would typically themselves scale the game framebuffer into a temp buffer and then passing that to WriteChunkyPixels() or WriteLUTPixelArray().
For window mode on a public (like WB ) screen, if it is 8 bit (and not hicolor/truecolor), they would also do a on-the-fly color remap pass. It's bad idea to change palette of public screens. Instead obtain colors with ObtainBestPen(). On hicolor/truecolor this is not necessary as WriteLUTPixelArray() has palette/LUT param which is used to map 8 bit source bytes to RGB values for dest bitmap.[/quote]
Yes, obviously it uses a 8 bit chunky framebuffer and I'm going to stick on full screen as default mode for the next release. Users will be still able to switch to window mode only modifying a flag in the prefs.txt file. I think in the future I'll add support for RTG compatibility, just at the moment I'm using simple rendering stuff to see the game running natively on AROS.
deadwoodAROS Dev
Posted 2 months agoKalamatee made some fixes to the bitmapscale.c, planar path. Please copy this file to rom/graphics and then
Let us know if it works better for you.
Code Download source
cd core-linux-x86_64-d
make kernel-graphics-quick
Let us know if it works better for you.
1 user reacted to this post
sonountaleban
You do not have access to view attachments
sonountalebanJunior Member
Posted 2 months ago@deadwood - Kalamatee made some fixes to the bitmapscale.c, planar path. Please copy this file to rom/graphics and then
Code Download source
cd core-linux-x86_64-d
make kernel-graphics-quick
Let us know if it works better for you.
I get this error during the compiling of that file
Code Download source
[MMAKE] Collecting targets...
[MMAKE] Making kernel-graphics-quick in rom/graphics
Makedepend rom/graphics/bitmapscale.c ...
Compiling rom/graphics/bitmapscale.c
Compile failed: /home/peppe/Documents/arosbuilds/toolchain-core-x86_64/x86_64-aros-gcc --sysroot /home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/AROS/Development -iquote ./ -iquote /home/peppe/Documents/arosbuilds/core-linux-x86_64-d/rom/graphics/.. -iquote /home/peppe/Documents/arosbuilds/AROS/rom/graphics -iquote . -m64 -mcmodel=large -mno-red-zone -mno-ms-bitfields -O0 -fno-omit-frame-pointer -Wno-pointer-sign -Wno-parentheses -g -ffixed-r12 -I/home/peppe/Documents/arosbuilds/AROS/rom/cgfx -DAROS_BUILD_TYPE=AROS_BUILD_TYPE_PERSONAL -DADEBUG=1 -DMDEBUG=1 -DUSE_EXEC_DEBUG -D__OOP_NOMETHODBASES__ -I/home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/rom/graphics/graphics/include -include /home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/rom/graphics/graphics/include/graphics_deflibdefs.h -I/home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/buildsdks/private/include -I/home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/buildsdks/rel/include -I/home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/buildsdks/config/include -D__AROS_GIMME_DEPRECATED__ -D__UTILITY_RELLIBBASE__ -D__OOP_RELLIBBASE__ -D__SRCFILENAME__="rom/graphics/bitmapscale.c" -c bitmapscale.c -o /home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/rom/graphics/graphics/bitmapscale.o
bitmapscale.c: In function 'Graphics_113_BitMapScale':
bitmapscale.c:457:1: error: label at end of compound statement
457 | out:
| ^~~
make[1]: *** [mmakefile:1326: /home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/rom/graphics/graphics/bitmapscale.o] Error 1
[MMAKE] make --no-print-directory TOP=/home/peppe/Documents/arosbuilds/core-linux-x86_64-d SRCDIR=/home/peppe/Documents/arosbuilds/AROS CURDIR=rom/graphics TARGET=kernel-graphics-quick --file=mmakefile kernel-graphics-quick failed: 512
[MMAKE] Error: Error while running make in rom/graphics: No such file or directory
make: *** [Makefile:373: kernel-graphics-quick] Error 10
However adding a semicolor should fix the error.
Edited by sonountaleban on 26-01-2026 15:11, 2 months ago
sonountalebanJunior Member
Posted 2 months ago@sonountaleban -@deadwood - Kalamatee made some fixes to the bitmapscale.c, planar path. Please copy this file to rom/graphics and then
Code Download source
cd core-linux-x86_64-d
make kernel-graphics-quick
Let us know if it works better for you.
I get this error during the compiling of that file
Code Download source
[MMAKE] Collecting targets...
[MMAKE] Making kernel-graphics-quick in rom/graphics
Makedepend rom/graphics/bitmapscale.c ...
Compiling rom/graphics/bitmapscale.c
Compile failed: /home/peppe/Documents/arosbuilds/toolchain-core-x86_64/x86_64-aros-gcc --sysroot /home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/AROS/Development -iquote ./ -iquote /home/peppe/Documents/arosbuilds/core-linux-x86_64-d/rom/graphics/.. -iquote /home/peppe/Documents/arosbuilds/AROS/rom/graphics -iquote . -m64 -mcmodel=large -mno-red-zone -mno-ms-bitfields -O0 -fno-omit-frame-pointer -Wno-pointer-sign -Wno-parentheses -g -ffixed-r12 -I/home/peppe/Documents/arosbuilds/AROS/rom/cgfx -DAROS_BUILD_TYPE=AROS_BUILD_TYPE_PERSONAL -DADEBUG=1 -DMDEBUG=1 -DUSE_EXEC_DEBUG -D__OOP_NOMETHODBASES__ -I/home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/rom/graphics/graphics/include -include /home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/rom/graphics/graphics/include/graphics_deflibdefs.h -I/home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/buildsdks/private/include -I/home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/buildsdks/rel/include -I/home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/buildsdks/config/include -D__AROS_GIMME_DEPRECATED__ -D__UTILITY_RELLIBBASE__ -D__OOP_RELLIBBASE__ -D__SRCFILENAME__="rom/graphics/bitmapscale.c" -c bitmapscale.c -o /home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/rom/graphics/graphics/bitmapscale.o
bitmapscale.c: In function 'Graphics_113_BitMapScale':
bitmapscale.c:457:1: error: label at end of compound statement
457 | out:
| ^~~
make[1]: *** [mmakefile:1326: /home/peppe/Documents/arosbuilds/core-linux-x86_64-d/bin/linux-x86_64/gen/rom/graphics/graphics/bitmapscale.o] Error 1
[MMAKE] make --no-print-directory TOP=/home/peppe/Documents/arosbuilds/core-linux-x86_64-d SRCDIR=/home/peppe/Documents/arosbuilds/AROS CURDIR=rom/graphics TARGET=kernel-graphics-quick --file=mmakefile kernel-graphics-quick failed: 512
[MMAKE] Error: Error while running make in rom/graphics: No such file or directory
make: *** [Makefile:373: kernel-graphics-quick] Error 10
However adding a semicolor in that line fixes the error.
sonountalebanJunior Member
Posted 2 months agoSorry, I did a mess with the posts here... Anyway, I've copied the newer graphics.library into my hosted AROS installation and I got a bit different result:


2 users reacted to this post
aha, Argo
deadwoodAROS Dev
Posted 2 months agoHopefully with debugging guide I attached you will be able to find the root cause of that issue.
BTW, if you don't want to use GDB but just want to "printf" use bug() function. It will print the log to linux console. Be sure to #include <aros/debug.h> to resolve the bug() symbol.
BTW, if you don't want to use GDB but just want to "printf" use bug() function. It will print the log to linux console. Be sure to #include <aros/debug.h> to resolve the bug() symbol.
sonountalebanJunior Member
Posted 2 months agoFixed... I needed to make the off screen bitmap "friend" of the main window bitmap. Also I have to use WriteChunkyPixels now, because my C2P routine stopped to work in hosted mode (release executable) and with AxRuntime (debug executable). However, I had tried to make it friend before the updated bitmapscale.c file and it didn't work.

I've noticed the low-res is much slower in hosted mode, while under AxRuntime or running in a native AROS installation it's the fastest resolution as expected.

This is the biggest res (1024x768) and on my machine it runs at similar frame rates in every environment.
I forgot a thing, I've removed the intermediate buffer for BitMapScale, it works well dealing directly with the window bitmap and the offscreen bitmap.

I've noticed the low-res is much slower in hosted mode, while under AxRuntime or running in a native AROS installation it's the fastest resolution as expected.

This is the biggest res (1024x768) and on my machine it runs at similar frame rates in every environment.
I forgot a thing, I've removed the intermediate buffer for BitMapScale, it works well dealing directly with the window bitmap and the offscreen bitmap.
Edited by sonountaleban on 27-01-2026 21:00, 2 months ago
3 users reacted to this post
aha, Argo, Farox
deadwoodAROS Dev
Posted 2 months agoOk, if you made your offscreen bitmap a "friend" to display bitmap, then you are no longer using planar bitmap as offscreen - which might explain why your C2P now crashes as PlanePtr in non-planar bitmaps are meaningless. Having your offscreen bitmap being "friend" of display also makes a different path being used in BitMapScale so that explains why it works now.
All in all good to hear problems are solved.
All in all good to hear problems are solved.
1 user reacted to this post
sonountaleban
sonountalebanJunior Member
Posted 2 months ago@deadwood - Ok, if you made your offscreen bitmap a "friend" to display bitmap, then you are no longer using planar bitmap as offscreen - which might explain why your C2P now crashes as PlanePtr in non-planar bitmaps are meaningless. Having your offscreen bitmap being "friend" of display also makes a different path being used in BitMapScale so that explains why it works now.
All in all good to hear problems are solved.
Ah, so basically WriteChunkyPixels is doing nothing because the offscreen bitmap is already in "chunky mode"? Apart copy the raw bytes into the dest rastport/bitmap, of course.
Also this implies that BitMapScale is still faulty in planar mode?
Edited by sonountaleban on 28-01-2026 05:57, 2 months ago
deadwoodAROS Dev
Posted 2 months agoI'd say 99% Yes and Yes, but you can debug this by just setting breakpoints in both functions or adding some bug() statements to them.
1 user reacted to this post
sonountaleban
You can view all discussion threads in this forum.
You cannot start a new discussion thread in this forum.
You cannot reply in this discussion thread.
You cannot start on a poll in this forum.
You cannot upload attachments in this forum.
You cannot download attachments in this forum.
You cannot start a new discussion thread in this forum.
You cannot reply in this discussion thread.
You cannot start on a poll in this forum.
You cannot upload attachments in this forum.
You cannot download attachments in this forum.
Moderator: Administrator, Moderators
