AgonConsole8 / agon-vdp

Official Firmware for the Agon Console8: ESP32 VDP
MIT License
43 stars 17 forks source link

Transformed bitmap plots #222

Closed stevesims closed 5 months ago

stevesims commented 6 months ago

adds support for creating (and adjusting) 2d affine transform matrixes in buffers. affine transforms supported include rotate, scale (with separate x and y scaling values), skew, shear, and translation

a transform to be set to apply to all bitmap plot operations. this works for all bitmap formats* in all screen depths

(for those interested, the crash on plotting bitmaps that had earlier been noted on this PR was caused by how the floating point unit and interrupts works. the plotting actually worked in all screen modes except for single-buffered 64 colour modes, as those did not attempt to draw the bitmaps from inside an interrupt.)

support for affine transforms is experimental and the API is subject to change. to allow for this feature to be integrated and released in the VDP a new command to "set test flag" has also been added

stevesims commented 6 months ago

this test program should draw a transformed bitmap, in 16-bit BBC BASIC. NB you need to have resources/pacman1.rgb from the Quark BBC BASIC repository for this to work:

10 REM transformed bitmap plot test
20 MODE 8
25 VDU 23, 0, &F8, 1; 1;   : REM enable test flag for affine transform feature
30 MB% = &40000
40 W% = 16 : H% = 16
50 DIM graphics 1024
60 OSCLI("LOAD ../resources/pacman1.rgb "+STR$(MB% + graphics))
190 REM send RGBA2222 data to VDP buffer 2
195 offset% = 0 : byte% = 0 : bit% = 0
196 VDU 23, 0, &A0, 2; 2
200 VDU 23, 0, &A0, 2; 0, W%*H%;
210 FOR I%=0 TO (W%*H%*3)-1 STEP 3
220   r% = ?(graphics+I%+0) DIV 64
230   g% = ?(graphics+I%+1) DIV 64
240   b% = ?(graphics+I%+2) DIV 64
250   a% = r% OR g% OR b%
260   p% = a% * 64 + b% * 16 + g% * 4 + r%
270   VDU p%
280 NEXT
290 REM set buffer to be a bitmap
300 VDU 23, 27, &20, 2;
310 VDU 23, 27, &21, W%; H%; 1
320 REM set up some transform buffers
330 VDU 23, 0, &A0, 10; 2
340 REM rotate by 5 degrees
350 VDU 23, 0, &A0, 10; &20, 2, &C0, 5;
360 REM main transform - translate by half width and height, then scale by 2
370 VDU 23, 0, &A0, 11; 2
380 VDU 23, 0, &A0, 11; &20, 6, &C0, -8; -8;
390 VDU 23, 0, &A0, 11; &20, 5, &C0, 2; 2;
400 REM Set the transform to be used
410 VDU 23, 0, &96, 1, 11;
420 MOVE 640, 512
430 REM plot bitmap in a loop, incrementing the angle every time
440 REPEAT
450   PLOT &E9, 0, 0
460   VDU 23, 0, &A0, 11; &20, 2, &C0, 5;
470   *FX 19
480 UNTIL FALSE

to get this code to work in ADL BBC BASIC you'd just need to remove the MB% stuff