эффект когда плывет палитра? а может чорный высветлять до белого и назад?
а если набор микровзрывов?
Вид для печати
При взятии монеты эффект создаётся вот как - в программе обработки прерываний срабатывает следующее:
mvi a,251
out 02
С палитрой это не связано напрямую.
Чёрный до белого и назад кажется будет слишком контрастно (на мой взгляд).
Насчёт набора микровзрывов хорошая идея, попробую !!
Игра готова по всем пунктам, кроме музыки.
Осталось вставить музыку и может некоторые звуки изменить.
После различных оптимизаций кода и информации удалось неплохо сократить файл - на данный момент игра занимает 30756 байт
Можно ещё кое-что ужать но похоже этого хватит.
metamorpho, а картинки из игры, ака скриншоты
в первый пост
Наткнулся в закромах на файл "Миссия невыполнима.mid", правда в ней только часть темы.
Написал простенький музыкальный редактор. К нему написал свой плеер. Возникла проблема не пойму почему так работает.
Плеер у меня обрабатывает три канала отдельно. Каждый канал отдельно работает правильно, но если их сразу три запускать то один играет, а два других "хрипят".
В чём может быть проблема ? Может есть какая-то особенность программирования каналов ВИ53 ?
Вот код:
Скрытый текст
;
;-----------------------------------------------
; Super player 08.2020
;-----------------------------------------------
;
;==== Мой формат плеера:
;===================================
pit_init1 .equ 36h
pit_init2 .equ 76h
pit_init3 .equ 0b6h
timeron .equ 1h
;
;------------------------------------
.ORG 0100H
; =======================
M0000H: DI
XRA A
OUT 10H ;
;
MVI A,0C3H
STA 0000H ;
STA 0038H ;
LXI H,M0000H
SHLD 0001H
LXI H,vsync
SHLD 0039H
;
LXI SP,100H
end_program:
mvi a, pit_init1 ; отключить канал 1
out $08
mvi a, pit_init2 ; отключить канал 2
out $08
mvi a, pit_init3 ; отключить канал 3
out $08
;
lxi h, repeat_point1 ;
shld data_pointer1 ; инициализация канала 1
lxi h, repeat_point2 ;
shld data_pointer2 ; инициализация канала 2
lxi h, repeat_point3 ;
shld data_pointer3 ; инициализация канала 3
mvi a, 1 ;
sta wait_counter1 ;
sta wait_counter2
sta wait_counter3
ei
command_line:
jmp command_line
;
;============================================ Плеер в программе обработки прерываний
;
vsync:
push h
push d
push b
push psw
;======================= обработка канала 1
kanal1:
lxi h,wait_counter1 ; отрабатываем установленную длительность
dcr m
jnz kanal2 ; переход если длительность не равна нулю
; ===== иначе если равна нулю то загружаем следующие данные
read_command1:
lhld data_pointer1 ; читаем данные
mov a,m
inx h
shld data_pointer1
cpi 255 ; проверяем это не конец мелодии ?
jnz oktava_can1 ; если нет то идём на обработку данных
; если конец мелодии канала то глушим канал
mvi a, 36h ; отключить канал 1
out $08
lxi h, repeat_point1 ; перезапуск мелодии
shld data_pointer1
jmp kanal2 ; переход на канал 2
;==================================================== проверка октавы
oktava_can1:
; ==============отсеиваем только то что от 108-114
cpi 114
jnc dlina_can1 ; если больше 114 то уходим
cpi 108
jc dlina_can1 ; если меньше 108 то уходим
call oktavian ; возвращает в HL адрес октавы
shld oktava_counter1 ; установка октавы для канала
lhld data_pointer1 ; читаем данные
mov a,m
inx h
shld data_pointer1
;============================================== проверка это длительность ?
dlina_can1:
; ==============отсеиваем только то что от 101-107
cpi 107
jnc off_1 ; если больше 114 то уходим
cpi 101
jc off_1 ; если меньше 108 то уходим
call dlinachiz ; возвращает в A длительность канала
sta swait_counter1 ; установка длительности для канала
lhld data_pointer1 ; читаем данные
mov a,m
inx h
shld data_pointer1
;============================================== проверка это пауза ?
off_1:
cpi 100
jnz set_1
mvi a,36h ; выключить канал 1
out 08
lda swait_counter1 ; взять длительность канала
sta wait_counter1 ; установка текущей длительности для канала
jmp kanal2 ; переход на канал 2
;============================================== значит это НОТА 1-12
set_1:
lhld oktava_counter1 ; берём адрес октавы для ноты
lxi d, 0002h; вычисляем адрес ноты
rizunok1:
dcr a
jz wuwitron1 ; нашли адресс ноты
dad d
jmp rizunok1
wuwitron1:
mvi a,36h ; задать режим для канала 1 (включить канал)
out 08
mov a, m
out 0bH
inx h
mov a, m
out 0bH
lda swait_counter1 ; взять длительность канала
sta wait_counter1 ; установка текущей длительности для канала
;==============================================================
;======================= обработка канала 2
;==============================================================
kanal2:
lxi h,wait_counter2 ; отрабатываем установленную длительность
dcr m
jnz kanal3 ; переход если длительность не равна нулю
; ===== иначе если равна нулю то загружаем следующие данные
read_command2:
lhld data_pointer2 ; читаем данные
mov a,m
inx h
shld data_pointer2
cpi 255 ; проверяем это не конец мелодии ?
jnz oktava_can2 ; если нет то идём на обработку данных
; если конец мелодии канала то глушим канал
mvi a, 76h ; отключить канал 2
out $08
lxi h, repeat_point2 ; перезапуск мелодии
shld data_pointer2
jmp kanal3 ; переход на канал 2
;==================================================== проверка октавы
oktava_can2:
; ==============отсеиваем только то что от 108-114
cpi 114
jnc dlina_can2 ; если больше 114 то уходим
cpi 108
jc dlina_can2 ; если меньше 108 то уходим
call oktavian ; возвращает в HL адрес октавы
shld oktava_counter2 ; установка октавы для канала
lhld data_pointer2 ; читаем данные
mov a,m
inx h
shld data_pointer2
;============================================== проверка это длительность ?
dlina_can2:
; ==============отсеиваем только то что от 101-107
cpi 107
jnc off_2 ; если больше 114 то уходим
cpi 101
jc off_2 ; если меньше 108 то уходим
call dlinachiz ; возвращает в A длительность канала
sta swait_counter2 ; установка длительности для канала
lhld data_pointer2 ; читаем данные
mov a,m
inx h
shld data_pointer2
;============================================== проверка это пауза ?
off_2:
cpi 100
jnz set_2
mvi a,76h ; выключить канал 2
out 08
lda swait_counter2 ; взять длительность канала
sta wait_counter2 ; установка текущей длительности для канала
jmp kanal3 ; переход на канал 2
;============================================== значит это НОТА 1-12
set_2:
lhld oktava_counter2 ; берём адрес октавы для ноты
lxi d, 0002h; вычисляем адрес ноты
rizunok2:
dcr a
jz wuwitron2 ; нашли адресс ноты
dad d
jmp rizunok2
wuwitron2:
mvi a,76h ; задать режим для канала 2 (включить канал)
out 08
mov a, m
out 0aH
inx h
mov a, m
out 0aH
lda swait_counter2 ; взять длительность канала
sta wait_counter2 ; установка текущей длительности для канала
;==============================================================
;======================= обработка канала 3
;==============================================================
kanal3:
lxi h,wait_counter3 ; отрабатываем установленную длительность
dcr m
jnz end_int ; выход из прерываний если длительность не равна нулю
; ===== иначе если равна нулю то загружаем следующие данные
read_command3:
lhld data_pointer3 ; читаем данные
mov a,m
inx h
shld data_pointer3
cpi 255 ; проверяем это не конец мелодии ?
jnz oktava_can3 ; если нет то идём на обработку данных
; если конец мелодии канала то глушим канал
mvi a, 0b6h ; отключить канал 3
out $08
lxi h, repeat_point3 ; перезапуск мелодии
shld data_pointer3
jmp end_int ; выход из прерываний
;==================================================== проверка октавы
oktava_can3:
; ==============отсеиваем только то что от 108-114
cpi 114
jnc dlina_can3 ; если больше 114 то уходим
cpi 108
jc dlina_can3 ; если меньше 108 то уходим
call oktavian ; возвращает в HL адрес октавы
shld oktava_counter3 ; установка октавы для канала
lhld data_pointer3 ; читаем данные
mov a,m
inx h
shld data_pointer3
;============================================== проверка это длительность ?
dlina_can3:
; ==============отсеиваем только то что от 101-107
cpi 107
jnc off_3 ; если больше 114 то уходим
cpi 101
jc off_3 ; если меньше 108 то уходим
call dlinachiz ; возвращает в A длительность канала
sta swait_counter3 ; установка длительности для канала
lhld data_pointer3 ; читаем данные
mov a,m
inx h
shld data_pointer3
;============================================== проверка это пауза ?
off_3:
cpi 100
jnz set_3
mvi a,0b6h ; выключить канал 3
out 08
lda swait_counter3 ; взять длительность канала
sta wait_counter3 ; установка текущей длительности для канала
jmp end_int ; выход из прерываний
;============================================== значит это НОТА 1-12
set_3:
lhld oktava_counter3 ; берём адрес октавы для ноты
lxi d, 0002h; вычисляем адрес ноты
rizunok3:
dcr a
jz wuwitron3 ; нашли адресс ноты
dad d
jmp rizunok3
wuwitron3:
mvi a,0b6h ; задать режим для канала 3 (включить канал)
out 08
mov a, m
out 09H
inx h
mov a, m
out 09H
lda swait_counter3 ; взять длительность канала
sta wait_counter3 ; установка текущей длительности для канала
;=================================
end_int:
pop psw
pop b
pop d
pop h
;
ei
ret
;
;
;============================================================
;---------------------------
; контр-октава (12 нот)
note_table1:
dw 45872,43290,40872,38560,36408,34364,32432,30612,28902,27273,25729,24311 ; до/до#/ре/ре#/ми/фа/фа#/соль/соль#/ля/ля#/си
; большая-октава
note_table2:
dw 22936,21645,20436,19280,18204,17182,16216,15306,14451,13636,12876,12146 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
; малая-октава
note_table3:
dw 11468,10823,10218,9646,9102,8591,8108,7653,7229,6818,6438,6075 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
; 1-я октава
note_table4:
dw 5734,5415,5107,4823,4551,4296,4054,3827,3614,3409,3219,3036 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
; 2-я октава
note_table5:
dw 2867,2708,2554,2412,2275,2147,2027,1913,1805,1705,1609,1519 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
; 3-я октава
note_table6:
dw 1433,1353,1277,1205,1137,1074,1014,957,904,852,804,759 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
; 4-я октава
note_table7:
dw 717,677,639,602,569,537,507,472,452,426,402,380 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
;================sound_data: .db
repeat_point1: db 111,104,1,2,3,4,5,6,7,8,9,10,11,12,255
repeat_point2: db 112,104,1,2,3,4,5,6,7,8,9,10,11,12,255
repeat_point3: db 113,104,1,2,3,4,5,6,7,8,9,10,11,12,255
;255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
;---------------------------
data_pointer1: .dw 0 ; позиция в нотном массиве для канала 1
data_pointer2: .dw 0 ; позиция в нотном массиве для канала 2
data_pointer3: .dw 0 ; позиция в нотном массиве для канала 3
wait_counter1: .db 0 ; текущее вычисление длительность для канала 1
wait_counter2: .db 0 ; текущее вычисление длительность для канала 2
wait_counter3: .db 0 ; текущее вычисление длительность для канала 3
swait_counter1: .db 0 ; установленная длительность для канала 1
swait_counter2: .db 0 ; установленная длительность для канала 2
swait_counter3: .db 0 ; установленная длительность для канала 3
oktava_counter1: .db 0 ; установленная ОКТАВА для канала 1
oktava_counter2: .db 0 ; установленная ОКТАВА для канала 2
oktava_counter3: .db 0 ; установленная ОКТАВА для канала 3
;=======================================
; подпрограммы определения длительности
dlinachiz:
cpi 101
jnz ghtimin1
mvi a,255 ;------ 1 - full
ret
ghtimin1:
cpi 102
jnz ghtimin2
mvi a,128 ;------ 1/2
ret
ghtimin2:
cpi 103
jnz ghtimin3
mvi a,64 ;------ 1/4
ret
ghtimin3:
cpi 104
jnz ghtimin4
mvi a,32 ;------ 1/8
ret
ghtimin4:
cpi 105
jnz ghtimin5
mvi a,16 ;------ 1/16
ret
ghtimin5:
cpi 106
jnz ghtimin6
mvi a,8 ;------ 1/32
ret
ghtimin6:
cpi 107
rnz
mvi a,4 ;------ 1/64
ret
;=======================================
; подпрограммы определения октавы
oktavian:
cpi 108
jnz timin1
lxi h,note_table1 ; контр-октава
ret
timin1:
cpi 109
jnz timin2
lxi h,note_table2 ; большая-октава
ret
timin2:
cpi 110
jnz timin3
lxi h,note_table3 ; малая-октава
ret
timin3:
cpi 111
jnz timin4
lxi h,note_table4 ; 1-я октава
ret
timin4:
cpi 112
jnz timin5
lxi h,note_table5 ; 2-я октава
ret
timin5:
cpi 113
jnz timin6
lxi h,note_table6 ; 3-я октава
ret
timin6:
cpi 114
rnz
lxi h,note_table7 ; 4-я октава
ret
;==============================
.end
[свернуть]
Не уверен, решит ли это проблему хрипа, но задавать режим канала таймера при каждом изменении делителя - это лишнее. Надо один раз в начале инициализировать все три канала и в паузах соответствующий канал.
oktava_counterы нужно поменять с db на dw
ivagor, спасибо большое - ПОМОГЛО !!
Автоматически скопировал при наборе и неподумал. А потом это же очевидно должно быть DW т.к. адресс два байта. Куда я смотрел не знаю ?
Да проблемы бывают кроются в чём-то более простом, а мы ищем их в сложном.
Зато я перерыл по теме ВИ53 журналы "Вектор-User", "Байты" и Черезова заодно посмотрел - искал там особенности программирования ВИ53, а тут банальное DW :)
Вот Шедевр! http://sensi.org/scalar/ware/436/
Только коротковат :(
Я так понимаю игра очень поздняя.
Игра готова. Обновил первый пост.
Как можно добавить её сюда?
Тогда, попросим @svofski в тему.
Вот!
http://sensi.org/scalar/ware/910
Чего-то мне кажется, что иногда мерцает. Или это спецэффект при съедании монетки?
metamorpho, игрушка очень красивая, но для казуального меня сложноватая. Насчет эффекта при взятии монетки согласен со svofski - как-то не очень. И бывает артефакт, когда при скролле от вертолета остается фрагмент.
Да мерцает - это такой спецэффект :)
svofski, спасибо за внесение в картотеку!!
- - - Добавлено - - -
ivagor, спасибо за отзыв!!
Да немного хардкора там есть :)
Насчёт эффекта - например могу сделать специальную версию без этого эффекта - если нужно :)
Про артефакт с вертолётом знаю, возможно позже исправлю, но сначала нужно понять откуда он растёт :)
Добавить в игру метку с номером сборки.
Доработать Редактор уровней, чтобы он проверял на соответствие номера сборки и менял уровни в rom-файле игры.
Выложить Редактор в комплекте с игрой.
Возможно у народа появятся идеи по поводу новых уровней, поделятся своими версиями...
Это мои мысли вслух.
Желание ещё сотворить для Вектора есть, как только появиться возможность....
Интересная идея.
Игру сделал так чтобы не было совсем хардкордно, но и чтобы не было совсем просто - чтобы был некий баланс.
9-й уровень проходим....можно посмотреть видео-прохождение в первом посту.
metamorpho, думаю попробовать портануть на другой комп, как к этому относишься? Не факт, что действительно начну что-то делать, но вдруг начну, а автор против.
Орион-Про (с парой дополнительных плат) вроде должен потянуть. Еще из продвинутых неспектрумов должен бы потянуть Алесте, но там и проц помедленнее и я его хуже знаю.
- - - Добавлено - - -
Кстати, если говорить о забугорных компах или приставках на z80, то msx 2 подходит, а sega master system подходит просто идеально, но там тысячи своих любителей.
ivagor, на специалист ? )
О специалисте проще будет думать, если metamorpho сделает версию для спека.
Да есть идея портануть на Спектрум, поскольку на втором месте после Вектора у меня идёт Спектрум - это мой второй компьютер из детства, а ещё там ведь конкурс :)
Если конечно игра подходит под правила конкурса, то я ещё могу успеть (если конечно разберусь с особенностями Спектрума). Хотя сдаётся мне что туда нужно делать более эффектную игру чтобы иметь шанс на приз :)
- - - Добавлено - - -
ivagor, если решишь портировать, то могу дать исходник (если с ним будет легче это сделать)
Если посмотреть на yrgb 2019, то там binorium из призеров мог бы возможно посоревноваться с yazzie, но для этого имхо как минимум нужно очень удачно перерисовать/конверснуть графику с использованием мультиколора и написать крутые музоны для ay. Там все же ситуация намного более конкурентная, для вектора новую игрушку делают раз в несколько лет, а на спеке несколько в год.
- - - Добавлено - - -
Спасибо, но лучше не надо. Если я возьму исходник и ничего не сделаю, то получится неудобно.
Игра коротенькая. Все легко проходится :)
На Спектруме придётся повозиться с вертикальным скроллом (в отличие от Вектора, там нет аппаратной поддержки оного от слова "совсем") и с attribute clashing в вертикальном направлении - но, судя по видео, игры, использующие вертикальный скролл, эту проблему как-то решали.
Это уже - не в обиду автору - не говоря о том, что для Спектрума ещё в годы его величия был тот же Cybernoid, который по геймплею довольно похож на Binorium, за исключением протяжённых по вертикали уровней с плавной прокруткой.