Важная информация

User Tag List

Показано с 1 по 10 из 31

Тема: Выводим спрайт, с проверкой границ экрана

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1
    Veteran
    Регистрация
    01.03.2005
    Адрес
    Новосибирск
    Сообщений
    1,979
    Спасибо Благодарностей отдано 
    69
    Спасибо Благодарностей получено 
    261
    Поблагодарили
    99 сообщений
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию Выводим спрайт, с проверкой границ экрана

    Всех с наступившим 0x7DD годом! Продолжаю эксперименты над выводом спрайта с учётом границ экрана, перетряхнул процедуру и сделал вывод атрибутов.

    Сами атрибуты выводятся в основном цикле, с каждой 8ой строкой спрайта. На мой взгляд это намного быстрее, чем выводить строку отдельной итерацией и тем более быстрее вывода атрибутов отдельным циклом, с учётом специфики границ экрана. Если спрайт не заходит за границы экрана, то подготовка регистров для процедуры вывода (включая проверку границ, расчет фазы атрибутов и адреса экрана) занимает около 300 тактов. При нижней границе у нас отсекается высота спрайта (+16 тактов), а вот верхнюю границу можно немного оптимизировать.

    Процедура по-прежнему не использует стек

    Код:
    	DEVICE ZXSPECTRUM128
    
    	MODULE MAIN
    
    SPR_SIZE=#10
    
    	ORG #8000
    
    START:
            LD SP,#7FFF
            LD HL,#BE00
            LD A,H
            LD I,A
            IM 2
            LD BC,#00BF
            LD (HL),C
            INC HL
            DJNZ $-2
            LD (HL),C
            LD H,C
            LD L,C
            LD (HL),#C9
    
    ST_LOOP:
    	EI
    	HALT
    	LD A,#07
    	OUT (#FE),A
    	
    	LD HL,TEST_SPRITE
    CURS_Y	LD D,0			; D=Y
    CURS_X	LD E,0			; E=X
    	LD B,64			; B=HEIGHT
    	LD C,SPR_SIZE		; C=LEN
    	CALL SPRITE_OUT
    
    	SUB A
    	OUT (#FE),A
    	JP ST_LOOP
    
    
    SPRITE_OUT:
    ;-----------------------------------------------------
    ; Проверка левой и правой границ, расчет длинны строки
    	LD A,E
    	OR A
    	JP P,R_EDGE
    	NEG
    	LD (L_SKIP1),A 
    	LD (L_SKIP2),A
    	NEG
    	ADD A,C	
    	LD E,#00	; Начало левой границы по X
    	EXX
    	LD IY,SP_CL2	; Указатель на процедуру вывода коррекции слева
    	LD DE,PHASE2    ; Указатель на параметр фазы
    	JP LEN_CL
    R_EDGE	ADD A,C
    	SUB #20
    	JR C,NO_COR
    	LD (R_SKIP1),A
    	LD (R_SKIP2),A
    	NEG
    	ADD A,C
    	CP C		; Спрайт на всю ширину экрана?
    	EXX
    	LD IY,SP_CL3	; Процедура вывода коррекции справа
    	LD DE,PHASE3    ; Указатель на параметр фазы
    	JR NZ,LEN_CL
    	EXX
    NO_COR	LD A,C          ; Вывод без коррекции
    	EXX
    	LD IY,SP_CL1	; Указатель на процедуру вывода без коррекции
    	LD DE,PHASE1    ; Указатель на параметр фазы
    LEN_CL	OR A
    	RET M		; Выход, если спрайт целиком за левой или правой границей экрана
    	ADD A,A		; Тут расчитываем длину спрайта для текущего метода вывода
    	SUB #40
    	NEG
    	LD IX,L_OUT1	; Указатель на процедуру вывода LDI (HL-->DE)	
    	LD C,A		; C'=A
    	LD B,#00
    	ADD IX,BC
    	EXX
    ;--------------------------------
    ; Проверка верхней границы экрана
    	LD A,D
    	CP #C1		; Верхняя граница (-1..-63)
    	JR C,D_EDGE
    	NEG             ; A - кол-во пропускаемых строк сверху
    	CP B
    	RET P		; Выход, если спрайт целиком за верхней границей экрана
    	LD D,A
    	PUSH DE
    	RRCA		; Расчитываем сколько строк атрибутов ушло за верхнюю границу
    	RRCA
    	RRCA
    	AND #1F
    	ADD A,D		; Пропускам D/8 строк
    	LD E,A
    	LD D,#00
    	PUSH BC
    	LD A,B
    	EXX
    	INC A
    	AND #07
    	LD (DE),A	; Помещаем код фазы в выбранную процедуру
    	EXX
    	LD B,#06
    MULCYC	SRL C
    	JR NC,NO_ADD
    	ADD HL,DE
    NO_ADD	SLA E
    	RL D
    	DJNZ MULCYC
    	POP AF
    	POP DE
    	SUB D
    	LD B,A
    	LD D,#40	; Начало верхней границы на экране
    	JP (IY)
    ;-------------------------------
    ; Проверка нижней границы экрана
    D_EDGE	LD A,D
    	SUB #C0         ; Нижняя граница > 192 ?
    	RET NC          ; Выход, если спрайт целиком за нижней границей экрана
    	ADD A,B
    	JR NC,CLC_DE	; Не корректируем высоту спрайта
    	SUB B
    	NEG
    	LD B,A
    ;-----------------------------
    ; Расчет экранного адреса
    ; E=X (#00-#1F), D=Y (#00-#BF)
    CLC_DE	LD A,D 		
    	AND #38
    	RLCA
    	RLCA
    	OR E
    	LD E,A
    	LD A,D
    	AND #C0
    	RRA	 
    	SCF	 
    	RRA	 
    	RRCA	 
    	XOR D
    	AND #F8
    	XOR D
    	LD D,A
    ;---------------------------------------
    ; Расчет фазы атрибутов для цикла вывода
    	LD A,B
    	EXX
    	INC A
    	AND #07
    	LD (DE),A	; Помещаем код фазы в выбранную процедуру
    	EXX
    	JP (IY)
    ;---------------------------------------------------
    ; Расчет в DE адрес атрибута, вывод строки атрибутов
    AT_OUT	LD A,D          
    	RRCA
    	RRCA
    	RRCA
    	AND #0B
    	OR #50
    	LD D,A
    ;-----------------------------
    ; Вывод строки спрайта
    L_OUT   LD C,D
    	JP (IX)
    L_OUT1	DUP 32
    	LDI
    	EDUP
    	RET
    ;-----------------------------
    ; Расчет следующего знакоместа
    COR_DE	LD A,E
    	SUB #E0
    	LD E,A
    	SBC A,A
    	AND #F8
    	ADD A,D
    	LD D,A
    	JP (IY)
    ;-----------------------------------------------------
    ; Процедура вывода на экран с атрибутами без коррекции 
    LOOP1	INC D
    	LD A,D
    	AND #07
    	JR Z,COR_DE
    SP_CL1	LD A,E
    	CALL L_OUT
    	DEC DE		; Коррекция D, если Е > #FF
    	LD E,A
    	LD A,B
    	AND #07
    PHASE1  EQU $+1
    	XOR #00         
     	JR Z,A_OUT1    
    	DJNZ LOOP1    
    	RET
    A_OUT1	PUSH DE
    	CALL AT_OUT
    	POP DE
    	DJNZ LOOP1
    	RET
    ;----------------------------------------------------------
    ; Процедура вывода на экран с атрибутами с коррекцией слева
    LOOP2	INC D
    	LD A,D
    	AND #07
    	JR Z,COR_DE
    SP_CL2	LD A,B
    L_SKIP1	EQU $+1
    	LD BC,#0000	; Переменная отступа слева
    	ADD HL,BC
    	LD B,E
    	CALL L_OUT
    	LD E,B		; При сдвиге влево D можно не корректировать
    	LD B,A
    	AND #07
    PHASE2	EQU $+1
    	XOR #00
    	JR Z,A_OUT2
    	DJNZ LOOP2
    	RET
    A_OUT2	PUSH DE
    	LD A,B
    L_SKIP2 EQU $+1
    	LD BC,#0000
    	ADD HL,BC
    	LD B,A
    	CALL AT_OUT
    	POP DE
    	DJNZ LOOP2
    	RET
    ;-----------------------------------------------------------
    ; Процедура вывода на экран с атрибутами с коррекцией справа
    LOOP3	INC D
    	LD A,D
    	AND #07
    	JR Z,COR_DE
    SP_CL3	LD A,B
    	LD B,E
    	CALL L_OUT
    	DEC DE		; Коррекция D, если Е > #FF
    	LD E,B
    R_SKIP1	EQU $+1
    	LD BC,#0000	; Переменная отступа справа
    	ADD HL,BC
    	LD B,A
    	AND #07
    PHASE3	EQU $+1
    	XOR #00
    	JR Z,A_OUT3
    	DJNZ LOOP3
    	RET
    A_OUT3	PUSH DE
    	CALL AT_OUT
    	LD A,B
    R_SKIP2	EQU $+1
    	LD BC,#0000
    	ADD HL,BC
    	LD B,A
    	POP DE
    	DJNZ LOOP3
    	RET
    
    ;----------------
    ; Тестовый спрайт
    	ORG #C000,#00
    TEST_SPRITE:
    	DUP 3	
    
    	DUP 4
    	DS SPR_SIZE,#55
    	DS SPR_SIZE,#AA
    	EDUP
    	DB #41
    	DS SPR_SIZE-2,#01
    	DB #41
    
    	DUP 4
    	DS SPR_SIZE,#F0
    	EDUP
    	DUP 4
    	DS SPR_SIZE,#0F
    	EDUP
    	DB #42
    	DS SPR_SIZE-2,#02
    	DB #42
    
    	DUP 4
    	DS SPR_SIZE,#55
    	DS SPR_SIZE,#AA
    	EDUP
    	DB #43
    	DS SPR_SIZE-2,#03
    	DB #43
    
    	DUP 4
    	DS SPR_SIZE,#F0
    	EDUP
    	DUP 4
    	DS SPR_SIZE,#0F
    	EDUP
    	DB #44
    	DS SPR_SIZE-2,#04
    	DB #44
    
    	DUP 4
    	DS SPR_SIZE,#55
    	DS SPR_SIZE,#AA
    	EDUP
    	DB #45
    	DS SPR_SIZE-2,#05
    	DB #45
    
    	DUP 4
    	DS SPR_SIZE,#F0
    	EDUP
    	DUP 4
    	DS SPR_SIZE,#0F
    	EDUP
    	DB #46
    	DS SPR_SIZE-2,#06
    	DB #46
    
    	DUP 4
    	DS SPR_SIZE,#55
    	DS SPR_SIZE,#AA
    	EDUP
    	DB #07
    	DS SPR_SIZE-2,#47
    	DB #07
    
    	DUP 4
    	DS SPR_SIZE,#F0
    	EDUP
    	DUP 4
    	DS SPR_SIZE,#0F
    	EDUP
    	DB #41
    	DS SPR_SIZE-2,#01
    	DB #41
    
    
    	EDUP
    	PAGE #00
    	SAVESNA "test.sna",START
    	ENDMODULE
    ---

    Upd. во вложении пример использования этой процедуры для вывода спрайта в игре.
    Вложения Вложения
    Последний раз редактировалось drbars; 07.06.2014 в 02:39.

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. времянки экрана Pentagon'а
    от siril в разделе Программирование
    Ответов: 6
    Последнее: 10.08.2011, 00:09
  2. Времянки экрана БК
    от Sandro в разделе БК-0010/0011
    Ответов: 18
    Последнее: 19.12.2010, 19:36
  3. посоветуйте спрайт-едитор
    от boo_boo в разделе Софт
    Ответов: 11
    Последнее: 15.03.2007, 10:43
  4. Самый большой спрайт игрока
    от goodboy в разделе Игры
    Ответов: 17
    Последнее: 21.08.2006, 07:52
  5. Разрешение экрана.
    от CityAceE в разделе Форум
    Ответов: 19
    Последнее: 06.03.2005, 06:37

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •