Разработка и ромхакинг > Ромхакинг и программирование
Sega MD VDP: Что оно такое и с чем его едят
(1/3) > >>
Segaman:
вот решил покапаться в сеговской вдп-шке и вот что пока нарыл.
в видео памяти есть 4 места, куда записываются значения для отображения
того или иного слоя на экране.
а это plan a, plan b, plan window и plan sprites
каждый из них записывается в массив $X000,
где X = чётное значение от 0 до E
например $4000.
я разобрал формат спрайтов в памяти.
для отображения одного спрайта требуется 8 байт значений

--- Код: ---пример спрайта:
    dc.w $00E4,$0F01,$2307,$0109
расшифровка:
0-1=y позиция
2   =размер спрайта+(неизвестно/возможно ((номер палитры)+4*отражение по гор.+8*отражение по верт.)*10)
3   =номер спрайта
4-5=номер тайла+$2000(неизвестно)
6-7=x позиция
значения размеров спрайтов:
               0 = 8*8
               1 = 8*16
               2 = 8*24
               3 = 8*32
               4 = 16*8
               5 = 16*16
               6 = 16*24
               7 = 16*32
               8 = 24*8
               9 = 24*16
               10= 24*24
               11= 24*32
               12= 32*8
               13= 32*16
               14= 32*24
               15= 32*32

--- Конец кода ---
сейчас пока изучаю дальше
уже знаю, что для того чтоб указать адрес и т.п. в вдп
нужно сложить флаги-биты.
раньше у меня был калькулятор такого значения, но сейчас
я его куда-то задевал. если у кого есть дайте плиз.
или доку по вдп-шке. пока
руководствуюсь инфой с соникретро.
если не найдётся калькулятор, напишу его сам.
сейчас занят написанием редактора значений из видео памяти
для отображения. чтоб например можно было создавать
какие нибудь заставки

Добавлено позже:
забыл рассказать про слои а и б
значения там такие:
$0819

0-1=отражение по гор.*8+отражение по верт.*4+номер тайла

размер слоя 64*64 по тайлам 8*8
итого 512*512 пикселей.
Smoke:

--- Цитата: Segaman ---4-5=номер тайла+$2000(неизвестно)
--- Конец цитаты ---
Номер тайла+номер палитры. Номера палитры _вроде_ бы:
0-$4000 -- 1-я
$5000-$8000 -- 2-я
$9000-$C000 -- 3-я
$C000-$F000 -- 4-я

У VDP есть регистры, установка их значений и указывает на адреса атрибутов спрайтов, планов и т.д. Инфа есть в тех обзоре SMD, который еще HardwareMan перевел. Вкратце принцип таков: вначале записываем в нужный регистр значение, потом непосредственно данные. Вот как я делал в МК2 для вывода спрайтов:

--- Код: ---                move.w   #$36, d0            ; КОЛ-ВО СПРАЙТОВ
                move.w   #$8F02, $C00004         ; ИНКРЕМЕНТ ЗАПИСИ В ВИДЕОПАМЯТЬ = 2БАЙТА
                move.l #$5C000003, $C00004 ; АДРЕС В VRAM: $BC00 (КУДА БУДЕМ ПИСАТЬ ДАННЫЕ)
spr_load2:      move.w   (a0)+, $C00000      ; ЗАПИСЫВАЕМ АТРИБУТЫ СПРАЙТА СЛОВАМИ
                move.w   (a0)+, $C00000
                move.w   (a0)+, $C00000
                move.w   (a0)+, $C00000
                dbf      d0, spr_load2
                move.w   #$856F, $C00004     ; НАСТРОЙКА VDP (R5=$6F) = 0x6F0 тайл в VDP (ОТКУДА БУДЕМ ЧИТАТЬ)
--- Конец кода ---
SPOT:
Игровая приставка Sega MegaDrive - может быть это чем-то поможет.
r57shell:
Блин, чё вы как дети. Есть же всё описанное, переводить не собираюсь, дока на инглише, встудию (прикрепил)...

А теперь переведём отрывок:

Оригинал:

