| Разработка и ромхакинг > Ромхакинг и программирование |
| [NES] Не могу разобраться с палитрами и атрибутами на асм |
| (1/2) > >> |
| baralgin1003:
День добрый! еще остались тут знатоки асма 6502? в общем ситуация такая: разобрался как грузить тайлы, а как их красить понять не могу. Может как то можно подключать палитру через .incbin ? логику работы атрибутов не понял вообще... |
| Ti_:
--- Цитата: baralgin1003 от 16 Август 2013, 22:03:04 ---День добрый! еще остались тут знатоки асма 6502? в общем ситуация такая: разобрался как грузить тайлы, а как их красить понять не могу. Может как то можно подключать палитру через .incbin ? логику работы атрибутов не понял вообще... --- Конец цитаты --- Ну как понять красить? Палитра в $3F00 загружена? Экран(бекграунд) включил? Или проблема только в выборе палитры для нужного блока. Ее можно выставлять только для 4 тайлов сразу (блок 2x2 тайла) . Как я понимаю первые 2 бита в памяти атрибут соотвествуют 1-ому блоку - ну и так далее. Хотя лучше доки почитай - могу врать. :lol: Ещё смотри там фон кривой по вертикали. Надо -8 смещение выставить, а не 0. |
| baralgin1003:
как я понял, атрибутами мы выставляем цвет из палитры, а по какому принципу и в какой последовательности это делать, я не пойму. палитра загружена, бекграунд включен. блок получается 2х2 тайла? это 16х16 пикселей. неужели такую область можно закрастить только одним цветом? |
| Ti_:
--- Цитата: baralgin1003 от 17 Август 2013, 00:34:33 ---как я понял, атрибутами мы выставляем цвет из палитры, а по какому принципу и в какой последовательности это делать, я не пойму. палитра загружена, бекграунд включен. блок получается 2х2 тайла? это 16х16 пикселей. неужели такую область можно закрастить только одним цветом? --- Конец цитаты --- Ну, не одним цветом, а одной палитрой. То есть 3 цвета + ещё 4-ый цвет фона, общий для всех. То есть всего имеем до 13 цветов на фон. В атрибутах и указываешь номер палитры - от 1-ой до 4-ой для этого блока. http://wiki.nesdev.com/w/index.php/Attribute_table |
| baralgin1003:
ну да, начинаю разбираться))) вот еще вопрос: как мне в фон загрузить большую картинку? размером 16х16 тайлов, чтоб была в середине экрана. сейчас делаю по-деревенски: --- Код: ---background: .db $0,$0,$0,$0,$0,$0,$0,$0,$00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0A,$0B,$0C,$0D,$0E,$0F,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1A,$1B,$1C,$1D,$1E,$1F,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4A,$4B,$4C,$4D,$4E,$4F,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5A,$5B,$5C,$5D,$5E,$5F,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6A,$6B,$6C,$6D,$6E,$6F,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7A,$7B,$7C,$7D,$7E,$7F,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8A,$8B,$8C,$8D,$8E,$8F,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$90,$91,$92,$93,$94,$95,$96,$97,$98,$99,$9A,$9B,$9C,$9D,$9E,$9F,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$A0,$A1,$A2,$A3,$A4,$A5,$A6,$A7,$A8,$A9,$AA,$AB,$AC,$AD,$AE,$AF,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$B0,$B1,$B2,$B3,$B4,$B5,$B6,$B7,$B8,$B9,$BA,$BB,$BC,$BD,$BE,$BF,$0,$0,$0,$0,$0,$0,$0,$0 .db $0,$0,$0,$0,$0,$0,$0,$0,$C0,$C1,$C2,$C3,$C4,$C5,$C6,$C7,$C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF,$0,$0,$0,$0,$0,$0,$0,$0 --- Конец кода --- и дальше в цикле загружаю --- Код: ---LoadBackgroundLoop: LDA background, x ; считаем данные (background + the value in x) STA $2007 ; запишем их в PPU INX ; X = X + 1 CPX #$FF ; сравним X со значением $FF, BNE LoadBackgroundLoop ; переход к LoadBackgroundLoop если нет совпадения --- Конец кода --- то есть, мне не хватает FF, чтоб перебрать всю директорию .db. |
| Ti_:
--- Цитата: baralgin1003 от 17 Август 2013, 12:04:24 ---ну да, начинаю разбираться))) вот еще вопрос: как мне в фон загрузить большую картинку? размером 16х16 тайлов, чтоб была в середине экрана. сейчас делаю по-деревенски: --- Конец цитаты --- --- Код: ---Ну как-то так можно (карту закидываешь в ром $8000) : LDY #$00 ; адрес карты тайлов младший STY 0 LDA #$80 ; адрес карты тайлов старший STA 1 LDX #4 ; повторить 4 раза copy: LDA (0),Y STA $2007 INY BNE copy ; 256 байт. INC 1 ; увеличиваем верхний байт DEX ; счетчик повторений BNE copy ; всего закинули 4раза по 256 = 1024 байта --- Конец кода --- --- Цитата: baralgin1003 от 17 Август 2013, 12:04:24 --- размером 16х16 тайлов, чтоб была в середине экрана. --- Конец цитаты --- Сделай лучше полную (32x30), можно будет закинуть целиком, не придется сбрасывать адрес после каждых 16 байт. А где нужно просто сам пропиши тайлы. Плюс такую можно будет открывать в редакторе NESSt (1024 байт полная с атрибутами, 960 без атрибут). |
| baralgin1003:
сделал, не грузит в PPU :( серый экран, хотя тайлы приземлились по $8000 (молестером смотрел). почти полный экран сделал (256х191) пардон, ступил. ща попробую выровнить картинку не грузит почему то... в PPU картинка сидит, а вот грузит он (скорее всего) так же до FF, при том один тайл. логика программы вроде правильна |
| evgeny:
Не Y надо увеличивать, а младший байт. |
| baralgin1003:
действительно, изменив на --- Код: ---copy: LDA (0),Y STA $2007 INC 0 BNE copy ; 256 байт. DEX ; счетчик повторений BNE copy --- Конец кода --- стала показываться картинка, которая лежит в бекграунд зоне, то, что попало в спрайтовую зону PPU - не отображается |
| Ti_:
--- Цитата: evgeny от 19 Август 2013, 09:37:59 ---Не Y надо увеличивать, а младший байт. --- Конец цитаты --- --- Цитата: baralgin1003 от 19 Август 2013, 09:51:11 ---действительно, изменив на стала показываться картинка, --- Конец цитаты --- С чего бы это? У меня работает, пруф: |
| baralgin1003:
у меня NESASM, перенес твой код туда .inesprg 1 ; 1x 16KB PRG-кода .ineschr 1 ; 1x 8KB CHR-кода .inesmap 0 ; mapper 0 = NROM, без использования мапперов .inesmir 1 ; фоновое зеркалирование ;;;;;;;;;;;;;;; .bank 0 .org $C000 RESET: SEI ; запрещаем внешнее прерывание CLD ; запрещаем десятичный режим LDX #$40 STX $4017 ; запрещаем аудио LDX #$FF TXS ; Установка стека INX ; в регистр X кладем 0 STX $2000 ; запрет вектора NMI STX $2001 ; запрет прорисовки STX $4010 ; запрет DMC IRQ vblankwait1: ; подождем vblank, чтобы убедиться, что PPU готов BIT $2002 BPL vblankwait1 clrmem: ; очистка памяти LDA #$00 STA $0000, x STA $0100, x STA $0200, x STA $0400, x STA $0500, x STA $0600, x STA $0700, x LDA #$FE STA $0200, x ;убрать все спрайты с экрана INX BNE clrmem vblankwait2: ; Second wait for vblank, PPU is ready after this BIT $2002 BPL vblankwait2 w: lda $2002 bpl w dex bpl w ;----------------- lda #$20 ldy #0 sta $2006 sty $2006 sty 0 lda #$80 sta 1 ;----------------- LDY #$00 ; адрес карты тайлов младший STY 0 LDA #$80 ; адрес карты тайлов старший STA 1 LDX #4 ; повторить 4 раза copy: LDA (0),Y STA $2007 INY BNE copy ; 256 байт. INC 1 ; увеличиваем верхний байт DEX ; счетчик повторений BNE copy lda #$3F sta $2006 sty $2006 copy_palette: LDA (0),Y STA $2007 INY CPY #16 bne copy_palette ;----------------- lda #8 sta $2001 lda #$B0 sta $2000 cli LDA #%10010000 ;разрешаем NMI, спрайты из шаблона 0, фон из шаблона Pattern 1 STA $2000 LDA #%00011110 ; разрешим спрайты, разрешим фон STA $2001 Forever: JMP Forever ;jump back to Forever, infinite loop NMI: LDA #$00 STA $2003 ; set the low byte (00) of the RAM address LDA #$02 STA $4014 ; set the high byte (02) of the RAM address, start the transfer ; очищем PPU чтобы отрисовать следующий кадр LDA #%10010000 ;разрешаем NMI, спрайты из шаблона 0, фон из шаблона Pattern 1 STA $2000 LDA #%00011110 ; разрешим спрайты, разрешим фон STA $2001 LDA #$00 ;;tell the ppu there is no background scrolling STA $2005 STA $2005 RTI ; return from interrupt ;;;;;;;;;;;;;; .org $FFFA ;first of the three vectors starts here .dw NMI ;when an NMI happens (once per frame if enabled) the ;processor will jump to the label NMI: .dw RESET ;when the processor first turns on or is reset, it will jump ;to the label RESET: .dw 0 ;external interrupt IRQ is not used in this tutorial ;;;;;;;;;;;;;; .bank 2 .org $8000 .incbin "map.nam" .incbin "pal.pal" .incbin "fore3.chr" ;includes 8KB graphics file from SMB1 PPU вообще пустой. из-за разных асмов может быть такое? подскажи еще, плиз, чем графику лучше делать? твоя картинка в молексе по-другому смотрится, блоки по-разному расположены у нас. из бмп перегонял прогой Map Image. YY-CHR обрезает картинку |
| Ti_:
--- Цитата: baralgin1003 link=topic=67195.msg971201#msg971201 ---PPU вообще пустой. из-за разных асмов может быть такое? подскажи еще, плиз, чем графику лучше делать? --- Конец цитаты --- Предположу что nesasm воспринимает --- Код: --- (0),Y как 0,Y . --- Конец кода --- Может там другая форма записи нужна вроде --- Код: ---[0],Y. --- Конец кода --- Вообще лучше не юзай его, там есть как минимум один баг - он мне попался когда делал сборщик объектов к хаку котов: длинные строчки 'обрезаются' - при этом никаких ошибок не пишет. Картинки можно в Nes Screen Tool как вариант. Там есть импорт из БМП. Насчет спрайтов yy-chr возможностей хватает вроде. |
| baralgin1003:
юзаю nesasm, потому что нашел по нему туториал ^_^ выдержка из доки: --- Цитата --- Operand syntax -------------- A accumulator #i immediate <n zero page <n,X zero page indexed by X <n,Y zero page indexed by Y [n] indirect (*) [n,X] indirect pre-indexed by X (*) [n],Y indirect zero page post-indexed by Y r relative n absolute n,X absolute indexed by X n,Y absolute indexed by Y (*) can be zero page or absolute --- Конец цитаты --- похоже действительно надо заменить скобки еще отличия: --- Цитата ---You can start with NESASM. When you get some basics, you can move to another assembler. You can even continue with NESASM for quite long time, I made two games with it without much troubles. I guess it will start to be problematic with a large scale project. Some differences are: - NESASM's local labels are starting with . (dot) while Asm6 local labels starting with @. So .label turns into @label. - NESASM has LOW and HIGH words to get LSB and MSB of a 16-bit value; Asm6 uses < and > symbols instead. So, lda #LOW(n) turns into lda #<n - NESASM uses [ ] brackets for relative addressing while Asm6 uses ( ) brackets. So lda [TEMP],y turns into lda (TEMP),y - Asm6 does not use . before .db, .dw, .byte, .word keywords. Just remove the dot. --- Конец цитаты --- погуглив, решил таки перебраться на асм6. а нет ли случайно исходников бегущей строки? хотелось бы поиграться |
| Guyver(X.B.M.):
Товарищи, подскажите. NESASM3 В игре при нажатии кнопки у меня короткий выводится звук: --- Цитата --- lda #%00000001 sta $4015 ;enable square 1 lda #%01010111 ;Duty 10, Volume F sta $4000 lda #$C9 ;0C9 is a C# in NTSC mode sta $4002 lda #$03 sta $4003 --- Конец цитаты --- Как сделать два последовательных звука с задержкой между ними? Подскажите примером... Очень нужно. |
| Shredder:
--- Цитата: Guyver(X.B.M.) от 19 Август 2017, 13:05:56 ---Как сделать два последовательных звука с задержкой между ними? Подскажите примером... Очень нужно. --- Конец цитаты --- Проиграй звук #1, затем загрузи положительное число в одну из ячеек оперативы и поставь на эту ячейку обратный отсчёт. Сделай, чтобы состояние счётчика проверялось постоянно, независимо от нажатий кнопок. Когда счётчик станет меньше 0, проиграй звук #2 и установи 0 в счётчик. Если интервал между звуками большой, то может понадобиться 2 связанных счётчика. |
| Guyver(X.B.M.):
Эх, голая теория :о) Я даже просто счётчик с трудом сделаю... |
| Shredder:
После проги проигрывания звука добавь: LDA 7F ; это максимальное число со знаком "+" (положительные: интервал 00-7F, отрицательные: 80-FF) STA 0500 ; загрузка числа 7F в ячейку оперативы #0500, вместо 0500 используй любую свободную ячейку Далее добавляешь в код в любом месте игры, который выполняется постоянно: $0000 - LDA 0500 ; проверяем состояние нашей ячейки, загружая её содержимое в аккумулятор $0001 - BEQ 0007 ; если в ячейке был 0, то пропускаем весь следующий добавленный нами код, словно его нет :) $0002 - DEC 0500 ; если в ячейке не 0, то вычитаем из счётчика единицу $0003 - BPL 0007 ; пропускаем загрузку звука #2, если знак предыдущей операции - "плюс"; а если в результате операции получился "минус" (счётчик достиг FF), то устанавливаем счётчик в 0 и прыгаем на любой выбранный адрес с прогой для проигрывания звука #2 $0004 - LDA 00 ; загружаем в аккумулятор 0 $0005 - STA 0500 ; устанавливаем счётчик в 0 $0006 - ; старт загрузки звука #2 $0007 |
| Guyver(X.B.M.):
Допустим, у меня 2 звука, каждый в своей подпрограмме: Playsound1: ;;звук 1 lda #$FF sta $4000 lda #%10011010 sta $4001 lda #$C5 sta $4002 lda #$CB sta $4003 lda #%00000001 sta $4015 rts Playsound2: ;;звук 2 lda #$FF sta $4000 lda #%11111010 sta $4001 lda #$35 sta $4002 lda #$3B sta $4003 lda #%00000001 sta $4015 rts Так я их вызывать буду в нужный момент: jsr Playsound1 jsr Playsound2 Непонятен счётчик - я не могу привести его к виду, который понимает NESASM3, вылазит куча ошибок... Помогите с синтаксисом... |
| MC68k:
--- Цитата ---Допустим, у меня 2 звука, каждый в своей подпрограмме: --- Конец цитаты --- --- Код: ---var1 EQU $0700 var2 EQU $0701 lda #%10011010 JSR beep ;здесь задржка. сделать можно по-разному, например LDA #0 STA var1 LDA #9 STA var2 loop:DEC var1 BNE loop DEC var2 BNE loop LDA #%11111010 JSR beep RTS beep:STA $4001 LDA #$FF STA $4000 #$C5 STA $4002 LDA #$CB STA $4003 LDA #1 STA $4015 RTS --- Конец кода --- |
| Guyver(X.B.M.):
Чегой-то не работает. Что есть var1 и var2, можно для примера? |
| Навигация |
| Главная страница сообщений |
| Следующая страница |