Ca a l'air de marcher. J'ai le pressentiment qu'il reste un truc qui cloche avec les histoires d'images qui ont des lignes noires en haut
pour faire un multiple de 4 lignes (norme du SDK Gp32 et de GP32Converter.exe)
Alors moi, pour compiler de l'assembleur ARM avec minigp32, je fais comme ca:
- dans le makefile (genere par Visual MinGW), je rajoute mon asm.o a la suite de tous les .o
- je fais un fichier sprite.h contenant la definition de ma fonction
#ifndef SPRITE_H #define SPRITE_H extern void GpBitBltASM(GPDRAWSURFACE* screen, int startX, int startY, unsigned char* sprite, int sprite_width, int sprite_height); #endif
- je fais un fichier asm.s avec le code de ma fonction (Pensez a commenter chaque ligne)
@***void GpBitBltASM(GPDRAWSURFACE * screen, int startX, int startY, unsigned char* sprite, int sprite_width, int sprite_height); *** .ALIGN .GLOBAL GpBitBltASM .TYPE GpBitBltASM, function .CODE 32 @r0 = screen (structure first then replaced by direct pointer) @r1 = startX @r2 = startY @r3 = sprite @r4 = sprite_width @r5 = sprite_height (user value then ASM value being a multiple of 4) @r6 = screen_width @r7 = screen_height @r8 = width copy @r9 = height copy @r10 = number of sprite lines after the multiple of 4 before. (if height of sprite is 9 then r10 = 1 because 9%4 = 1) GpBitBltASM: SUB sp,sp,#8 @protect the memory where the params are STMFD r13!,{r4-r10} @save used registers LDR r4,[r13,#36] @then load the 5th and 6th params using ldrs LDR r5,[r13,#40] @2 params + 7 saved registers (4 bytes each) @=> 9 x 4 = 36 bytes from sp (r4), and then 40 for r5 LDR r6, [r0, #8] @read screen_width LDR r7, [r0, #12] @read screen_height LDR r0, [r0] @read screen pointer ADD r2, r2, r5 @Convert user coordinates to gp32 coordinates (y becomes screen height - (y+sprite_height) ) SUB r2, r7, r2 @. @GP32 height of sprite must be a multiple of 4. If user given height is not a multiple of 4, some pixels are added. ANDS r10, r5, #0x0003 @r5%4 -> r10 (check if height is a multiple of 4) SUBNE r5, r5, r10 @if modulo if not zero clear last bits (if not ...) ADDNE r5, r5, #4 @and add #4 (... replace height by next multiple of 4) MOV r8, r4 @first value of Lcopy MOV r9, r5 @first value of Hcopy @those 3 lines were added in order to adapt the function to sprites with lines non multiple of 4. CMP r10, #0 @if r10 is not zero (r10 is the number of lines after multiple of 4) RSBNE r10, r10, #4 @then number of lines to remove is #4-r10 SUBNE r9, r9, r10 @and zap last lines of dead pixels by reducing height copy (here because columns have to have a multiple of 4 pixels) @vertical update of screen and sprite pointers and of copy zone height. CMP r2, #0 @if startY is positive ADDGT r0, r0, r2 @then add startY to screenPointer SUBLT r3, r3, r2 @else remove startY from sprite pointer (=add absolute value of startY to pointer) ADDLT r9, r9, r2 @and reduce height of copy zone to correct value. ADD r2, r2, r5 @precalc (r2+r5+1) = startY + heightSprite-1 SUB r2, r2, #1 @which is max Y value of sprite SUBS r2, r7, r2 @test screenheight - (starty+heightSprite-1). If this is negative, the sprite goes outside the screen (up) ADDLT r9, r9, r2 @reduce height of copy and then copy zone stay in the screen. @r2 is now free to be used. @horizontal update of screen and sprite pointers and of copy zone width CMP r1, #0 @if startX is positive MULGT r2, r1, r7 @precalc startX*screenHeight and put it in r2 ADDGT r0, r0, r2 @add startX*screenHeight to screen pointer MULLT r2, r1, r5 @else precalc startX*spriteheight and put it in r2 SUBLT r3, r3, r2 @and remove this value to sprite pointer (=add absolute value) ADDLT r8, r8, r1 @and reduce width of copy zone. ADD r2, r1, r4 @precalc (r1+r4) = startX + widthSprite SUBS r2, r6, r2 @screenwidth - (startX + widthSprite). If this is negative sprite goes outside the screen (right) ADDLT r8, r8, r2 @Then reduce width of copy zone to correct value. @r1 is now free to be used CMP r8, #0 @if width copy <=0 BLE endGpBitBltASM @jump to the end of the function CMP r9, #0 @if height copy <=0 BLE endGpBitBltASM @jump to the end of the function bigLoop: STMFD sp!, {r0, r3} @Push pointer to screen and to sprite STMFD sp!, {r9} @Save height copy value (r9) smallLoop: LDRB r1, [r3], #1 @read pixel P2[0] and P2++ STRB r1, [r0], #1 @write pixel P1[0] and P1++ SUBS r9, r9, #1 @r9 -- BNE smallLoop @loop while r9 != 0 (do every pixels of the column) LDMFD sp!, {r9} @Restore Lcopy value LDMFD sp!, {r0, r3} @Pop pointer to screen and to sprite ADD r0, r0, r7 @Next screen column ADD r3, r3, r5 @Next sprite line (r5 is corrected height. The one that is a multiple of 4) SUBS r8, r8, #1 @Do it widthCopy times BNE bigLoop endGpBitBltASM: LDMFD r13!,{r4-r10} @end of function. Restore register ADD sp,sp,#8 @restore stack pointer BX lr @and back to C
4- et je compile comme d'hab