214 lines
9.7 KiB
NASM
214 lines
9.7 KiB
NASM
; ═══════════════════════════════════════════════════════════════════════════
|
|
; Модуль UI - текстовый интерфейс плеера
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
; Использует WC API для рисования окна.
|
|
;
|
|
; Обязательный порядок при старте плагина:
|
|
; 1. CALL GEDPL ; восстановить дисплей/палитру WC (обязательно!)
|
|
; 2. CALL UI_INIT ; нарисовать окно (IX = PLWND)
|
|
; 3. CALL UI_DRAW_INFO ; заполнить содержимое
|
|
;
|
|
; Все оконные функции (PRWOW, RRESB, TXTPR) требуют IX = SOW (PLWND)
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
; ─── Структура окна SOW (Structure Of Window) ─────────────────────────────
|
|
; Должна лежать в #8000-#BFFF или #0000-#3FFF.
|
|
; +8 (DW) = 0 при первом вызове PRWOW, WC заполнит адресом буфера.
|
|
PLWND:
|
|
DB 0 ; +0: тип 0 = стандартное окно с рамкой
|
|
DB 0 ; +1: маска цвета курсора
|
|
DB WND_X ; +2: X позиция на экране
|
|
DB WND_Y ; +3: Y позиция на экране
|
|
DB WND_W ; +4: ширина окна
|
|
DB WND_H ; +5: высота окна
|
|
DB CLR_MAIN ; +6: цвет (paper+ink)
|
|
DB 0 ; +7: резерв (всегда 0!)
|
|
DW 0 ; +8,+9: буфер (0 = не выведено, WC заполнит)
|
|
DB 0 ; +10: разделитель 1 (0 = нет)
|
|
DB 0 ; +11: разделитель 2 (0 = нет)
|
|
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
; UI_INIT - Вывести окно плеера на экран
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
UI_INIT:
|
|
PUSH AF
|
|
PUSH BC
|
|
PUSH DE
|
|
PUSH HL
|
|
|
|
LD IX,PLWND ; IX = SOW (обязательно для PRWOW!)
|
|
CALL PRWOW ; нарисовать окно
|
|
|
|
POP HL
|
|
POP DE
|
|
POP BC
|
|
POP AF
|
|
RET
|
|
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
; UI_DRAW_INFO - Нарисовать информацию о файле в окне
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
UI_DRAW_INFO:
|
|
PUSH AF
|
|
PUSH BC
|
|
PUSH DE
|
|
PUSH HL
|
|
|
|
; Заголовок плеера
|
|
LD IX,PLWND ; IX = SOW
|
|
LD D,1 ; Y = 1 (внутри окна)
|
|
LD E,2 ; X = 2 (внутри окна)
|
|
LD HL,STR_TITLE
|
|
CALL TXTPR
|
|
|
|
; Строка подсказки клавиш
|
|
LD IX,PLWND
|
|
LD D,2
|
|
LD E,2
|
|
LD HL,STR_KEYS
|
|
CALL TXTPR
|
|
|
|
; Статус (Playing/Paused)
|
|
CALL UI_DRAW_STATUS
|
|
|
|
POP HL
|
|
POP DE
|
|
POP BC
|
|
POP AF
|
|
RET
|
|
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
; UI_DRAW_STATUS - Показать статус воспроизведения
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
UI_DRAW_STATUS:
|
|
PUSH AF
|
|
PUSH BC
|
|
PUSH DE
|
|
PUSH HL
|
|
|
|
LD A,(PAUSED)
|
|
OR A
|
|
JR NZ,UI_SHOW_PAUSED
|
|
LD HL,STR_PLAYING
|
|
JR UI_SHOW_STATUS
|
|
UI_SHOW_PAUSED:
|
|
LD HL,STR_PAUSED
|
|
UI_SHOW_STATUS:
|
|
LD IX,PLWND ; IX = SOW
|
|
LD D,4 ; Y = 4 (внутри окна)
|
|
LD E,2
|
|
CALL TXTPR
|
|
|
|
POP HL
|
|
POP DE
|
|
POP BC
|
|
POP AF
|
|
RET
|
|
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
; UI_UPDATE - Периодическое обновление (вызывается из главного цикла)
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
UI_UPDATE:
|
|
PUSH AF
|
|
PUSH BC
|
|
PUSH DE
|
|
PUSH HL
|
|
|
|
; --- Вычислить MM:SS из PLAY_SECONDS ---
|
|
LD HL,(PLAY_SECONDS)
|
|
LD B,0 ; B = minutes
|
|
UI_DIV60:
|
|
LD A,H
|
|
OR L
|
|
JR Z,UI_DIV_DONE ; HL=0 → B=min, HL=0=sec
|
|
LD DE,-60 ; 0xFFC4
|
|
ADD HL,DE ; HL -= 60; carry set ← HL_orig >= 60
|
|
JR NC,UI_DIV_UNDO ; нет carry → HL_orig < 60 → восстановить
|
|
INC B ; засчитать минуту
|
|
JR UI_DIV60
|
|
UI_DIV_UNDO:
|
|
LD DE,60
|
|
ADD HL,DE ; восстановить HL = остаток (секунды)
|
|
UI_DIV_DONE:
|
|
LD C,L ; C = секунды (0-59)
|
|
|
|
; --- Записать MM в TIME_BUF+6,7 ---
|
|
LD A,B
|
|
LD HL,TIME_BUF+6
|
|
CALL UI_BYTE2DEC
|
|
|
|
; --- Записать SS в TIME_BUF+9,10 ---
|
|
LD A,C
|
|
LD HL,TIME_BUF+9
|
|
CALL UI_BYTE2DEC
|
|
|
|
; --- Отобразить ---
|
|
LD IX,PLWND
|
|
LD D,6
|
|
LD E,2
|
|
LD HL,TIME_BUF
|
|
CALL TXTPR
|
|
|
|
POP HL
|
|
POP DE
|
|
POP BC
|
|
POP AF
|
|
RET
|
|
|
|
; UI_BYTE2DEC: конвертировать A (0-99) в 2 ASCII-цифры по адресу (HL)
|
|
; Меняет: A, F
|
|
UI_BYTE2DEC:
|
|
LD B,0
|
|
UI_B2D_L:
|
|
CP 10
|
|
JR C,UI_B2D_END
|
|
SUB 10
|
|
INC B
|
|
JR UI_B2D_L
|
|
UI_B2D_END:
|
|
; B=десятки, A=единицы
|
|
PUSH AF
|
|
LD A,B
|
|
ADD A,'0'
|
|
LD (HL),A
|
|
INC HL
|
|
POP AF
|
|
ADD A,'0'
|
|
LD (HL),A
|
|
RET
|
|
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
; UI_REMOVE - Закрыть окно плеера (восстановить экран)
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
UI_REMOVE:
|
|
PUSH AF
|
|
PUSH BC
|
|
PUSH DE
|
|
PUSH HL
|
|
|
|
LD IX,PLWND ; IX = SOW (обязательно для RRESB!)
|
|
CALL RRESB ; восстановить экран под окном
|
|
|
|
POP HL
|
|
POP DE
|
|
POP BC
|
|
POP AF
|
|
RET
|
|
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
; SHOW_ERROR / SHOW_WARNING - Заглушка (не реализовано)
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
SHOW_ERROR:
|
|
SHOW_WARNING:
|
|
RET
|
|
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
; Строки UI (завершаются нулём — формат WC TXTPR)
|
|
; ═══════════════════════════════════════════════════════════════════════════
|
|
STR_TITLE: DB "VGM Player v2.0 (OPL3)",0
|
|
STR_KEYS: DB "ESC-Exit SPC-Next P-Prev M-Pause",0
|
|
STR_PLAYING: DB "Playing... ",0
|
|
STR_PAUSED: DB "** PAUSED ** ",0
|
|
; TIME_BUF: динамический буфер для отображения времени (изменяется в UI_UPDATE)
|
|
TIME_BUF: DB "Time: 00:00",0
|