--- Код: ---13.) Background Layers
 ----------------------------------------------------------------------------

 The VDP manages two background layers, called plane A and plane B.

 Name Tables
 -----------

 There are three tables stored in video RAM that define the layout for
 planes A, B, and W.

 Each table is a matrix of 16-bit words. Each word has the following format:

    pccvhnnnnnnnnnnn

    p = Priority flag
    c = Palette select
    v = Vertical flip
    h = Horizontal flip
    n = Pattern name
 
 The pattern name is the upper 11 bits of the physical address of pattern
 in video RAM. Bit zero of the name is ignored in interlace mode 2.

 The vertical and horizontal flip flags tell the VDP to draw the pattern
 flipped in either direction.

 The palette select allows the pattern to be shown in one of four
 16-color palettes.

 The priority flag is described later.

 The name tables for plane A and B share the same dimensions. The name
 table size cannot exceed 8192 bytes, so while a 64x64 or 128x32 name
 table is allowed, a size of 128x128 or 64x128 is invalid.

 The name table for plane W is 32x32 in 32-cell mode, and 64x32 in 40-cell
 mode. This size is fixed and is entirely dependant on the display width.

 Window
 ------

 The window plane operates differently from plane A or B. It can be thought
 of a 'replacement' for plane A which is used under certain conditions.
 That said, plane A cannot be displayed in any area where plane W is
 located, it is impossible for them to overlap.

 Registers 17 and 18 define an area which the window is restricted to.

 In terms of priority and intensity calculation for shadow / hilight mode,
 plane W is treated _exactly_ the same as plane A.

 Horizontal Scrolling
 --------------------

 The horizontal scroll table holds the scroll value for every line of
 both planes A and B, that can be positioned anywhere within video RAM.

 Each entry of the scroll table is a 16-bit word. It has the following
 format:

 ------xxxxxxxxxx

 x = Horizontal scroll value (0-3FFh)

 Bits D15 through D10 are ignored by the VDP.

 The lower three bits of the scroll value provide a pixel offset into each
 column comprised of one pattern. The upper seven bits provide an offset
 into each column of the name table (0-127).

 When the scroll value is larger than the width of the playfield, the
 display wraps horizontally.

 Scroll values for planes A and B are stored in an interleaved fashion.
 Entry #0 of the table is for plane A, entry #1 is for plane B, and this
 repeats for the entire length of the table.

 The manual says the scroll table is 960 bytes in size,
 and this seems like an accurate figure, considering the scroll table
 address bits suggest the table can be 1024 bytes.

 However, I do not know what happens in double-resolution interlace
 mode. To provide a scroll entry for both planes on every line, a total
 of 1920 bytes would be needed. (480 lines x 2 planes x 2 bytes per line)

 Here is some "C" pseudocode to illustrate how the VDP reads the scroll
 table depnding on the settings of bits 0 and 1 of register #11:

 void get_scroll(int line, int *scroll_a, int *scroll_b)
 {
    switch(vdp_reg[11] & 3)
    {
        case 0x00: /* Full screen */
            *scroll_a = *(word *)vram[hscb + 0];
            *scroll_b = *(word *)vram[hscb + 2];
            break;

        case 0x01: /* First eight lines */
            *scroll_a = *(word *)vram[hscb + ((line & 7) * 2) + 0];
            *scroll_b = *(word *)vram[hscb + ((line & 7) * 2) + 2];
            break;

        case 0x02: /* Every row */
            *scroll_a = *(word *)vram[hscb + ((line & ~7) * 2) + 0];
            *scroll_b = *(word *)vram[hscb + ((line & ~7) * 2) + 2];
            break;

        case 0x03: /* Every line */
            *scroll_a = *(word *)vram[hscb + (line * 2) + 0];
            *scroll_b = *(word *)vram[hscb + (line * 2) + 2];
            break;
    }
 }

 A scroll mode setting of 01b is not valid; however the unlicensed version
 of Populous uses it. This mode is identical to per-line scrolling, however
 the VDP will only read the first sixteen entries in the scroll table for
 every line of the display.

 ----------------------------------------------------------------------------
 14.) Priority
 ----------------------------------------------------------------------------

 The VDP manages a fairly complex system of priorities between the two
 background layers and sprites. The basic ordering is:


 (back)                                         (front)
        A  >  B  >  C  >  D  >  E' >  F' >  G'

 ' = Denotes high priority
 A = Backdrop color
 B = Low priority plane B
 C = Low priority plane A
 D = Low priority sprites
 E = High priority plane B
 F = High priority plane A
 G = High priority sprites

 The sprite priority bit does not affect inter-sprite priority, only the
 relation between background data. Low priority sprites *can* overlap high
 priority sprites. Games that do this to mask other sprites include
 Castlevania Bloodlines, Raiden Trad, and Alien Soldier.

 ----------------------------------------------------------------------------
 15.) Sprites
 ----------------------------------------------------------------------------

 The Genesis can display a total of eighty 32x32 15-color sprites.
 There are of course various restrictions on the display capacity, based
 on current configuration of the VDP.

 Sprite Attribute Table
 ----------------------

 All sprite data is stored in a region of VRAM called sprite attribute table.
 The table is 640 bytes in size. Each 8-byte entry has the following format:

 Index + 0  :   ------yy yyyyyyyy
 Index + 2  :   ----hhvv
 Index + 3  :   -lllllll
 Index + 4  :   pccvhnnn nnnnnnnn
 Index + 6  :   ------xx xxxxxxxx

 y = Vertical coordinate of sprite
 h = Horizontal size in cells (00b=1 cell, 11b=4 cells)
 v = Vertical size in cells (00b=1 cell, 11b=4 cells)
 l = Link field
 p = Priority
 c = Color palette
 v = Vertical flip
 h = Horizontal flip
 n = Sprite pattern start index
 x = Horizontal coordinate of sprite

