View Single Post
Old 11 September 2023, 10:17   #6
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by Brick Nash View Post
Thanks for the reply.

Yeah, I had a feeling it wouldn't be easy with the planar mode, so I'll have a look at the chunky>Planar>chunky thing.

Could you point me in the direction of some source code? My searches haven't turned much up. Thanks!
Here's what I used back in 1997, which is designed for in-place remapping the colours of a planar bitmap. Up to 256 colours are supported.

Code:
**
**	:ts=8
**

	include "graphics/gfx.i"

	section	text,code

*--------------------------------------------------------------------------

do_plane_rd	macro
	move.l	-(a0),a1
	move.b	0(a1,a4.l),d7
	add.b	d7,d7
	addx.w	d0,d0
	add.b	d7,d7
	addx.w	d1,d1
	add.b	d7,d7
	addx.w	d2,d2
	add.b	d7,d7
	addx.w	d3,d3
	add.b	d7,d7
	addx.w	d4,d4
	add.b	d7,d7
	addx.w	d5,d5
	add.b	d7,d7
	addx.w	d6,d6
	swap	d6
	add.b	d7,d7
	addx.w	d6,d6
	swap	d6
	endm

do_plane_wr	macro
	move.l	(a0)+,a1
	lsr.w	#1,d0
	addx.w	d7,d7
	lsr.w	#1,d1
	addx.w	d7,d7
	lsr.w	#1,d2
	addx.w	d7,d7
	lsr.w	#1,d3
	addx.w	d7,d7
	lsr.w	#1,d4
	addx.w	d7,d7
	lsr.w	#1,d5
	addx.w	d7,d7
	lsr.w	#1,d6
	addx.w	d7,d7
	swap	d6
	lsr.w	#1,d6
	addx.w	d7,d7
	swap	d6
	move.b	d7,0(a1,a4.l)
	endm

*--------------------------------------------------------------------------

; VOID __asm RemapBitMap(register __a0 struct BitMap * srcbm,
;                        register __a1 struct BitMap * destbm,
;                        register __a2 UBYTE *         table1,
;                        register __d0 UWORD           width);

ofs_read_planes		equ	0
ofs_write_planes	equ	ofs_read_planes+4
ofs_bperrow		equ	ofs_write_planes+4
ofs_col_ctr		equ	ofs_bperrow+4
ofs_row_ctr		equ	ofs_col_ctr+2
ofs_adr_add		equ	ofs_row_ctr+2
ofs_src_offset		equ	ofs_adr_add+4
ofs_dst_offset		equ	ofs_src_offset+4
ofs_dadr_add		equ	ofs_dst_offset+4
st_depth		equ	ofs_dadr_add+4

	xdef	RemapBitMap

RemapBitMap:
	movem.l	d2-d7/a2-a6,-(a7)
	sub.l	#st_depth,a7			; adjust for temp vars
	add.w	#7,d0
	lsr.w	#3,d0				; convert width into bytes per row
	move.w	d0,ofs_col_ctr(a7)		; save as column counter
	move.w	bm_Rows(a0),ofs_row_ctr(a7)	; save row counter
	move.w	d0,ofs_bperrow(a7)		; save as bytes per row offset
	sub.w	bm_BytesPerRow(a0),d0		; subtract row modulo
	ext.l	d0
	neg.l	d0				; make it positive (the row modulo is always >= number of bytes per row)
	move.l	d0,ofs_adr_add(a7)		; save as offset to add to plane address
	move.w	bm_BytesPerRow(a1),d0		; get the destination bitmap row modulo
	sub.w	ofs_col_ctr(a7),d0		; subtract column counter
	ext.l	d0
	move.l	d0,ofs_dadr_add(a7)		; save as destination offset
	moveq	#0,d0
	move.l	d0,ofs_dst_offset(a7)		; clear destination offset
	move.l	d0,ofs_src_offset(a7)		; clear source offset
	move.b	bm_Depth(a0),d0
	add.w	d0,d0
	add.w	d0,d0				; make the depth a long word offset
	lea	bm_Planes(a0,d0.w),a0		; get behind the last plane to carry a pointer
	move.l	a0,ofs_read_planes(a7)		; save the plane address
	lea	depth_rd_jmp_tbl(pc),a6
	move.l	0(a6,d0.w),a6			; address of the routine to read the last plane
	move.b	bm_Depth(a1),d0
	add.w	d0,d0
	add.w	d0,d0				; make the depth a long word offset
	move.l	depth_wr_jmp_tbl(pc,d0.w),a5	; address of the routine to write the first plane
	lea	bm_Planes(a1),a1		; get the first plane
	move.l	a1,ofs_write_planes(a7)		; save the plane address

	moveq	#0,d1				; clear the registers
	moveq	#0,d2
	moveq	#0,d3
	moveq	#0,d4
	moveq	#0,d5
	moveq	#0,d6
	moveq	#0,d7

