| Разработка и ромхакинг > Ромхакинг и программирование |
| SGDK |
| << < (23/40) > >> |
| m4x1k:
--- Цитата: Sharpnull от 19 Март 2019, 09:58:14 ---Начинал делать порт одной текстовой игры, сделал вывод текста со сглаживанием через копирование отдельных символов в тайлы. Главная проблема - медленно, полное заполнение экрана текста заметно (заполнял построчно), хотя можно отображать весь экран после заполнения VRAM, главное чтобы видеопамяти хватило. Задача несложная, но есть коварные моменты. Могу скинуть позже, только код не очень. --- Конец цитаты --- Со сглаживанием — это как? Я начал писать свой вывод, но с удовольствием посмотрю твой выход в данной ситуации. Я делаю через битовое смещение тайла, вроде со всем разобрался, осталось всю математику только написать. :neznayu: В планах хочу сделать функцию, которая будет выводить текст на экран с большим выбором плюшек. Очень удивился, когда узнал, что только в Pier Solar запарились с подобным. Ведь подобное не только экономит место для большего вывода символов на экране, но и экономит место в видеопамяти: не нужно хранить целый шрифт, только те данные, которые будут использованы. Хотел уточнить по поводу PLAN_WINDOW — какой смысл в нём вообще, если это тот же PLAN_A? У меня на окне почему-то не работает прозрачность — вместо прозрачности выводит цвет заднего фона PLAN_B. И вывод работает тоже как-то коряво. Карта 128х32 и PLAN_WINDOW при этом выводит на себя данные немного иначе, начинает затрагивать область за границей экрана, хотя код выводит только в пределах границ. С PLAN_A работает как надо. |
| Sharpnull:
--- Цитата: m4x1k от 19 Март 2019, 15:39:22 ---Со сглаживанием — это как? --- Конец цитаты --- Больше одного цвета (+фон). --- Цитата: m4x1k от 19 Март 2019, 15:39:22 ---Я делаю через битовое смещение тайла --- Конец цитаты --- Попиксельно копировать долго, поэтому тоже копирую сразу несколько пикселей, но возможно не очень эффективно. --- Цитата: m4x1k от 19 Март 2019, 15:39:22 ---Ведь подобное не только экономит место для большего вывода символов на экране, но и экономит место в видеопамяти: не нужно хранить целый шрифт, только те данные, которые будут использованы. --- Конец цитаты --- Если текста выводится много, то экономии нет. Усложняется код. --- Цитата: m4x1k от 19 Март 2019, 15:39:22 ---PLAN_WINDOW — какой смысл в нём вообще --- Конец цитаты --- Обычно интерфейс выводят. А прозрачности у Window кажется и не должно быть. |
| Sharpnull:
Мой вывод текста без лишнего кода. Шрифт генерировал в BMFont, скриптами раскидывал в ASCII ряд и сохранял в виде кода (myfont.c). Русский текст в text_win1251.bin (кодировка windows-1251). Шрифт не идеальный, тёмный оттенок серого плохо виден и расстояние между символами получается разным. Кернинга нет. |
| m4x1k:
Посмотрел. Почему ты думаешь, что медленно? К примеру, если выводить как в игрушках, на диалоговое окно, где 3 символа в высоту -- будет моментально. Код не маленький. :-\ Спасибо, постараюсь что-нибудь подчерпнуть. Добавлено позже: А как в SGDK сделать непрерывное выполнение одной функции из другой? Немного не понимаю самого процесса, возможно, я даже глупость спрашиваю, объясню подробнее. Есть функция, вызванная из main, в ней план, который в цикле скроллится от координаты 0 до 100. В этом же цикле проверяем равняется ли координата 50, если равна, то запускаем функцию вывода текста. Функция текста в свою очередь выводит символы с паузой в 20мс. И в момент вывода текста стопорится скроллинг плана, пока вся функция вывода текста не завершится, при этом музыка, к примеру, продолжит играть. Как можно хотя бы в теории организовать одновременное выполнение подобных функций? :neznayu: |
| Sharpnull:
m4x1k, если код не выполняется за один кадр, значит медленно. Смотрел Pier Solar, мне показалось, что там текст тоже не сразу выводится после нажатия кнопки, чтобы не смотреть анимацию вывода текста. --- Цитата: m4x1k от 19 Март 2019, 19:23:02 ---А как в SGDK сделать непрерывное выполнение одной функции из другой? --- Конец цитаты --- По-моему вы говорите об общей вещи, а не специфичного для SGDK. 1/60 - 16.(6) мс, если FPS не проседает ниже 60, то можно в каждом кадре складывать по 16 или 16.666 с фиксированной точкой и выводить символ, когда время пришло. Обычный счётчик. В SGDK есть таймеры и прошедшее время можно узнать. В современных движках ещё используют сопрограммы (coroutines). |
| m4x1k:
Возможно, не так описал. Вкратце: int main() { //Вызываю первую функцию. FUNKTION1(); } static void FUNKTION1() { while (1) { В функции задаю скроллинг экрана. VDP_setHorizontalScroll(PLAN_B, X--); //Если позиция -300, то выводим текст. if (X == -300) { for (int i = 0; i < 128; i++) { ОБРАБАТЫВАЕМ СИМВОЛ; ВЫВОДИМ СИМВОЛ; ТАЙМЕР 2МС; } } } } Вот такого плана действие. Смысл в том, что пока идёт красный цикл, то основной цикл в ступоре. Мне же нужно, чтобы всё работало равномерно. Похожее действие выполняет функция VDP_fadeIn -- она не ждёт своего завершения, а начинает фейдинг совместно с последующим действием в программе. Я просто не встречался до этого с такой проблемой, но мне кажется, что я совсем глупый вопрос задаю, возможно, он даже не решаем и я не могу делать так, как описано в примере. :neznayu: ------------------ Решил проблему передачей функции значения скроллинга. Если 0, не скроллим, если иное, то продолжаем скроллинг в новой функции. Но проблему это решает только со скроллингом. С анимацией заднего фона такие же проблемы будут. |
| Sharpnull:
m4x1k, я об этом и говорил. Например из sgdk\sample\sprite: --- Код: --- while (TRUE) { handleInput(); updatePhysic(); // Внутри updateCamera() -> VDP_setHorizontalScroll(PLAN_A, fix32ToInt(-camposx)); updateAnim(); SPR_update(); VDP_waitVSync(); } --- Конец кода --- Анимация фона делается например так: --- Код: ---static u8 counter = 0; // Может быть общим для нескольких анимаций void updateBGAnim(void) { counter++; // Каждый 4-й кадр будет выполняться // ... или дробный счётчик if (!(counter & 0x3)) { // Анимация фона } } ... while(TRUE) { handleInput(); updatePhysics(); updateBGAnim(); VDP_waitVSync(); } --- Конец кода --- Можно сделать и сложные системы событий. Вопрос, опять же, общий структурный, а не специфичный только для SGDK. VDP_fade() работает также: VDP_initFading() инициализирует начальные значения, а на каждой итерации (если не async) while (VDP_doFadingStep()); обработка для одного кадра, где смещается цвет (есть свой счётчик шагов), внутри вызывается VDP_waitVSync(), чтобы дождаться VBLANK, следующего кадра. Кстати, VDP_setHorizontalScroll()/VDP_setVerticalScroll() вроде стоит вызывать сразу после VDP_waitVSync(), может быть разрыв кадра. VDP_fade() тоже делает изменение CRAM (палитры) после VDP_waitVSync(). |
| m4x1k:
--- Цитата: Sharpnull от 20 Март 2019, 05:01:44 ---m4x1k, я об этом и говорил. Например из sgdk\sample\sprite: --- Код: --- while (TRUE) { handleInput(); updatePhysic(); // Внутри updateCamera() -> VDP_setHorizontalScroll(PLAN_A, fix32ToInt(-camposx)); updateAnim(); SPR_update(); VDP_waitVSync(); } --- Конец кода --- Анимация фона делается например так: --- Код: ---static u8 counter = 0; // Может быть общим для нескольких анимаций void updateBGAnim(void) { counter++; // Каждый 4-й кадр будет выполняться // ... или дробный счётчик if (!(counter & 0x3)) { // Анимация фона } } ... while(TRUE) { handleInput(); updatePhysics(); updateBGAnim(); VDP_waitVSync(); } --- Конец кода --- Можно сделать и сложные системы событий. Вопрос, опять же, общий структурный, а не специфичный только для SGDK. VDP_fade() работает также: VDP_initFading() инициализирует начальные значения, а на каждой итерации (если не async) while (VDP_doFadingStep()); обработка для одного кадра, где смещается цвет (есть свой счётчик шагов), внутри вызывается VDP_waitVSync(), чтобы дождаться VBLANK, следующего кадра. Кстати, VDP_setHorizontalScroll()/VDP_setVerticalScroll() вроде стоит вызывать сразу после VDP_waitVSync(), может быть разрыв кадра. VDP_fade() тоже делает изменение CRAM (палитры) после VDP_waitVSync(). --- Конец цитаты --- Вроде бы дошло, наконец. Для подобного нужно создать отдельные общие функции тех же скроллинга и анимации и уже из других подфункций по надобности вызывать их. Всё правильно понял? Сегодня буду скроллинг переписывать. Я там его по куче раз вызываю, действительно ведь нораздо легче общую функцию написать было... Спасибо огромное. :) Я зарегистрировался неделю назад на spritesminds, но там мне не подтвердили регистрацию. Либо забили, забыли, либо ещё что-то. :neznayu: Так бы там тоже людей можно было подоставать вопросами, а больше и мест-то нет в интернете... |
| SeregaZ:
так там мертвый сайт. активность есть, но совсем мало. так что много не потерял. |
| Sharpnull:
m4x1k, попытался зарегистрироваться на spritesmind, нажал один раз Submit убралась часть формы, где нужно ввести Mortal, позже попробовал нажать ещё пару раз на Submit: --- Цитата ---Information You have been permanently banned from this board. Please contact the Board Administrator for more information. A ban has been issued on your IP address. --- Конец цитаты --- Причём форум тоже нельзя читать. Теперь понятно, почему так мало людей делают игры для SMD. Стоит ли говорить, кем нужно быть, чтобы банить по IP-адресу. |
| MetalliC:
на зарубежных форумах это не такое уж и редкое явление т.к. спамботы всех задолбали, потому если поклацал пару раз куда не нужно - давай, до свидания. |
| Sharpnull:
MetalliC, я бы понял, если на какое-то короткое время. На emu-land тоже нельзя быстро искать игры, несколько секунд задержка. Здесь комбо: не догадались прикрутить ReCaptcha + нельзя просматривать форум после бана + бессрочный бан. Выходные узлы Tor у них конечно же забанены. IP-адрес у меня динамически выдаётся, но запороть ещё один адрес не хочу. |
| Werton:
Sharpnull, я тоже не мог там зарегаться, регистрация была отключена из-за спама на неопределенный срок, а все желающие отправлялись в ... почту админа. Написал ему раз - молчит, написал второй - молчит, недельку подождал, ну думаю дохлый номер. А помог сам Stephane, которого я попросил через github (прямо в описании бага - ничего серьезного, всего лишь не обновленный пример) написать админу SpritesMind по каким-нибудь "внутренним каналам", что он любезно и сделал, через пару дней зарегали. Вот такой вот квест :lol: |
| m4x1k:
Там админ со своими тараканами. Я читал, что он с соплями удалял сайт, потом возвращал. Sharpnull, у меня тоже что-то писал про бан, я подумал, что глюк какой-то. Но бана не было. На почту пришло сообщение, что нужна ручная активация от админа. А пока — на форум хочешь зайти, пишет то же самое. Писал по почте админу тоже — ноль внимания. Потом залез в тему: http://gendev.spritesmind.net/forum/viewtopic.php?f=1&t=2594 и понял, что у Админа тамошнего точно есть какая-то особая любовь к вновьприбывшим. Вкратце: «Я сделал, а вы не цените». И это он писал, что основным приоритетом форума является разработка новых игр. А вот Stef как раз наоборот — постоянно отписывается в темах и помогает людям. |
| Sharpnull:
Я сейчас забанил ещё один выходной узел Tor, он забанился сразу, возможно из-за почты на mail.ru (или там всё сломано в конец), нажал кнопку с одного раза, значит дело бы не в количестве нажатий Submit. В тексте вроде не было ничего написано про запрещённые почты и это жёстко в любом случае. Жаль Stef не перешёл на нормальный форум. Спасибо, Werton, m4x1k. Значит нет смысла там регистрироваться, тем более английский я плохо знаю. :) |
| m4x1k:
По ходу изучаю ещё вывод спрайтов. Подскажите, как обозначать коллизии бэкграунда для объекта? К примеру есть тайл-спрайт. Он двигается по плану и при встрече определённого тайла он туда не может пройти. Как это реализуется? Сам принцип понимаю, в массиве делаем для всей карты значения 0/1, где 0 идти нельзя, 1 можно. Но как вот само «заграждение» для движущего спрайта выставить? if (colission == 0) { //Спрайт упирается в стену. } Вот, как логику красного выражения можно записать? Не нашёл примеров, к сожалению.( На примере Соника просто выставлена граница экрана, он в неё упирается. А нужно, к примеру, произвольно карту коллизий (платформы, препятствия). |
| Segaman:
на линухе водятся компиляторы под моторолку на С и С++. что об этом думаете? :wow: можем ли мы переписать SGDK под С++? наверняка компиль код грамотней оптимизирует, чем тот что в SGDK. писал код со структурами внутри структур, так в ассемблере просматривал: компиль записывал в регистр адреса указатель на структуру, учитывая, что она всегда тамже (в том же регистре) и ничем не перезаписывается |
| MetalliC:
--- Цитата: Segaman от 26 Март 2019, 12:24:23 ---можем ли мы переписать SGDK под С++? --- Конец цитаты --- нахрена ? чтоб весило побольше ? к примеру, раньше exe-шник MAME весил 50-60 мегабайт, но сейчас, после того как большую часть кода переписали с C на C++ оно же весит под 400 мег. отсюда вопрос - а оно вам надо ? |
| Sharpnull:
--- Цитата: Segaman от 26 Март 2019, 12:24:23 ---можем ли мы переписать SGDK под С++? --- Конец цитаты --- На том форуме, где меня забанили, давно ещё спрашивали про C++, Stef отвечал, что оверхед большой. С++ медленнее чем C по определению, даже с отключением всяких фишек. --- Цитата: m4x1k от 20 Март 2019, 20:17:38 ---Но как вот само «заграждение» для движущего спрайта выставить? --- Конец цитаты --- Есть простой способ. Допустим уровень состоит из блоков 16x16, у нас есть массив с 0 и 1, каждый кадр или при перемещении персонажа преобразуем координаты углов коллайдера (прямоугольника который не должен вылезать из уровня) в массив, то есть просто делим на 16 и проверяем. Так делается в Battle City MD, файл collision.c, функция moveAvailableInWalls(). |
| worm:
--- Цитата: Segaman от 26 Март 2019, 12:24:23 ---можем ли мы переписать SGDK под С++? --- Конец цитаты --- Может тогда сразу под пайтон? А что - язык функциональный и простой как 3 копейки :lol: А если серьезно - плюсы по определению хуже чистого ЦЭ. Итоговый бинарник будет весить больше, выполняться медленнее, а сам код будет генериться максимально убогим образом. Си - это, грубо говоря, высокоуровневый ассемблер, а плюсы даже не системные. Да и вообще, где тот старый добрый сигаман, который любил чистый асм?)) |
| Навигация |
| Главная страница сообщений |
| Следующая страница |
| Предыдущая страница |