--- Конец кода ---

Вольный перевод от меня... о, на сайт выложу потом.

--- Код: ---13.) Фоновые (задние) Слои
 ----------------------------------------------------------------------------

 VDP управляет двумя фоновыми слоями, называющимися плоскость A (plane A) и плоскость B (plane B).

 Name Tables
 -----------

 Существует три таблицы, тусующиеся в видео памяти (VRAM) которые определяют схему отображения
 плоскостей A, B, и W (Window - окно).

 Каждая таблица это матрица из 16-битовых слов (word-ов). Каждое слово имеет следуйщий формат:

    pccvhnnnnnnnnnnn

    p = Priority flag (Флаг приоритета)
    c = Palette select (Номер палитры)
    v = Vertical flip (Вертикальный ... нету русского слова, короче отобразить ли вертикально зеркалом... (mirror) )
    h = Horizontal flip (Горизонтальный флип)
    n = Pattern name (Имя шаблона)

 Имя шаблона это 11 старших битов (upper 11 bits) физического адреса шаблона
 в видео памяти (VRAM). Нулевой бит имени шаблона игнорируется в interlace(черезстрочность) режиме 2.

 Вертикальный и горизонтальный флип флаги говорят VDP нарисовать шаблон флипнуто в соответственных направлениях.

 Выбор палитры допускает показ шаблона в одной из четырёх 16-цветовых палитр.

 Флаг приоритета будет описан пожже.

 Таблицы плоскостей A, B имеют одну размерность. Таблицы плоскостей
 не могут превосходить размер 8192 байта, поэтому разрешены таблицы
 размерами 64x64 или 128x32, а размеры 128x128 или 64x128 запрещены.

 Таблица плоскости W имеет размер 32x32 в 32-клеточном режиме, и 64x32 в 40-клеточном режиме
 Этот размер фиксирован, и полностью зависит от размера дисплея.

 Окно
 ------

 Плоскость окна работает по-другому, в отличии от плоскостей A или B. Её можно представлять
 как "замену" для плоскости A, которая используется в некоторых условиях.
 Плоскость A не может быть показана в любой месте где плоскость W находится,
 они никогда не перекрывают друг друга.

 Регистры 17 и 18 определяют область где окно запрещено.

 In terms of priority and intensity calculation for shadow / hilight mode,
 plane W is treated _exactly_ the same as plane A.

 Горизонтальный скролл (прокрутка)
 --------------------

 The horizontal scroll table holds the scroll value for every line of
 both planes A and B, that can be positioned anywhere within video RAM.

 Each entry of the scroll table is a 16-bit word. It has the following
 format:

 ------xxxxxxxxxx

 x = Horizontal scroll value (0-3FFh)

 Bits D15 through D10 are ignored by the VDP.

 The lower three bits of the scroll value provide a pixel offset into each
 column comprised of one pattern. The upper seven bits provide an offset
 into each column of the name table (0-127).

 When the scroll value is larger than the width of the playfield, the
 display wraps horizontally.

 Scroll values for planes A and B are stored in an interleaved fashion.
 Entry #0 of the table is for plane A, entry #1 is for plane B, and this
 repeats for the entire length of the table.

 The manual says the scroll table is 960 bytes in size,
 and this seems like an accurate figure, considering the scroll table
 address bits suggest the table can be 1024 bytes.

 However, I do not know what happens in double-resolution interlace
 mode. To provide a scroll entry for both planes on every line, a total
 of 1920 bytes would be needed. (480 lines x 2 planes x 2 bytes per line)

 Here is some "C" pseudocode to illustrate how the VDP reads the scroll
 table depnding on the settings of bits 0 and 1 of register #11:

 void get_scroll(int line, int *scroll_a, int *scroll_b)
 {
    switch(vdp_reg[11] & 3)
    {
        case 0x00: /* Full screen */
            *scroll_a = *(word *)vram[hscb + 0];
            *scroll_b = *(word *)vram[hscb + 2];
            break;

        case 0x01: /* First eight lines */
            *scroll_a = *(word *)vram[hscb + ((line & 7) * 2) + 0];
            *scroll_b = *(word *)vram[hscb + ((line & 7) * 2) + 2];
            break;

        case 0x02: /* Every row */
            *scroll_a = *(word *)vram[hscb + ((line & ~7) * 2) + 0];
            *scroll_b = *(word *)vram[hscb + ((line & ~7) * 2) + 2];
            break;

        case 0x03: /* Every line */
            *scroll_a = *(word *)vram[hscb + (line * 2) + 0];
            *scroll_b = *(word *)vram[hscb + (line * 2) + 2];
            break;
    }
 }

 A scroll mode setting of 01b is not valid; however the unlicensed version
 of Populous uses it. This mode is identical to per-line scrolling, however
 the VDP will only read the first sixteen entries in the scroll table for
 every line of the display.

 ----------------------------------------------------------------------------
 14.) Приоритет
 ----------------------------------------------------------------------------

 VDP управляет сложной системой приоритетов между двумя фоновыми слоями
 и спрайтами. Основной порядок:


 (back)                                         (front)
        A  >  B  >  C  >  D  >  E' >  F' >  G'

 ' = Означает высокий приоритет
 A = Цвет заднего фона
 B = Низкого приоритета плоскость B
 C = Низкого приоритета плоскость A
 D = Низкого приоритета спрайты
 E = Высокого приоритета плоскость B
 F = Высокого приоритета плоскость A
 G = Высокого приоритета спрайты

 Бит приоритета в спрайте, не влияет на приоритеты между спрайтами, только
 на позицию между слоями. Спрайт низкого приоритета *может* перекрыть
 спрайт высокого приоритета. Игры делают это, чтобы скрыть другие спрайты:
 Castlevania Bloodlines, Raiden Trad, и Alien Soldier.

 ----------------------------------------------------------------------------
 15.) Спрайты
 ----------------------------------------------------------------------------

 Genesis может показать всего восемьдесят 32x32 15-цветных спрайтов.
 Они конечно имеют разные ограничения, основанные на текущей
 конфигурации VDP.

 Таблица атрибутов спрайтов
 ----------------------

 Все данные о спрайтах записаны в VRAM в месте, называемом "таблица атрибутов спрайтов"
 Эта таблица размером 640 байтов. Каждая 8-байтовая запись имеет следующий формат:

 Index + 0  :   ------yy yyyyyyyy
 Index + 2  :   ----hhvv
 Index + 3  :   -lllllll
 Index + 4  :   pccvhnnn nnnnnnnn
 Index + 6  :   ------xx xxxxxxxx

 y = Вертикальная координата спрайта (сверху вниз)
 h = Горизонтальный размер в клетках (cell) (в тайлах) (00b=1 cell, 11b=4 cells)
 v = Вертикальный размер в клетках (00b=1 cell, 11b=4 cells)
 l = Поле линковки (соединения... привязки, как хотите так и называйте).
 p = Приоритет
 c = Цветовая палитра
 v = Вертикальный флип
 h = Горизонтальный флип
 n = Индекс начала спрайтового шаблона
 x = Горизонтальная координата шаблона