byte_loop:
	moveq	#0,d0				; this must be zero for the shifting to work
	move.l	ofs_read_planes(a7),a0		; get the address of the last plane to read from (+1 for predecrement)
	move.l	ofs_src_offset(a7),a4		; that's the row and column index
	jmp	(a6)				; read from the planes

depth_wr_jmp_tbl:
	dc.l	0
	dc.l	one_deep1
	dc.l	two_deep1
	dc.l	three_deep1
	dc.l	four_deep1
	dc.l	five_deep1
	dc.l	six_deep1
	dc.l	seven_deep1
	dc.l	eight_deep1

depth_rd_jmp_tbl:
	dc.l	0
	dc.l	one_deep
	dc.l	two_deep
	dc.l	three_deep
	dc.l	four_deep
	dc.l	five_deep
	dc.l	six_deep
	dc.l	seven_deep
	dc.l	eight_deep

eight_deep:
	do_plane_rd
seven_deep:
	do_plane_rd
six_deep:
	do_plane_rd
five_deep:
	do_plane_rd
four_deep:
	do_plane_rd
three_deep:
	do_plane_rd
two_deep:
	do_plane_rd
one_deep:
	do_plane_rd

	move.b	0(a2,d0.w),d0			; translate the register contents
	move.b	0(a2,d1.w),d1
	move.b	0(a2,d2.w),d2
	move.b	0(a2,d3.w),d3
	move.b	0(a2,d4.w),d4
	move.b	0(a2,d5.w),d5
	move.b	0(a2,d6.w),d6
	swap	d6
	move.b	0(a2,d6.w),d6
	swap	d6

	move.l	ofs_dst_offset(a7),a4		; that's the row and column index
	move.l	ofs_write_planes(a7),a0		; get the address of the first plane to write to
	jmp	(a5)				; write to the planes

eight_deep1:
	do_plane_wr
seven_deep1:
	do_plane_wr
six_deep1:
	do_plane_wr
five_deep1:
	do_plane_wr
four_deep1:
	do_plane_wr
three_deep1:
	do_plane_wr
two_deep1:
	do_plane_wr
one_deep1:
	do_plane_wr

	addq.l	#1,ofs_dst_offset(a7)		; wrote another byte
	addq.l	#1,ofs_src_offset(a7)		; read another byte
	subq.w	#1,ofs_col_ctr(a7)		; processed another column
	bne	byte_loop			; if there is still another byte, restart

	move.w	ofs_bperrow(a7),ofs_col_ctr(a7)	; reset the column counter
	move.l	ofs_adr_add(a7),d0
	add.l	d0,ofs_src_offset(a7)		; move up to the next source row
	move.l	ofs_dadr_add(a7),d0
	add.l	d0,ofs_dst_offset(a7)		; move up to the next destination row
	subq.w	#1,ofs_row_ctr(a7)		; process another row
	bne	byte_loop			; if there is still another row, restart

	lea	st_depth(a7),a7			; drop the local vars
	movem.l	(a7)+,d2-d7/a2-a6
	rts					; and return

*--------------------------------------------------------------------------

	end
Olaf Barthel is offline  
 
Page generated in 0.07616 seconds with 11 queries