What you want to use is RBG0 of VDP2.
RBG0 is a 3D rotating, scaling, and tiling plane.
In this thread, XL2 attached a demo that uses RBG0.
https://forum.jo-engine.org/index.php?topic=864.0There are no Jo engine abstractions to use RBG0.
Here is a more direct example of the parameter setup for an RBG0 plane:
slRparaInitSet((void *)RBG0_PRA_ADR);
slMakeKtable((void *)RBG0_KTB_ADR);
slCharRbg0(COL_TYPE_256 , CHAR_SIZE_1x1);
slPageRbg0((void *)RBG0RB_CEL_ADR , 0 , PNB_1WORD|CN_12BIT);
slPlaneRA(PL_SIZE_1x1);
sl1MapRA((void *)RBG0RA_MAP_ADR);
slOverRA(0);
slKtableRA((void *)RBG0_KTB_ADR , K_MODE0 | K_FIX | K_LINE | K_2WORD | K_ON | K_LINECOL);
Cel2VRAM(tuti_cel , (void *)RBG0RA_CEL_ADR , 65536);
Map2VRAM(tuti_map , (void *)RBG0RA_MAP_ADR , 64 , 64 , 2 , 884);
Pal2CRAM(tuti_pal , (void *)RBG0RA_COL_ADR , 160);
slRparaMode(RA);
slBack1ColSet((void *)BACK_COL_ADR , 0);
slColorCalc( CC_ADD | CC_TOP | NBG2ON | RBG0ON);
slColorCalcOn( NBG2ON | RBG0ON);
slScrTransparent(NBG2ON | RBG0ON);
slColRateLNCL(0x00);
To display & transform the RBG0 plane, you need to end the matrix it is in with the following:
slCurRpara(RA);
slScrMatConv();
slScrMatSet();
slCurRpara sets RBG0's rotation parameter type.
slScrMatConv converts the matrix to a scroll screen matrix. (Note the consumes the matrix in the process, do not set polygons in this matrix)
slScrMatSet sets the converted matrix and sends it to VDP2 rather than VDP1.
In addition, you may note this command:
slScrAutoDisp(NBG0ON | RBG0ON );
slScrAutoDisp sets data inside of SGL (the development library) to notify VDP2 of which scroll screens are to be displayed automatically each frame.
I HIGHLY RECOMMEND YOU READ VDP2 USER'S MANUAL REGARDING THE SCROLL SCREEN, OR THE SEGA OF EUROPE TUTORIAL DOCUMENT.Those can be found here:
https://antime.kapsi.fi/sega/docs.html