Перейти к содержимому

Поиск по сайту

Результаты поиска по тегам 'ocelot'.

  • Поиск по тегам

    Введите теги через запятую.
  • Поиск по автору

Тип публикаций


Блоги

  • Робот Байт
  • Fingercomp's Playground
  • 1Ridav' - блог
  • Totoro Cookies
  • Блог cyber01
  • IncluderWorld
  • KelLiN' - блог
  • Крутой блог
  • eutomatic blog
  • Programist135 Soft
  • Сайт в сети OpenNet
  • PieLand
  • Очумелые ручки
  • Блог недоблоггера
  • В мире Майнкрафт
  • LaineBlog
  • Квантовый блог
  • Блог qwertyMAN'а
  • some blog name
  • Дача Игоря
  • Путешествия Xytabich'а
  • Рецепты программирования
  • Шкодим по крупному
  • 123
  • mineOS и её удивительный мир
  • Поляна говнокода Bumer 32

Форумы

  • Программирование
    • Программы
    • База знаний
    • Разработчикам
    • Вопросы
  • Игровой раздел
    • Игровые серверы
    • Моды и плагины
    • Жалобы
    • Ивенты и конкурсы
    • Файлы
  • Общение
    • Задать вопрос
    • Обратная связь
    • Беседка
    • Шкатулка
  • Технический раздел
    • Корзина

Группы продуктов

Нет результатов для отображения.


Искать результаты в...

Искать результаты, которые...


Дата создания

  • Начать

    Конец


Последнее обновление

  • Начать

    Конец


Фильтр по количеству...

Зарегистрирован

  • Начать

    Конец


Группа


AIM


MSN


ICQ


Yahoo


Jabber


ВКонтакте


Город


Интересы

