В Altira 2.40 реакции на стрелки нет. Рожица добегает по строчке слева направо и всё! Нельзя ли другой тест под стрелки? В эмуляторе второй игрок - всегда компьютер.
В Altira 2.40 реакции на стрелки нет. Рожица добегает по строчке слева направо и всё! Нельзя ли другой тест под стрелки? В эмуляторе второй игрок - всегда компьютер.
Последний раз редактировалось andrews; 05.09.2024 в 11:03.
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
все время сначала включали режим, потом задавали спрайты.
Заодно надо посмотреть, где располагается Display List и адресована видеопамять - возможен конфликт.
- - - Добавлено - - -
попробуй адреса 84, 85/86
- - - Добавлено - - -
Код:import stdio import stdlib array hello_world = "Hello world" void main() { putstr(hello_world, hello_world.length) poke(84,5) poke(85,3) putstr(hello_world, hello_world.length) while(true){} }
breeze(05.09.2024)
Супер! Офигенно! То что надо!!!
p.s. с клавиатурой засадаЕсли юзать как в примере с опросом через ROM:
То да, код нажатой клавиши возвращается, но пока не отпустишь нифига нет.Код:lda #$C sta $2A lda $E425 pha lda $E424 pha rts
Если выкинуть кусок в начале:
То да, оно работает. Но во первых каждый раз пибикает, во вторых медленно, а третьих если ни одна клавиша не нажата то из «цикла» не отпускает и всё тупо висит пока не нажмёшь клавишу.Код:lda $E425 // GET ADRESS-VECTOR pha // FROM ROM HANDLER TAB lda $E424 // PLACE ADDRESS AS pha // RETURN ADDRESS TO STACK rts // JUMP TO ROM-ROUTINE
Нужно искать какой-то опрос напрямую через порты, как на спектруме. Но ничего вменяемого пока не нашел.
peek(764). Если клавиша нажата, впиши в нее 255
В общем, какая-то байда с включением видеорежима - не получаю текстовый. Написал код по примеру, теперь не работает print #6. Заставил, чтобы заработало, нашлись доки(:
Код:array(byte) hello_world = [$30,$31,$32,$33,$9B] array(byte) nam=[$53,$3a,$9B] void main() { asm { lda #18 PHA ; Store on stack LDX #$60 ; IOCB6 for screen LDA #$C ; CLOSE command STA $0342,X;ICCOM,X ; in command byte JSR $E456;CIOV ; Do the CLOSE LDX #$60 ; The screen again LDA #3 ; OPEN command STA $0342,X;ICCOM,X ; in command byte LDA #nam&255 ; Name is "S:" STA $0344,X;ICBAL,X ; Low byte LDA #nam/256 ; High byte STA $0345,X;ICBAH,X PLA ; Get GRAPHICS n STA $034B,X;ICAX2,X ; Graphics mode AND #$F0 ; Get high 4 bits EOR #$10 ; Flip high bit ORA #$C ; Read or write STA $034A,X;ICAX1,X ; n+16, n+32 etc. JSR $E456;CIOV ; Setup GRAPHICS n //print #6 lda #2 sta $84 lda #2 sta 85 ldx #$60 lda #hello_world&255 sta $0344,X ; ICBAL lda #hello_world/256 sta $0345,X ; ICBAL lda #9 sta $0342,X ; ICCOM lda #0 sta $0348,X ;ICBLL lda #$FF sta $0349,X ;ICBLH JSR $E456;CIOV lda #0 sta 84 lda #2 sta 85 ldx #$60 lda #nam&255 sta $0344,X ; ICBAL lda #nam/256 sta $0345,X ; ICBAL lda #9 sta $0342,X ; ICCOM lda #0 sta $0348,X ;ICBLL lda #$FF sta $0349,X ;ICBLH JSR $E456;CIOV } // putstr(hello_world, hello_world.length) poke(84,5) poke(85,3) // putstr(hello_world, hello_world.length) while(true){} }
Последний раз редактировалось Shiny; 05.09.2024 в 15:05. Причина: адрес 764, а не 765
Это было не просто, но мы справились. Структура спрайтов на атари это ещё то гениальное решение
Короче доделал универсальную шнягу для отображения спрайта, теперь задаёшь номер 0,1,2,3 и вгружаются данные для Player0 … Player3 соответственно.
Было немного неприятно узнать, что данные спрайта в начале и в конце надо обязательно обрамлять $00 иначе при движении вверх/вниз крайний байт начинает мазать в линию x_x
Сырки:
sprites.mfk
boulder.mfkКод:const byte pmgmem=$80 //pmgmem*256 == place for sprites void sprInit() { poke($D407,pmgmem) // PMGBASE place in memory poke ($022F,%00111110) // SDMCTL - Shadow of $D400 - Direct Memory Access (DMA) Control // Bit Dec Function // 7 128 not used // 6 64 not used // 5 32 Direct Memory Access on=1/off=0 // 4 16 One-line P/M-vertical resolution on=1/off=0 // 3 8 DMA for Players on=1/off=0 // 2 4 DMA for Missiles on=1/off=0 // 0,1 3 Wide playfield (48 bytes/chars) // 0,1 2 Normal playfield (40 bytes/chars) // 0,1 1 Narrow playfield (32 bytes/chars) // 0,1 0 Playfield off poke ($D01D,%00000011) // GRACTL controls PM and Triggers // Bit Function // 7 unused // 6 unused // 5 unused // 4 unused // 3 unused // 2 Latch Triggers when =1 // 1 Turn on players when =1 // 0 Turn on missiles when =1 poke ($026F,1) // GPRIOR Priority Selection Register // Bit Value Description // 0 1 P0-P1-P2-P3 PF0-PF1-PF2-PF3 BAK // 1 2 P0-P1 PF0-PF1-PF2-PF3 P2-P3 BAK // 2 4 PF0-PF1-PF2-PF3 P0-P1-P2-P3 BAK // 3 8 PF0-PF1 P0-P1-P2-P3 PF2-PF3 BAK // 4 16 Four Missiles add up to be 5th player // 5 32 Overlapping Players have 3rd color // 6 64 GTIA Mode see next table // 7 128 GTIA Mode see next table poke ($D008,0) // [W] SIZEP0 size of player 0 // 0 = normal, 1 = double, 3 = quadruple // [R] M0PL Collision Missile 0 with Player poke ($D009,0) // [W] SIZEP1 size of player 1 poke ($D00a,0) // [W] SIZEP2 size of player 2 poke ($D00b,0) // [W] SIZEP3 size of player 3 // poke ($D00b,0) // [W] SIZEM size of missile } //asm void setColor(byte player, byte register(a) m) @ $02C0 + player extern asm void setColor(byte player, byte register(a) m) { LDX player STA $02C0,X RTS } asm void setPosX(byte player, byte register(a) m) { LDX player STA $D000,X RTS } void sprShow(byte sprNum, pointer _sprData, byte _sprSize, byte _sprColor, byte x, byte y) { pointer pmg0 //, pmg1 ubyte i setColor(sprNum, _sprColor) setPosX(sprNum, x) // poke ($D004,x) // HPOSM0 horisontal place missile 0 // poke ($D005,x) // HPOSM1 horisontal place missile 1 // poke ($D006,x) // HPOSM2 horisontal place missile 2 // poke ($D007,x) // HPOSM3 horisontal place missile 3 // copy sprite data to defined place pmg0=word((pmgmem*256) + 1024 + ($100 * sprNum) + y) for i,0,to,_sprSize-1 { pmg0[i]=_sprData[i] } }
- - - Добавлено - - -Код:import stdio import sprites array titleStr = "Boulder Dash ][" array(byte) heroSpr0 = [0,$24,$3c,$5a,$5a,$3c,$18,$3c,$42,$18,0,$18,0] array(byte) heroSpr1 = [0,$18,$24,$18,0,$18,0,0,$66,0] array(byte) heroSpr2 = [0,$24,$24,$24,0] byte color0 = $56 byte color1 = $0e byte color2 = $c6 noinline asm void wait(byte register(a) f) { clc adc os_RTCLOK.b2 .rt_check: cmp os_RTCLOK.b2 bne .rt_check rts } void printAt(byte x, byte y, byte i) { poke(84, y) poke(85, x) putword(i) putstrz(" "z) } void main() { byte pX byte pY byte joy sprInit() putstr(titleStr , titleStr.length) new_line() putstrz("Use JoyStick, LOOK!"z) new_line() pX = 120 pY = 116 putstrz("PosX: "z) putword(pX) new_line() putstrz("PosY: "z) putword(pY) new_line() joy = peek(632) putstrz("JoyStick: "z) putword(joy) sprShow(0, heroSpr0, heroSpr0.length, color0, pX, pY) sprShow(1, heroSpr1, heroSpr1.length, color1, pX, pY+7) sprShow(2, heroSpr2, heroSpr2.length, color2, pX, pY+11) while (true) { wait(1) joy = peek(632) if (joy == 11 || joy == 10 || joy == 9) { pX -= 1 } else if (joy == 7 || joy == 6 || joy == 5) { pX += 1 } if (joy == 14 || joy == 10 || joy == 6) { pY -= 1 } else if (joy == 13 || joy == 9 || joy == 5) { pY += 1 } if (joy != 15) { sprShow(0, heroSpr0, heroSpr0.length, color0, pX, pY) sprShow(1, heroSpr1, heroSpr1.length, color1, pX, pY+7) sprShow(2, heroSpr2, heroSpr2.length, color2, pX, pY+11) printAt(8, 2, pX) printAt(8, 3, pY) printAt(12, 4, joy) } else { printAt(12, 4, joy) } } }
Что бы не рисовать ручками, решил тут поискать спрайты в памяти оригинального Boulder Dash.
Ага, щаз! Судя по структуре похоже оно тайлами фигарит
К слову нашёл сырки, кто-то декомпильнул оригинальный Boulder Dash
andrews(26.10.2024), Oleg N. Cher(06.09.2024)
Интересно, а прокатит ли способ сложения цветов? В Preliminary Monty 16K это выглядит оч даже симпатично.
- - - Добавлено - - -
Добрался до Apple ii
Компиляция
MASTER.dsk можно найти в дистрибутиве AppleWin,AppleCommander-1.3.5 найдете гуглом.Код:java -jar millfork.jar -I .\include\ -t apple2 xp.mfk java -jar AppleCommander-1.3.5.jar -d MASTER.dsk xp java -jar AppleCommander-1.3.5.jar -p MASTER.dsk xp B 0xc00 < xp.a2
первая строка - компиляция
вторая строка - удаление с диска файла xp
третья строка - копирование файла на образ диска
Запуск: BRUN XP
Код xp.mfk
Код://Apple II lowres pattern import stdlib array(byte) cold=[$00,$88,$44,$CC,$EE,$AA,$FF,$55,$77,$66,$22,$33,$11,$BB,$99,$DD] pointer linea @ 0x26//GBASL,GBASH asm byte gbascalc(byte a) @ $F847 extern// in:A=Y coordinate, out:(GBASL,GBASH)=video memory address asm byte setlores() @ $FB40 extern void main() { byte i,y setlores() poke ($C052,0)//enable graphics/text mixed mode for y,0,to,23 { gbascalc(y)//calculate address for i,0,to,39 { linea[i]=cold[(i&y)&15] // linea[i]=cold[i&15]//obly debug output } } while true{} }
Ну шо, таки допилил Онимацию, теперь почти настоящий боудер получился
Как обычно сырки:
boulder.mfk:
блок спрайтов без измененийКод:import stdio import sprites array titleStr = "Boulder Dash ][" array(byte) heroSpr0a = [0,$24,$3c,$5a,$5a,$3c,$18,$3c,$42,$18,0,$18,0] array(byte) heroSpr0b = [0,$24,$3c,$7e,$5a,$3c,$18,$3c,$42,$18,0,$18,0] array(byte) heroSpr0c = [0,$24,$3c,$7e,$7e,$3c,$18,$3c,$42,$18,0,$18,0] array(byte) heroSpr1a = [0,$18,$42,$18,0,$18,0,0,$66,0] array(byte) heroSpr1b = [0,$18,$24,$18,0,$18,0,0,$66,0] array(byte) heroSpr1c = [0,$18,$24,$18,0,$18,0,$60,$06,0] array(byte) heroSpr2a = [0,$24,$24,$24,0] array(byte) heroSpr2b = [0,$24,$24,$04,0] array(pointer) aFrames0 = [ heroSpr0a, heroSpr0b, heroSpr0c, heroSpr0a, heroSpr0b, heroSpr0c, heroSpr0a, heroSpr0b, heroSpr0c, heroSpr0a, heroSpr0a, heroSpr0a, heroSpr0a, heroSpr0a, heroSpr0a, heroSpr0a, heroSpr0a, heroSpr0a, heroSpr0a, heroSpr0a, heroSpr0a ] array(pointer) aFrames1 = [ heroSpr1a, heroSpr1a, heroSpr1a, heroSpr1a, heroSpr1a, heroSpr1a, heroSpr1a, heroSpr1a, heroSpr1a, heroSpr1b, heroSpr1c, heroSpr1b, heroSpr1c, heroSpr1b, heroSpr1c, heroSpr1b, heroSpr1c, heroSpr1b, heroSpr1c, heroSpr1b, heroSpr1c ] array(pointer) aFrames2 = [ heroSpr2a, heroSpr2a, heroSpr2a, heroSpr2a, heroSpr2a, heroSpr2a, heroSpr2a, heroSpr2a, heroSpr2a, heroSpr2a, heroSpr2b, heroSpr2a, heroSpr2b, heroSpr2a, heroSpr2b, heroSpr2a, heroSpr2b, heroSpr2a, heroSpr2b, heroSpr2a, heroSpr2b ] array(byte) aTime = [ 150, 3, 3, 150, 3, 3, 150, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 ] byte color0 = $56 byte color1 = $0e byte color2 = $c6 noinline asm void wait(byte register(a) f) { clc adc os_RTCLOK.b2 .rt_check: cmp os_RTCLOK.b2 bne .rt_check rts } void printAt(byte x, byte y, byte i) { poke(84, y) poke(85, x) putword(i) putstrz(" "z) } void main() { byte pX byte pY byte joy byte posFrame byte curTime word curFrame0 word curFrame1 word curFrame2 sprInit() putstr(titleStr , titleStr.length) new_line() putstrz("Use JoyStick, LOOK!"z) new_line() pX = 120 pY = 116 putstrz("PosX: "z) putword(pX) new_line() putstrz("PosY: "z) putword(pY) new_line() joy = peek(632) putstrz("JoyStick: "z) putword(joy) posFrame = 0 curTime = aTime[posFrame] curFrame0 = aFrames0[posFrame] curFrame1 = aFrames1[posFrame] curFrame2 = aFrames2[posFrame] sprShow(0, curFrame0, heroSpr0a.length, color0, pX, pY) sprShow(1, curFrame1, heroSpr1a.length, color1, pX, pY+7) sprShow(2, curFrame2, heroSpr2a.length, color2, pX, pY+11) while (true) { wait(1) joy = peek(632) if (joy == 11 || joy == 10 || joy == 9) { pX -= 1 } else if (joy == 7 || joy == 6 || joy == 5) { pX += 1 } if (joy == 14 || joy == 10 || joy == 6) { pY -= 1 } else if (joy == 13 || joy == 9 || joy == 5) { pY += 1 } if (joy != 15) { sprShow(0, curFrame0, heroSpr0a.length, color0, pX, pY) sprShow(1, curFrame1, heroSpr1a.length, color1, pX, pY+7) sprShow(2, curFrame2, heroSpr2a.length, color2, pX, pY+11) printAt(8, 2, pX) printAt(8, 3, pY) printAt(12, 4, joy) } else { printAt(12, 4, joy) } curTime -= 1 if (curTime == 0) { posFrame += 1 if (posFrame == aTime.length) { posFrame = 0 } curTime = aTime[posFrame] curFrame0 = aFrames0[posFrame] curFrame1 = aFrames1[posFrame] curFrame2 = aFrames2[posFrame] sprShow(0, curFrame0, heroSpr0a.length, color0, pX, pY) sprShow(1, curFrame1, heroSpr1a.length, color1, pX, pY+7) sprShow(2, curFrame2, heroSpr2a.length, color2, pX, pY+11) } } }
andrews(26.10.2024), Oleg N. Cher(07.09.2024)
Я конечно знатно прифигел, пока разбирался со спрайтами на атари и как ими рулить. Но я честно не подозревал какая ещё большая Ж с «ракетами». Это какой-то ппц:
В смысле 2 пикселя? o_O Нахрена оно мне такое надо это недопаделие?Каждый спрайт имеет ширину 8 пикселей и всего 2 цвета (1 + прозрачный)
есть 4 «нормальных» спрайта шириной 8 пикселей... и 4 спрайта ракет шириной всего 2(!) пикселя...
но мы можем расположить их вместе, чтобы получить 5 спрайтов.
Я честно думал, что у меня будет 4 спрайта игроков и 4 спрайта противников (ракет) и сталкиваясь будет срабатывать коллизия.
А тут получается всего 4 спрайта и какие-то 4 каличных пульки.
Я в печали. Вообще тогда какой-либо смысл юзания спрайтов сваливается в 0. Смысл? Если даже сделать например 2 спрайта игрока и 2 спрайта противника, то как я понял коллизии между ними нет?
@Shiny тебе слово.
Нормальные там пульки. Насчет столкновений не интересовался, но в Mapping есть описание по адресам $D000 и дальше.
- - - Добавлено - - -
Вот книга по pmg.
breeze(07.09.2024)
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)