--- Конец кода ---
Не всё перевёл... если чо, поможет гугл.
Rumata:
"flip" часто переводят как "зеркальный переворот"
Segaman:

--- Цитата: SPOT от 13 Ноябрь 2010, 19:54:10 ---Игровая приставка Sega MegaDrive - может быть это чем-то поможет.

--- Конец цитаты ---
Спасибо огромное. Офигительная дока.
Segaman:
Народ, научите пож. юзать скроллинг слоёв. Нужусь уже 8 дней, а кроме вертикального смещения обоих слоёв нифига не выходит. Пробовал из соника 1 скопипастить, так там ваще хер пойми как всё работает. Знаю ток, что есь такая VSRAM, там и храниться вся инфа по скролингу слоёв. Выручайте, буду крайне благодарен. Прост игруху начал писать. Пока ток сорс умный собираю.
vladikcomper:
В VSRAM хранится только память вертикальной прокрутки. Память горизонтальной прокрутки как и многое другое хранится в VRAM, ее начало настраивается через регистр $0D, туда записывается байт, который представляет собой адрес VRAM, деленный на $400. Формат прокрутки, если правильно помню: одно слово на План А и одно слово на План Б.

В Соник 1, ктсати, используется буфер горизонтальной прокрутки (в RAM), он копируется в видеопамять при вертикальном прерывании.
Segaman:

--- Цитата: SPOT от 13 Ноябрь 2010, 19:54:10 ---Игровая приставка Sega MegaDrive

--- Конец цитаты ---
в этой доке на 2й странице написано
--- Цитата ---Большое количество внутренних
регистров микросхемы музыкального
синтезатора не позволяет
рассмотреть их в рамках данной
книги.
--- Конец цитаты ---
А где тогда эти регистры можно рассмотреть?






Segaman:
Кто нить знает, как юзать увеличение слоёв, как в играх Gunstar Heroes (Sega Screen), Bram Stoker's Dracula (Book Screen) и Puggsy (Credits).
Ещё интересно, как проверяется наличие контроллера в консоли (Contra Hard Corps, Gunstar Heroes) и как проверяется язык и регион (те же 2 игры)
Teffycom:
Проверка региона в сонике есть
vladikcomper:

--- Цитата: Segaman от 28 Апрель 2011, 11:34:36 ---Кто нить знает, как юзать увеличение слоёв, как в играх Gunstar Heroes (Sega Screen), Bram Stoker's Dracula (Book Screen) и Puggsy (Credits).

--- Конец цитаты ---
Сега не подерживает это аппаратно, этого можно добиться только программным рендерингом.

Растяжение по вертикали обычно делают с помощью одного трюка. Игра вызывает горизонтальное прерывание на каждой строке, и до того, как видеопроцессор начнет рисовать следующую строку на экране, изменяет значение вертикального скролинга для слоя. После этого на следующей строке отобразится уже другая часть слоя. Этим трюком можно дублировать или пропускать отображаемые на экране строчки слоя, и добиваться растяжения, сужения - любой деформации.

С растяжением по горизонтали все сложнее, потому что подобные трюки реализовать невозможно. Придется либо рисовать пиксели вручную, либо грузить уже заведомо растянутые версии картинки (это занимает много места в РОМе, но порой по-другому никак, так как рисование программно "на лету" может серьезно тормозить).

Я, кстати, уже занимался подобным. Работал над своим алгоритмом для растяжения изображений по горизонтали. Написать это дело реально, но сложно, и еще потом долго голову ломать, как оптимизировать, чтобы работало на таком медленном процессоре. Способ свой, код из других игр не изучал, так как люблю все делать сам и почти не умею нормально дизасемблить :) Алгоритм перерабатывал много раз, оптимизировал до предела. В итоге где-то 15 FPS (на глаз) при резайсинге картинки 40x9 тайлов, с первой версией алгоритма было 0,1 FPS. Намучавшись с оптимизацией, я его забросил, но недавно захотел взяться за это дело, т.к. появились идеи.
Segaman:
и правда. щас проглядел видео память
там тупо все кадры разобраны и всё
жаль канешно...

Добавлено позже:
А вообще раз увеличение по вертикали поддерживается аппаратно, то можно написать скрипт, который будет увеличивать графически по горизонтали. Так ещё и быстрее и качественнее.
Rumata:

--- Цитата: Segaman от 28 Апрель 2011, 11:34:36 ---как проверяется язык и регион
--- Конец цитаты ---
Чтение из $A10000:
D7: 0 - Domestic / 1 - Oversea
D6: 0 - NTSC / 1 - PAL
Segaman:
Вообще, если можно отрисовывать попиксельно, то теоретически можно на экране вывести весь доступный диапозон цветов, даже без использования тайлов, чисто за сщёт смены цвета заднего фона. Но это довольно проблематично в плане мощности процессора. Времени обрабатывать что-то, кроме отрисовки просто не будет. Хотя это может не хило подойти для показа видео заставок.
vladikcomper:

--- Цитата: Segaman от 29 Апрель 2011, 17:08:34 ---и правда. щас проглядел видео память
там тупо все кадры разобраны и всё
жаль канешно...
--- Конец цитаты ---
Но как вариант, они могли все эти кадры зарендерить заранее. Можно просто загружать готовые кадры, а можно еще будет и прорисовать их перед отображением.


--- Цитата: Segaman от 29 Апрель 2011, 17:08:34 ---А вообще раз увеличение по вертикали поддерживается аппаратно, то можно написать скрипт, который будет увеличивать графически по горизонтали. Так ещё и быстрее и качественнее.

--- Конец цитаты ---
Какой скрипт ты имеешь в виду? И по сравнению с чем будет быстрее?


--- Цитата: Segaman от 30 Апрель 2011, 08:22:32 ---Вообще, если можно отрисовывать попиксельно, то теоретически можно на экране вывести весь доступный диапозон цветов, даже без использования тайлов, чисто за сщёт смены цвета заднего фона. Но это довольно проблематично в плане мощности процессора. Времени обрабатывать что-то, кроме отрисовки просто не будет. Хотя это может не хило подойти для показа видео заставок.

--- Конец цитаты ---
Мне кажется, ты не совсем верно понял про попиксельную отрисовку.
Если было можно задавать цвет каждому пикселю, действительно можно было вывести всю палитру без проблем. Но цвета индексированы, и пиксели рисуются в тайлах.
Единственный способ добиться отображения всей палитры - изменять цвета в CRAM на определеных строках. Пример есть в Соник 1, там менялась палитра для создания воды в Labyrinth Zone.
Ti_:

--- Цитата ---Color resolution : 12bits, but only internally. 1536 colors of possible 4096 are usable. Under normal conditions, only 512 are ready for use. There are 4x 15 color palettes for sprites and background layers which allows for 61 colors on screen at any given time when no tricks or shadow/highlight mode are used.
--- Конец цитаты ---
а вот кто знает что это за мифические 1536 цветов?
Segaman:
Нифига не 12бит. Тока 9бит отвечают за цвет. А это 512 цветов, блин. А эти 1536 цветов не знаю откуда взяты.

vladikcomper, а я не так сказал штоли? Без тайлов чисто цветом заднего фона отрисовывать каждый пиксель за сщёт смены цвета в нужной точке. Все же предыдущие уже закрашены предыдущим цветом заднего фона. Так и можно выжать (теоретически) все 512 цветов.
Немного не пойму как узнать, что пиксель (или строка) был отрисован? Там есть штото вроде interrupt'а на такой случай? Или как?
r57shell:
Segaman, HBLANK, VBLANK почитай про них...
на счёт 1536 = 512*3 -  мне кажется это намёк на то, что все 512 цветов можно показывать засветлёнными, и затемнёнными. Однако эти 12 бит никак не влияют всё же (вроде как, инфы покрайней мере такой я не знаю), только 9 из них цвет задают. Засветлённые, и затемнённые не вних (вроде) указываются.
vladikcomper:

--- Цитата: Segaman от 30 Апрель 2011, 12:53:49 ---vladikcomper, а я не так сказал штоли? Без тайлов чисто цветом заднего фона отрисовывать каждый пиксель за сщёт смены цвета в нужной точке.

--- Конец цитаты ---
Нельзя. Нет попиксельных прерываний. Возможны только построчные прерывания (Horizontal Interrupts). Ты можешь изменить палитру и параметры отбражения только для целой следующей строки на экране, но никак не для пикселя.
Навигация
Главная страница сообщений
Следующая страница

Перейти к полной версии