Blitter optimizations (thanks qkumba!) and minor fixes.

This commit is contained in:
Scott Duensing 2020-08-06 14:11:38 -05:00
parent 36beed9f6c
commit 9aed38a5b6
8 changed files with 146 additions and 159 deletions

View file

@ -175,12 +175,16 @@ SDL_Surface *loadImage(char *filename) {
//printf("%s = %dx%d, %d bits per pixel, %d colors\n", filename, image->w, image->h, image->format->BitsPerPixel, colors);
if (image->w != 320 || image->h != 200 || colors > 16) {
fprintf(stderr, "Image must be 320x200 pixels, 8 bits per pixel, with 16 or fewer colors.\n");
if (image->w != 320 || image->h != 200) {
fprintf(stderr, "Image must be 320x200 pixels.\n");
free(image);
image = NULL;
}
if (colors > 16) {
fprintf(stderr, "Expecting 16 or fewer colors. Only using first 16.\n");
}
return image;
}
@ -188,7 +192,7 @@ SDL_Surface *loadImage(char *filename) {
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Usage: %s [color.png] [stencil.png] [outfile] {anyting}\n", argv[0]);
printf("Usage: %s [color.png] [stencil.png|NO_STENCIL] [outfile] {anyting}\n", argv[0]);
printf("(If {anything} is provided, image will be displayed as converted until keypress.)\n");
return 1;
}

View file

@ -98,7 +98,7 @@ function doIIgsBuild() {
rm "/tmp/IIgs/JLSTATS#040000" 2> /dev/null || true
rm "${IMPORT}" 2> /dev/null || true
cp "${OUT}/test" "${OUT}/Test#B30000"
cp "${OUT}/test" "${OUT}/Test#b3db03"
cp "${JOEY}/joeylib/joeylib/src/kanga.img" "${OUT}/kanga.img#060000"
cp "${JOEY}/joeylib/joeylib/src/font.img" "${OUT}/font.img#060000"
cp "${JOEY}/joeylib/joeylib/src/font.stn" "${OUT}/font.stn#060000"
@ -108,7 +108,7 @@ function doIIgsBuild() {
"${CADIUS}" createvolume "${IMPORT}" ${VOL} 32MB > /dev/null
"${CADIUS}" createfolder "${IMPORT}" ${VOL}/data > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL} "${JOEY}/dist/IIgs/Tool221#ba0000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL} "${OUT}/Test#b30000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL} "${OUT}/Test#b3db03" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL}/data "${OUT}/kanga.img#060000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL}/data "${OUT}/font.img#060000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL}/data "${OUT}/font.stn#060000" > /dev/null

View file

@ -35,87 +35,77 @@ VblTime ds 2 ; Integer Counter
;----------------------------------------
; Blit an 8x8 block to (almost) anywhere on a surface.
; Optimized by qkumba - thanks!
;----------------------------------------
asmB88 start
source equ 1 ; Source Pixels Offset
target equ 3 ; Target Pixels Offset
t equ 5 ; Temp
xc equ 7 ; X Counter
yc equ 9 ; Y Counter
xc equ 5 ; X Counter
yc equ 7 ; Y Counter
jsubroutine (4:surface,4:tiles,2:sx,2:sy,2:tx,2:ty),10
using GlobalData
; Find offset into tile memory
; Divide source horizontal position by two since there are two pixels per byte
lda sx ; Load X source position into accumulator
lsr a
sta t
clc
lda sy ; Load sy to get index into scanline table
asl a ; Multiply by two to get offset into scanline table (two bytes per entry in table)
tay
; Divide source horizontal position by two since there are two pixels per byte
lda sx ; Load X source position into accumulator
lsr a
clc
lda ScTable,y ; Load byte offset of y position from table
adc t ; Add t to scanline offset
adc ScTable,y ; Add to byte offset of y position from table
sta source ; Offset to start of source pixels
; Divide target horizontal position by two since there are two pixels per byte
lda tx ; Load X target position into accumulator
lsr a ; Shift Right - divide by 2
clc
sta tx ; Store it back into cx2
; Find offset into target surface memory
lda ty ; Load ty to get index into scanline table
asl a ; Multiply by two to get offset into scanline table (two bytes per entry in table)
tay
lda ScTable,y ; Load byte offset of y position from table
adc tx ; Add x position to scanline offset
; Divide target horizontal position by two since there are two pixels per byte
lda tx ; Load X target position into accumulator
lsr a ; Shift Right - divide by 2
clc
adc ScTable,y ; Add x position to byte offset of y position from table
sta target ; Offset to start of target pixels
lda #0 ; Load 0 into X and Y counters
sta xc
stz xc ; Load 0 into X, 8 into Y counters
lda #8
sta yc
blitTop ldy source ; Load Y register with source pixel offset
lda [tiles],y ; Load 4 tile pixels
tyx
ldy target ; Load Y register with target pixel offset
sta [surface],y ; Store 4 pixels into screen
clc ; Increment to next pixel target quad
lda #2
adc target
sta target
clc ; Increment to next pixel source quad
lda #2
adc source
sta source
iny ; Increment to next pixel target quad
iny
sty target
inx ; Increment to next pixel source quad
inx
stx source
clc
lda xc ; Increment X counter
adc #1
inc a
and #1 ; count to 2 and auto-reset
sta xc
cmp #2 ; End of X pixels?
bcc blitTop ; Nope!
;;cmp #2 ; End of X pixels?
bne blitTop ; Nope!
lda #0 ; Reset X counter
sta xc
clc ; Increment target offset
lda #156
adc target
tya
adc #156
sta target
clc ; Increment source offset
lda #156
adc source
txa
adc #156
sta source
clc
lda yc ; Increment Y counter
adc #1
sta yc
cmp #8 ; End of Y pixels?
bcc blitTop ; Nope!
dec yc ; Decrement Y counter
;;cmp #0 ; End of Y pixels?
bne blitTop ; Nope!
jreturn
end
@ -139,41 +129,34 @@ tile_pix equ 13
using GlobalData
; Find offset into tile memory
; Divide source horizontal position by two since there are two pixels per byte
lda sx ; Load X source position into accumulator
lsr a ; Shift Right - divide by 2
tax ; save in temp
; c=? but does not matter
lda sy ; Load sy to get index into scanline table
asl a ; Multiply by two to get offset into scanline table (two bytes per entry in table)
tay
txa
adc ScTable,y ; Load byte offset of y position from table
; c=0 from the asl above here
sta source ; Offset to start of source pixels; Find offset into target surface memory
; Divide target horizontal position by two since there are two pixels per byte
lsr tx
lda ty ; Load ty to get index into scanline table
asl a ; Multiply by two to get offset into scanline table (two bytes per entry in table)
tay
lda ScTable,y ; Load byte offset of y position from table
; c=0 from the asl above
adc tx ; Add x position to scanline offset
sta target ; Offset to start of target pixels; Find the upper left corner of the stencil
lda sy
asl a
tay
lda ScTable,y ; look up in the pixel scanline table
lsr a
lsr a ; we're 4 times smaller, so just divide it
sta stoffset
lda #0 ; Load 0 into X and Y counters
sta xc
; Divide source horizontal position by two since there are two pixels per byte
lda sx ; Load X source position into accumulator
lsr a ; Shift Right - divide by 2
clc
adc ScTable,y ; Add byte offset of y position from table
sta source ; Offset to start of source pixels; Find offset into target surface memory
lda ty ; Load ty to get index into scanline table
asl a ; Multiply by two to get offset into scanline table (two bytes per entry in table)
tay
; Divide target horizontal position by two since there are two pixels per byte
lda tx
lsr a
clc
adc ScTable,y ; Add byte offset of y position from table
sta target ; Offset to start of target pixels; Find the upper left corner of the stencil
stz xc ; Load 0 into X, 8 into Y counters
lda #8
sta yc
blitTop anop
@ -182,6 +165,7 @@ blitTop anop
sta mask0123 ; default all 4 pixels visible
lda sx ; add in stencil X position
tax
lsr a
lsr a
lsr a ; div by 8 to get to byte index
@ -189,7 +173,7 @@ blitTop anop
adc stoffset
tay
lda sx
txa
and #7
; A = number of initial bits to shift out
; to get to the mask
@ -203,32 +187,15 @@ skipbit anop ; burn bits we don't care about
dex
bpl skipbit
tax
bcc mask0 ; bit clear, leave mask alone
lda #$00F0 ; bit set, set the mask bits
rol a
rol a
rol a
rol a
rol a
and #30
tay
lda BMTable,y
trb mask0123
mask0 anop
txa
asl a
tax
bcc mask1 ; bit clear, leave mask alone
lda #$000F ; bit set, set the mask bits
trb mask0123
mask1 anop
txa
asl a
tax
bcc mask2 ; bit clear, leave mask alone
lda #$F000 ; bit set, set the mask bits
trb mask0123
mask2 anop
txa
asl a
bcc mask3 ; bit clear, leave mask alone
lda #$0F00 ; bit set, set the mask bits
trb mask0123
mask3 anop
; c=?
clc ; c=0
lda sx
adc #4 ; Add 4 here because we're moving left to right
@ -237,6 +204,7 @@ mask3 anop
ldy source ; Load Y register with source pixel offset
lda [tiles],y ; Load 4 tile pixels
sta tile_pix
tyx
ldy target ; Load Y register with target pixel offset
lda [surface],y
@ -244,53 +212,51 @@ mask3 anop
ora tile_pix
sta [surface],y ; Store 4 pixels into screen
;clc ; Increment to next pixel target quad
lda #2
adc target
sta target
; c=0 here as long as target didn't go over $FFFF
;clc ; Increment to next pixel source quad
lda #2
adc source
sta source ;clc ; c=0 here as long as source didn't go above $FFFF
iny
iny
sty target
inx
inx
stx source ;clc ; c=0 here as long as source didn't go above $FFFF
lda xc ; Increment X counter
adc #1
inc a
and #1
sta xc
cmp #2 ; End of X pixels?
bcc blitTop ; Nope! lda #0 ; Reset X counter
;;cmp #2 ; End of X pixels?
bne blitTop ; Nope!
stz xc ; reset xcounter to 0
; c = 1
; reset stencil X
sec
lda sx
sbc #8
sta sx
; c=0
clc
lda stoffset ;Increment Stencil offset
adc #40 ; 160 / 4
sta stoffset ; c=0 ; Increment target offset
lda #156 ; c=1, so instead of doing clc, adc 156, just do adc 155
adc target
clc
tya
adc #156
sta target
;clc ; Increment source offset
; c=0 unless target goes above $FFFF
lda #156
adc source
clc ; Increment source offset
txa
adc #156
sta source
; clc c=0 unless source goes above $FFFF
lda yc ; Increment Y counter
adc #1
sta yc
cmp #8 ; End of Y pixels?
bcs maskend ; Yep!
jmp blitTop
dec yc ; Increment Y counter
;;cmp #8 ; End of Y pixels?
beq maskend ; Yep!
jmp blitTop ; can it reach now?
maskend anop
jreturn
end
BMTable anop
dc i'$0000,$0F00,$F000,$FF00'
dc i'$000F,$0F0F,$F00F,$FF0F'
dc i'$00F0,$0FF0,$F0F0,$FFF0'
dc i'$00FF,$0FFF,$F0FF,$FFFF'
end
;----------------------------------------
; Set Border Color
@ -323,21 +289,21 @@ loopY equ 9
jsubroutine (4:surface,2:startX,2:startY,2:width,2:height,4:mapData,2:stride,4:tiles),10
lda #0 ; Zero some starting values
sta offset
stz offset ; Zero some starting values
clc ; Find loop ending values
; Find loop ending values
lda width ; Load width of map to draw, in tiles
asl a ; Multiply by 8 to get pixels
asl a
asl a
clc
adc startX ; Add starting position in pixels
sta loopX ; Store it
clc
lda height ; Load height of map to draw, in tiles
asl a ; Multiply by 8 to get pixels
asl a
asl a
clc
adc startY ; Add starting position in pixels
sta loopY ; Store it
@ -347,13 +313,15 @@ loopY equ 9
drawTop phy ; Keep Y for later
ldy offset ; Y is now offset into map data
lda [mapData],y
pha
and #$00ff ; We only want 8 bits
sta tileX
iny
lda [mapData],y
pla
xba
and #$00ff ; We only want 8 bits
sta tileY
iny
iny
sty offset
ply ; Y is our loop counter again
@ -926,14 +894,12 @@ temp1 equ 1
lda Yp ; Load accumulator with Y location
asl a ; Shift accumulator left (multiply by 2) for word offset into table
tay ; Transfer accumulator to y register
lda ScTable,y ; Look up scan line address offset
sta temp1 ; Store accumulator (row offset into SHR memory) into temp1
clc ; Clear carry flag
lda Xp ; Place X position in accumulator
lsr a ; Logical Shift Right (divide by 2, two pixels per byte) - bit shifted off the end goes into carry flag
php ; Save our carry flag for later!
clc ; Clear carry
adc temp1 ; Add X position to SHR address with carry - a now contains address of color pair we want
adc ScTable,y ; Add X position to SHR address with carry - a now contains address of color pair we want
plp ; Restore our carry flag
tay ; Transfer accumulator to y register
lda [surface],y ; Load pixel pair into accumulator
@ -1105,7 +1071,6 @@ NSHigh lda [pointer],y ; Get byte to check
sta [pointer],y ; Store it back
NSEnd iny ; Increment Y
clc ; Clear carry
cpy count ; Compare Y to number of bytes to modify
bcc NSLow ; Keep going

View file

@ -26,6 +26,7 @@
#include <memory.h>
#include <misctool.h>
#include <sound.h>
#include <MIDISynth.h>
#undef false
#undef true
@ -38,6 +39,10 @@
#endif
#define DPForSound 0x0000 // Needs one direct page
#define DPTotal 0x0100 // Total size of all tool DP usage
typedef struct {
char length;
char text[255];
@ -320,11 +325,13 @@ void jlUtilShutdown(void) {
asmStop();
// Shutdown tools
UnloadOneTool(0xDD); // NinjaTracker
MTShutDown();
MSShutDown(); // MIDI Synth
SoundShutDown(); // Sound Tool Set
//UnloadOneTool(0xDD); // NinjaTracker
MTShutDown(); // Misc Tools
DisposeAll(_jlMemID);
MMShutDown(_jlMyID);
TLShutDown();
MMShutDown(_jlMyID); // Memory Manager
TLShutDown(); // Tool Locator
jlUtilDie("Clean Exit.");
}
@ -332,16 +339,23 @@ void jlUtilShutdown(void) {
void jlUtilStartup(char *appTitle) {
handle ZeroPageHandle;
ptr ZeroPagePtr;
(void)appTitle; // Unused on IIgs
// Start up neded tools
TLStartUp();
_jlMyID = MMStartUp();
TLStartUp(); // Tool Locator
_jlMyID = MMStartUp(); // Memory Manager
_jlMemID = _jlMyID | 0x0100; // Set aux ID to 1.
_jlMusicMemID = _jlMyID | 0x0200; // Set music ID.
MTStartUp();
LoadOneTool(0xDD, 0); // NinjaTracker
JOEY_CHECK_TOOL_ERROR("LoadOneTool")
ZeroPageHandle = NewHandle((Long)DPTotal, (Word)_jlMyID, (Word)attrBank | attrPage | attrFixed | attrLocked, (Long)0);
ZeroPagePtr = *ZeroPageHandle;
MTStartUp(); // Misc Tools
SoundStartUp((word)ZeroPagePtr + DPForSound); // Sound Tool Set
MSStartUp(); // MIDI Synth
//LoadOneTool(0xDD, 0); // NinjaTracker
//JOEY_CHECK_TOOL_ERROR("LoadOneTool")
// Reserve shadow area for SHR
_jlSHRShadowHandle = NewHandle((LongWord)0x8000, (Word)_jlMemID, (Word)(attrLocked + attrFixed + attrBank + attrAddr), (Pointer)0x012000);

View file

@ -45,10 +45,10 @@ function buildIIgs() {
iix chtyp -t lib ${GSTARGET}/joeylib
# Link our program and create a map file
iix -DKeepType=S16 link +L ${OFILES} keep=${GSTARGET}/${PROJECT}#b30000 > ${PROJECT}.map
iix -DKeepType=S16 link +L ${OFILES} keep=${GSTARGET}/${PROJECT}#b3db03 > ${PROJECT}.map
# Create a disassembly and linker input listing
iix dumpobj +D ${GSTARGET}/${PROJECT}#b30000 &> ${PROJECT}.dis || true
iix dumpobj +D ${GSTARGET}/${PROJECT}#b3db03 &> ${PROJECT}.dis || true
echo ${OFILES} > ${PROJECT}.lnk
# Be sure our work directories exists
@ -57,7 +57,7 @@ function buildIIgs() {
# Create disk image, setting known file types
${CADIUS} createvolume ${IMPORT} ${VOL} 32MB > /dev/null
${CADIUS} createfolder ${IMPORT} ${VOL}/data > /dev/null
${CADIUS} addfile ${IMPORT} ${VOL} ${TARGET}/${PROJECT}#b30000 > /dev/null
${CADIUS} addfile ${IMPORT} ${VOL} ${TARGET}/${PROJECT}#b3db03 > /dev/null
${CADIUS} addfile ${IMPORT} ${VOL} ${JOEY}/dist/IIgs/Tool221#ba0000 > /dev/null
for F in "${DATA[@]}"; do
N=${WORK}/data/`basename ${F}`#060000

View file

@ -42,13 +42,13 @@
)
)
)
(gimp-image-convert-indexed img
NO-DITHER
MAKE-PALETTE
16
FALSE
FALSE
"")
;(gimp-image-convert-indexed img
; NO-DITHER
; MAKE-PALETTE
; 16
; FALSE
; FALSE
; "")
(set! count (+ count 1))
(file-png-save
1

View file

@ -936,6 +936,7 @@ function start() {
clang \
cmake \
cpio \
curl \
flex \
g++-multilib \
gcc-multilib \

3
scripts/startGrafX2.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/bash
grafx2 -size 320x200 -quadruple -rgb 16 "${JOEY}/joeylib/assets/JoeyLib.gpl" &