Найдено 4 результата

  1. Уже давно в майнкрафте существует задача: создать библиотеку или программу, которая могла бы отрисовать произвольную картинку. Это нужно в самых разных сценариях: чтобы написать веб-браузер (или, например, приложение-клиент соцсети), показать на здании свой логотип, или для журнального столика в отеле. ——— Что же мешает в OpenComputers просто считать данные картинки и её отрисовать? Разнообразие форматов и настроек. На многих сайтах можно одновременно найти PNG, WebP и JPEG; последние два формата подразумевают сжатие с возможными потерями и в этом отношении очень настраиваются. Соответственно, программе надо с десяток разных модулей/путей кода, чтобы декодировать что угодно — или придётся зависеть от какого-нибудь внешнего конвертера изображений. Разрешение мониторов OC не соответствует размерам стандартных картинок. У мониторов третьего уровня 160x50 знакомест (которые разбиваются на два квадратика в высоту) и всего 256 цветов в палитре. Декодирование целой картинки через виртуальную машину Lua подтормаживает (а без декодирования не получится её даже уменьшить), особенно когда приходится делать паузы для сборщика мусора. Постоянная замена цветов и отрисовка по одному пикселю тормозит уже за счёт ограничений видеокарты в моде. Пункту 4 можно противодействовать с помощью DoubleBuffering от @ECS, пункт 2 требует какого-то алгоритма уменьшения картинки (если же она слишком мала, то мы можем покрутить разрешение монитора). Что же касается первого и третьего... сразу напрашивается идея создать внешнюю библиотеку, которая всем этим бы занималась. На ум приходят несколько вариантов, на чём её можно написать и как интегрировать: Rust (как более безопасный и потенциально быстрый язык) скомпилировать в .dll/.so и подключить к OC, примерно как нативный вариант Lua; Того же подключить из machine.lua; На Scala (тот же язык, на котором написан OpenComputers) сделать патч к самому OpenComputers; ... Уже известно, что первый вариант вызывает мучения (https://computercraft.ru/blogs/entry/666-profiliruem-programmy-pod-oc/) и отсутствие персистентности у компьютеров. Пользователи, очевидно, будут очень рады тому, что программы надо писать из расчёта «всё будет выключаться в произвольные моменты». Поэтому сейчас рассмотрим, как пойти по третьему пути; для простоты компиляции возьмём испытуемым Ocelot Desktop, понимая, что он не очень сильно отличается от OpenComputers. Оказывается, у нас уже есть пример компонента, работающего с данными -- “data card”; основной файл этой карточки можно найти на https://gitlab.com/cc-ru/ocelot/ocelot-brain/-/blob/master/src/main/scala/totoro/ocelot/brain/entity/DataCard.scala. Пример ... object DataCard { val SecureRandomInstance: ThreadLocal[SecureRandom] = new ThreadLocal[SecureRandom]() { override def initialValue: SecureRandom = SecureRandom.getInstance("SHA1PRNG") } class Tier1 extends DataCard { ... override def tier: Tier = Tier.One @Callback(direct = true, limit = 32, doc = """function(data:string):string -- Applies base64 encoding to the data.""") def encode64(context: Context, args: Arguments): Array[AnyRef] = { result(Base64.encodeBase64(check(context, args))) } ... Сразу замечаем, что функции, экспортируемые для использования в Lua, собраны в одном классе и отмечены декоратором @Callback; кроме того, в структуре указываются ещё характеристики компонента (название, «поставщик», уровень и тому подобное). Программируем сами?.. Подумаем теперь над интерфейсом нашей карточки: decode(массив байт) —> обёртка над картинкой (таблица? объект Scala?) обёртка —> ширина, высота обёртка —> получить цвет конкретного пикселя. Раз у нас поддерживается любой формат изображений, то здесь будут четыре канала — R, G, B, A; возможно, методы для первичной обработки изображения? Например, масштабирование. В принципе, этого достаточно, чтобы начать программировать, но попробуем сделать по-другому: попросим нейросеть написать код за нас. В рассуждениях можно будет увидеть, как DeepSeek сомневается, добавлять ли собственно декодирование PNG и других форматов или сделать лишь какой-то сырой, и в итоге он останавливается на втором варианте: Не вполне понятно, в каком именно порядке отдаются цветовые каналы, но это похоже на правду... для какого-то сырого формата, где Lua хватило бы простого выбора байт из строки. Что ж, не будем сдаваться, запросим декодирование популярных форматов. К сожалению, там модель начинает путаться в порядке каналов и в точных импортах, но всё же выдаёт осмысленный код: package totoro.ocelot.brain.entity // Core image processing import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.nio.ImageSource import com.sksamuel.scrimage.metadata.ImageMetadata import com.sksamuel.scrimage.implicits._ // For Scala syntactic sugar :cite[2] // Format-specific readers (explicit safe imports) import com.sksamuel.scrimage.webp.WebpWriter import com.sksamuel.scrimage.formats.{GifWriter, JpegWriter, PngWriter} // Error handling import scala.util.{Try, Success, Failure} import totoro.ocelot.brain.entity.machine.{AbstractValue, Arguments, Callback, Context} class ImageDecoder extends /* ... existing entity setup ... */ { @Callback(direct = true, doc = """function(data:string):userdata -- Decodes common formats (PNG/WebP/JPEG/GIF) or raw RGBA""") def decode(context: Context, args: Arguments): Array[AnyRef] = { val data = args.checkByteArray(0) // 1. Attempt standard format decoding via Scrimage :cite[1]:cite[3] Try(ImmutableImage.loader().fromBytes(data)) match { case Success(scrimageImg) => // Convert Scrimage image to raw RGBA format for consistency val rgba = scrimageImg.bytes(PngWriter.NoCompression).take(8) ++ // Store metadata scrimageImg.argbFlatMap(p => Array( ((p >> 16) & 0xFF).toByte, // R ((p >> 8) & 0xFF).toByte, // G (p & 0xFF).toByte, // B ((p >> 24) & 0xFF).toByte // A )) result(new ImageUserdata(scrimageImg.width, scrimageImg.height, rgba)) case Failure(_) => // 2. Fallback to raw format if standard decoding fails if (data.length < 8) throw new IllegalArgumentException("Invalid header") val width = java.nio.ByteBuffer.wrap(data.slice(0, 4)).getInt val height = java.nio.ByteBuffer.wrap(data.slice(4, 8)).getInt if (8 + width*height*4 > data.length) throw new IllegalArgumentException("Invalid pixel data") result(new ImageUserdata(width, height, data.slice(8, data.length))) } } } Программируем сами, да Вооружимся компилятором (для Scala это sbt) и допишем код до нормального состояния. Дадим сначала карточке весёлое название и имя вендора: class ImageCard extends Entity with Environment with DeviceInfo with Tiered { override val node: Node = Network.newNode(this, Visibility.Neighbors) .withComponent("imagine", Visibility.Neighbors) .create() private final lazy val deviceInfo = Map( DeviceAttribute.Class -> DeviceClass.Processor, DeviceAttribute.Description -> "Image decoder card", DeviceAttribute.Vendor -> "ProgramCrafter Individual Enterprises", DeviceAttribute.Product -> "PCI-E Byte-to-Byte Visual-Only Decoder" ) override def getDeviceInfo: Map[String, String] = deviceInfo override def tier: Tier = Tier.Two ... И потом напишем её единственный метод. ... @Callback(direct = false, doc = """function(data:string):userdata -- Decodes an image in common format (PNG/WebP/JPEG/GIF)""") def decode(context: Context, args: Arguments): Array[AnyRef] = { val data = args.checkByteArray(0) val scrimageImg = ImmutableImage.loader().fromBytes(data) result(new ImageUserdata(scrimageImg)) } } class ImageUserdata(var pixels: ImmutableImage) extends AbstractValue { def this() = this(ImmutableImage.create(8, 8)) // For deserialization @Callback(direct = true, doc = "function():number -- Get image width") def getWidth(context: Context, args: Arguments): Array[AnyRef] = result(pixels.width) @Callback(direct = true, doc = "function():number -- Get image height") def getHeight(context: Context, args: Arguments): Array[AnyRef] = result(pixels.height) @Callback(direct = true, limit = 1000000, doc = "function(x:number, y:number):number -- Get ARGB value at specified coordinates, 1-based") def getARGB(context: Context, args: Arguments): Array[AnyRef] = { val x = args.checkInteger(0) - 1 val y = args.checkInteger(1) - 1 if (x < 0 || x >= pixels.width || y < 0 || y >= pixels.height) throw new IllegalArgumentException("coordinates out of bounds") val p = pixels.pixel(x, y) result(p.alpha(), p.red(), p.green(), p.blue()) } @Callback(direct = false, doc = "function(target_width:number, target_height:number):number -- Get a new image scaled appropriately to fit within specified bounds") def fit(context: Context, args: Arguments): Array[AnyRef] = {...} // Serialization private final val PixelTag = "ScrImage" override def load(nbt: NBTTagCompound, workspace: Workspace): Unit = { super.load(nbt, workspace) pixels = ImmutableImage.loader().fromBytes(nbt.getByteArray(PixelTag)) } override def save(nbt: NBTTagCompound): Unit = { super.save(nbt) nbt.setByteArray(PixelTag, pixels.bytes(PngWriter.MaxCompression)) } } Когда всё написанное скомпилируется, обёртка изображения будет поддерживать персистентность, масштабирование, получение размеров и конкретных пикселей картинки. Остаётся пока один нерешённый вопрос: а как этот код будет вызываться? Кормим Оцелота На самом деле добавить новую карточку не очень сложно, достаточно: нарисовать иконку 16x16, поместить в ocelot-desktop/sprites/items прогнать ocelot-desktop/spritepack и положить новый атлас текстур на место старого добавить новую иконку в Icons.scala (в объекте Items) добавить код ImageCard в репозиторий создать подкласс ImageCardItem with CardItem и соответствующую ему Factory зарегать завод в Items.scala Изменения можно посмотреть на https://gitlab.com/ProgramCrafter/ocelot-desktop/-/compare/develop...ac0acb33. Тестируем Окажется ужасно, если наша карточка не будет работать. Поставим её в компьютер и запустим вот такой скрипт: local com = require 'component' local unc = require 'unicode' local img = com.imagine local gpu = com.gpu local function set_halfpixel(x, y, back, fore) local bg, fg = gpu.getBackground(), gpu.getForeground() if bg == fore then gpu.setForeground(back) gpu.set(x, y, unc.char(0x2584)) else if bg ~= back then gpu.setBackground(back) end if fg ~= fore then gpu.setForeground(fore) end gpu.set(x, y, unc.char(0x2580)) end end local filename = (...) or '/home/775251537.0.jpg' local file = io.open(filename, 'rb') local buf = file:read('*a') file:close() local image = assert(img.decode(buf)) local w, h = gpu.getResolution() local image_fit = image.fit(w, (h - 1) * 2) local pts_w, pts_h = image_fit.getWidth(), image_fit.getHeight() io.read() for x = 1, pts_w do for y = 1, pts_h, 2 do local _, r1, g1, b1 = image_fit.getARGB(x, y) local _, r2, g2, b2 = 0,0,0,0 if y + 1 <= pts_h then _,r2,g2,b2 = image_fit.getARGB(x, y + 1) end local top = r1*65536 + g1*256 + b1 local bot = r2*65536 + g2*256 + b2 set_halfpixel(x, (y + 1) // 2, bot, top) end end require'term'.setCursor(1, h) И получим изображение дивана-танка. Требуемые улучшения Проверить, что за библиотека ScrImage, действительно ли она безопаснее или удобнее остальных. (Кажется, что удобнее, ведь она в отличие от javax ImageIO поддерживает WebP.) Сделать так, чтобы открытые картинки потребляли память, потому что сейчас ничто не мешает коду открыть сотню раз по мегабайту. Без этого на сервере такой патч запускать нельзя. Добавить, если не обойдётся вычислительно дорого, фильтры и повороты в интерфейс карточки.
  2. Для тех, кто спешит: Потестировать онлайн: https://ocelot.fomalhaut.me/ Скачать на комп и потестировать: Ocelot Desktop На форуме давно мелькают упоминания Ocelot. Это эмулятор OpenComputers, который находится в разработке примерно с 2015 года, был несколько раз переписан и наконец увидел свет в закрытом альфа-тесте зимой 2018. Я немного отвлекся на другие проекты (привет Stem), но теперь возвращаюсь к разработке Ocelot, и с гордостью предствляю вам тизер-анонс и, по совместительству, открытый альфа-тест Ocelot. Ещё один эмулятор? Да. Будем честны. Нормального эмулятора OpenComputers не существует. Те что есть - полны костылей, не совсем соответствуют реальному моду, сложны в установке, заброшены... и так далее. Ocelot - это решение всех этих проблем. Основная идея Ocelot - взять уже существующий код мода OpenComputers, тщательно отделить всё не нужное (Майнкрафт), затем осторожно переписать то что получилось с поправкой на реалии эмулятора. Благодаря этому, Ocelot эмулирует OpenComputers с ранее невиданной точностью. Вплоть до того, что в эмуляторе могут встречаться те же самые баги, что и в моде. Что он умеет? Практически всё. В перспективе. Ocelot позволяет воссоздать схему любой сложности из любого количества блоков - мониторов, компьютеров (любой конфигурации), проводов, модемов и прочих компонентов. Он позволяет управлять скоростью работы компьютеров, позволяет изменять "игровое" время, ставить его на паузу, сохранять состояние работы компьютеров и потом возобновлять работу с любого сохранения. Сейчас доступен базовый набор компонентов и блоков. Это кабель, корпус компьютера, APU/CPU, плашки памяти, видеокарты, дата-карты, EEPROM, дискеты, жесткие диски (managed и unmanaged режимов), интернет-карта, линкед-карта, сетевая карта (проводная и безпроводная), редстоун-карта / блок и монитор. Список будет расширяться. В перспективе будет эмуляция всех блоков и компонентов стандартного OC, роботов, дронов, микроконтроллеров, серверных стоек, плюс эмуляция адаптера и интеграции с ванильными блоками и блоками других модов. Что можно потрогать? Ocelot задуман как модульный проект. А именно: Ocelot Brain Основа эмулятора - это библиотека Ocelot Brain. Она написана на Scala и может быть подключена к любому другому проекта на Scala (и, может быть, Java). Ocelot Brain - это как раз переработанный код OpenComputers в компактной и удобной форме. Отвечает за всю эмуляцию кода и компонентов, а также сохранение / загрузку проектов. Вы можете использовать его для своих проектов, можете помочь с разработкой и патчами. Проект открыт и доступен по адресу: https://gitlab.com/cc-ru/ocelot/ocelot-brain На данный момент Ocelot Brain актуален версии OpenComputers 1.7.7. Ocelot Online На основе проекта Ocelot Brain, в качестве демонстрации его возможностей, создается проект Ocelot Online. Ocelot Online это эмулятор OpenComputers в виде сайта. Да. Всё что вам нужно для его запуска - это открыть сайт. Ссылка: https://ocelot.fomalhaut.me/ Исходный код тоже доступен: https://gitlab.com/cc-ru/ocelot/ocelot-online Поскольку проект пока находится в альфа-релизе, большая часть возможностей закрыта. Доступен только один монитор на всех, который позволяет взаимодействовать с уже настроенным демо-проектом. Конфигурация проекта: Креативный корпус, CPU T3, видеокарта T3, две планки памяти T3.5, managed жесткий диск T3, unmanaged жёсткий T3, интернет карта, редстоун карта T2, дисковод с дискетой Open OS, монитор T2, клавиатура и EEPROM с Advanced Loader от товарища Luca_S. Отличия от стандартного OpenComputers: * В OpenOS уже установлен HPM. Благодаря этому можно быстро ставить разные программы через hpm install. * Вставка текста заменена с Insert на Ctrl + V. Браузер не дает изменить этот хоткей. * В редакторе edit кнопка выхода заменена на Ctrl + E. Стандартная комбинация юзается браузером для закрытия вкладок - и переопределить её нельзя по соображениям безопасности. * Вместо OpenOS EEPROM используется Advanced Loader. Это сделано для удобства и наглядности. * Не работает лок на пользователя - по понятным причинам. Ocelot Online должен так же работать на смартфонах. Однако возможно придется отключить T9 - он портит эвенты клавиатуры. В разработке находится более сложная версия, где все получат возможность зарегистрировать аккаунт и создавать личные проекты любой конфигурации. Но это дело будущего. Ocelot Desktop Это классический вариант эмулятора Ocelot в виде программы, которую можно скачать и запустить на любой операционной системе, где есть Java. Построен на Ocelot Brain и библиотеке LWJGL (как и сам майнкрафт). Разработкой занимается товарищ @LeshaInc. Протестировать проект, сообщить о багах и поддержать разработчиков можно в топике Ocelot Desktop: Альфа-тест Итак, дорогие пользователи, пишите ваши хотелки, сообщайте о багах, обо всем что работает не так как должно, и как в оригинальном OC. Я, со своей стороны, постараюсь проект не забрасывать, развивать и своевременно (или не очень) обновлять. Благодарности Над проектом также работали: @LeshaInc, @Laine_prikol, @Fingercomp и @MeXaN1cK. За что им огромное спасибо и респект. Не забудем также всех, кто помогал с альфа-тестированием, Сангара - за чудесный мод, и мейнтейнеров OpenComputers за то что его не забросили. Enjoy!
  3. Пока у развивающегося Ocelot Brain ведётся работа над полноценной документацией, я решил что было бы неплохо, если бы демо Оцелота было бы доступно не только на Scala, но и на во многом совместимом со Scala языке программирования Java. Тогда бы возросла доступность Оцелота для тех разработчиков, которым уж совсем не даётся Scala, а попробовать Оцелот хочется. Поэтому я создал гист на ГитХабе, в котором приведён абсолютно тот же (по функционалу) код что и в оригинальном Demo.scala, но уже для Java 8: https://gist.github.com/Vladg24YT/dcbb1ed68658122f21e8edcf32f0db6d Лог PowerShell'а, доказывающий работоспособность демо, прилагается: https://pastebin.com/U6NCg97Y Содержимое Ocelot.log:
  4. Всем привет. Мы тут пишем эмулятор OpenComputers, и в процессе его нужно тестировать. Поэтому будет очень здорово, если кто-нибудь напишет утилиту-бенчмарк. Утилита должна выглядеть как программка для OpenOS, на Lua. В идеале её надо загрузить в Hel, чтобы было быстрее устанавливать. Для чего именно она нужна? Делать бенчмарк компьютера в Minecraft смысла особо нет - там и так понятно насколько будет производительной твоя "сборка". Но это имеет смысл делать в эмуляторе - потому что эмулятор может глючить, лагать, багать, и жрать оперативную память. (Например, сегодня мы запустили в Ocelot Online демку, которая очень быстро рендерила текст на экране, и в результате, у @Fingercomp браузер сожрал 5 гигабайт оперативной памяти, засвопился и вырубил на час весь компьютер.) Что именно она должна тестировать? Утечки оперативной памяти, производительность рендера и лаги эмулятора. Для этого можно например запустить интенсивный рендер на экране какого-нибудь цветастого мусора. Или любой другой вариант. Засечь время и потом сверить "внутриигровые" часы с настоящими, чтобы определить, не лагало ли оно. (Параллельно тесту можно будет уже вручную смотреть диспетчер задач - не жрет ли браузер или десктопный эмулятор ресурсы больше положенного.) Правильную работу компонентов. То есть проверить, соединяет ли интернет карта с интернетом, посылает ли сетевые сообщения модем, и так далее. Всю инфу надо потом красиво вывести на экран. Можно в графическом виде, можно в командной строке. Награда? Большое спасибо от всей души. Короче, если кто-то будет искать идею "что бы написать" - бенчмарк для эмулятора это вариант. Он нам пригодится.
×
×
  • Создать...