diff --git a/createLiveImage.sh b/createLiveImage.sh index 963e05c..8786390 100755 --- a/createLiveImage.sh +++ b/createLiveImage.sh @@ -5,6 +5,11 @@ then echo "Please run as root" exit fi +if [ ! -d rootfs\ overrides/chibrax/node_modules ] +then + echo "please run npmi.sh" + exit 1 +fi CHIBRAX_MOUNT_POINT="/tmp/chibraxMountPoint" diff --git a/kernel/.config b/kernel/.config index be07f71..ef2edd7 100644 --- a/kernel/.config +++ b/kernel/.config @@ -871,6 +871,7 @@ CONFIG_ARCH_HAS_PKEYS=y # CONFIG_PERCPU_STATS is not set # CONFIG_GUP_TEST is not set CONFIG_ARCH_HAS_PTE_SPECIAL=y +CONFIG_MAPPING_DIRTY_HELPERS=y CONFIG_SECRETMEM=y # @@ -2443,7 +2444,7 @@ CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y CONFIG_VT_CONSOLE_SLEEP=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set CONFIG_LDISC_AUTOLOAD=y @@ -3046,19 +3047,22 @@ CONFIG_AGP_INTEL=y CONFIG_INTEL_GTT=y CONFIG_VGA_ARB=y CONFIG_VGA_ARB_MAX_GPUS=16 -# CONFIG_VGA_SWITCHEROO is not set +CONFIG_VGA_SWITCHEROO=y CONFIG_DRM=y CONFIG_DRM_MIPI_DSI=y # CONFIG_DRM_DP_AUX_CHARDEV is not set # CONFIG_DRM_DEBUG_MM is not set # CONFIG_DRM_DEBUG_SELFTEST is not set CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_FBDEV_OVERALLOC=300 # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set # CONFIG_DRM_DP_CEC is not set CONFIG_DRM_TTM=y -CONFIG_DRM_VRAM_HELPER=m -CONFIG_DRM_TTM_HELPER=m +CONFIG_DRM_VRAM_HELPER=y +CONFIG_DRM_TTM_HELPER=y CONFIG_DRM_GEM_SHMEM_HELPER=y +CONFIG_DRM_SCHED=y # # I2C encoder or helper chips @@ -3074,9 +3078,36 @@ CONFIG_DRM_GEM_SHMEM_HELPER=y # # end of ARM devices -# CONFIG_DRM_RADEON is not set -# CONFIG_DRM_AMDGPU is not set -# CONFIG_DRM_NOUVEAU is not set +CONFIG_DRM_RADEON=y +# CONFIG_DRM_RADEON_USERPTR is not set +CONFIG_DRM_AMDGPU=y +# CONFIG_DRM_AMDGPU_SI is not set +# CONFIG_DRM_AMDGPU_CIK is not set +# CONFIG_DRM_AMDGPU_USERPTR is not set + +# +# ACP (Audio CoProcessor) Configuration +# +# CONFIG_DRM_AMD_ACP is not set +# end of ACP (Audio CoProcessor) Configuration + +# +# Display Engine Configuration +# +CONFIG_DRM_AMD_DC=y +CONFIG_DRM_AMD_DC_DCN=y +# CONFIG_DRM_AMD_DC_HDCP is not set +# CONFIG_DRM_AMD_SECURE_DISPLAY is not set +# end of Display Engine Configuration + +# CONFIG_HSA_AMD is not set +CONFIG_DRM_NOUVEAU=y +CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT=y +CONFIG_NOUVEAU_DEBUG=5 +CONFIG_NOUVEAU_DEBUG_DEFAULT=3 +# CONFIG_NOUVEAU_DEBUG_MMU is not set +# CONFIG_NOUVEAU_DEBUG_PUSH is not set +CONFIG_DRM_NOUVEAU_BACKLIGHT=y CONFIG_DRM_I915=y CONFIG_DRM_I915_FORCE_PROBE="" CONFIG_DRM_I915_CAPTURE_ERROR=y @@ -3093,13 +3124,15 @@ CONFIG_DRM_I915_STOP_TIMEOUT=100 CONFIG_DRM_I915_TIMESLICE_DURATION=1 # CONFIG_DRM_VGEM is not set # CONFIG_DRM_VKMS is not set -# CONFIG_DRM_VMWGFX is not set +CONFIG_DRM_VMWGFX=y +# CONFIG_DRM_VMWGFX_FBCON is not set +# CONFIG_DRM_VMWGFX_MKSSTATS is not set # CONFIG_DRM_GMA500 is not set # CONFIG_DRM_UDL is not set # CONFIG_DRM_AST is not set # CONFIG_DRM_MGAG200 is not set -CONFIG_DRM_QXL=m -CONFIG_DRM_VIRTIO_GPU=m +CONFIG_DRM_QXL=y +CONFIG_DRM_VIRTIO_GPU=y CONFIG_DRM_PANEL=y # @@ -3121,20 +3154,96 @@ CONFIG_DRM_PANEL_BRIDGE=y # CONFIG_DRM_BOCHS is not set # CONFIG_DRM_CIRRUS_QEMU is not set # CONFIG_DRM_GM12U320 is not set -CONFIG_DRM_SIMPLEDRM=m +CONFIG_DRM_SIMPLEDRM=y CONFIG_DRM_XEN=y -CONFIG_DRM_XEN_FRONTEND=m -CONFIG_DRM_VBOXVIDEO=m +CONFIG_DRM_XEN_FRONTEND=y +CONFIG_DRM_VBOXVIDEO=y # CONFIG_DRM_GUD is not set # CONFIG_DRM_HYPERV is not set -# CONFIG_DRM_LEGACY is not set +CONFIG_DRM_LEGACY=y +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_R128 is not set +# CONFIG_DRM_I810 is not set +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y # # Frame buffer Devices # CONFIG_FB_CMDLINE=y -# CONFIG_FB is not set +CONFIG_FB_NOTIFY=y +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_DDC=y +CONFIG_FB_BOOT_VESA_SUPPORT=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +CONFIG_FB_FOREIGN_ENDIAN=y +CONFIG_FB_BOTH_ENDIAN=y +# CONFIG_FB_BIG_ENDIAN is not set +# CONFIG_FB_LITTLE_ENDIAN is not set +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_VGA16=y +CONFIG_FB_UVESA=y +CONFIG_FB_VESA=y +# CONFIG_FB_EFI is not set +# CONFIG_FB_N411 is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_NVIDIA=y +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_XEN_FBDEV_FRONTEND=y +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +CONFIG_FB_HYPERV=m +# CONFIG_FB_SM712 is not set # end of Frame buffer Devices # @@ -3153,6 +3262,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_ARCXCNN is not set # end of Backlight & LCD device support +CONFIG_VGASTATE=y CONFIG_VIDEOMODE_HELPERS=y CONFIG_HDMI=y @@ -3163,7 +3273,16 @@ CONFIG_VGA_CONSOLE=y CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=80 CONFIG_DUMMY_CONSOLE_ROWS=25 +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set # end of Console display driver support + +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y # end of Graphics support CONFIG_SOUND=y @@ -4019,7 +4138,7 @@ CONFIG_SYNC_FILE=y CONFIG_VIRT_DRIVERS=y CONFIG_VBOXGUEST=m # CONFIG_NITRO_ENCLAVES is not set -CONFIG_VIRTIO=m +CONFIG_VIRTIO=y CONFIG_VIRTIO_PCI_LIB=m CONFIG_VIRTIO_MENU=y CONFIG_VIRTIO_PCI=m @@ -4028,7 +4147,7 @@ CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_INPUT=m CONFIG_VIRTIO_MMIO=m CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y -CONFIG_VIRTIO_DMA_SHARED_BUFFER=m +CONFIG_VIRTIO_DMA_SHARED_BUFFER=y # CONFIG_VDPA is not set CONFIG_VHOST_MENU=y # CONFIG_VHOST_NET is not set @@ -4070,21 +4189,29 @@ CONFIG_XEN_AUTO_XLATE=y CONFIG_XEN_ACPI=y CONFIG_XEN_SYMS=y CONFIG_XEN_HAVE_VPMU=y -CONFIG_XEN_FRONT_PGDIR_SHBUF=m +CONFIG_XEN_FRONT_PGDIR_SHBUF=y # end of Xen driver support # CONFIG_GREYBUS is not set # CONFIG_COMEDI is not set # CONFIG_STAGING is not set CONFIG_X86_PLATFORM_DEVICES=y -# CONFIG_ACPI_WMI is not set +CONFIG_ACPI_WMI=y +CONFIG_WMI_BMOF=m +# CONFIG_HUAWEI_WMI is not set +CONFIG_MXM_WMI=y +# CONFIG_PEAQ_WMI is not set +# CONFIG_XIAOMI_WMI is not set +# CONFIG_GIGABYTE_WMI is not set # CONFIG_ACERHDF is not set # CONFIG_ACER_WIRELESS is not set +# CONFIG_ACER_WMI is not set # CONFIG_AMD_PMC is not set # CONFIG_ADV_SWBUTTON is not set # CONFIG_APPLE_GMUX is not set # CONFIG_ASUS_LAPTOP is not set # CONFIG_ASUS_WIRELESS is not set +# CONFIG_ASUS_WMI is not set CONFIG_EEEPC_LAPTOP=y # CONFIG_X86_PLATFORM_DRIVERS_DELL is not set # CONFIG_AMILO_RFKILL is not set @@ -4093,10 +4220,12 @@ CONFIG_EEEPC_LAPTOP=y # CONFIG_GPD_POCKET_FAN is not set # CONFIG_HP_ACCEL is not set # CONFIG_WIRELESS_HOTKEY is not set +# CONFIG_HP_WMI is not set # CONFIG_IBM_RTL is not set # CONFIG_IDEAPAD_LAPTOP is not set # CONFIG_SENSORS_HDAPS is not set # CONFIG_THINKPAD_ACPI is not set +# CONFIG_THINKPAD_LMI is not set CONFIG_X86_PLATFORM_DRIVERS_INTEL=y # CONFIG_INTEL_ATOMISP2_PM is not set # CONFIG_INTEL_SAR_INT1092 is not set @@ -4108,6 +4237,8 @@ CONFIG_X86_PLATFORM_DRIVERS_INTEL=y # CONFIG_INTEL_SPEED_SELECT_INTERFACE is not set # end of Intel Speed Select Technology interface support +# CONFIG_INTEL_WMI_SBL_FW_UPDATE is not set +# CONFIG_INTEL_WMI_THUNDERBOLT is not set # CONFIG_INTEL_HID_EVENT is not set # CONFIG_INTEL_VBTN is not set # CONFIG_INTEL_OAKTRAIL is not set @@ -4117,12 +4248,15 @@ CONFIG_X86_PLATFORM_DRIVERS_INTEL=y # CONFIG_INTEL_TURBO_MAX_3 is not set # CONFIG_INTEL_UNCORE_FREQ_CONTROL is not set # CONFIG_MSI_LAPTOP is not set +# CONFIG_MSI_WMI is not set # CONFIG_SAMSUNG_LAPTOP is not set # CONFIG_SAMSUNG_Q10 is not set # CONFIG_TOSHIBA_BT_RFKILL is not set # CONFIG_TOSHIBA_HAPS is not set +# CONFIG_TOSHIBA_WMI is not set # CONFIG_ACPI_CMPC is not set # CONFIG_COMPAL_LAPTOP is not set +# CONFIG_LG_LAPTOP is not set # CONFIG_PANASONIC_LAPTOP is not set # CONFIG_SONY_LAPTOP is not set # CONFIG_SYSTEM76_ACPI is not set @@ -4892,8 +5026,9 @@ CONFIG_HAVE_GENERIC_VDSO=y CONFIG_GENERIC_GETTIMEOFDAY=y CONFIG_GENERIC_VDSO_TIME_NS=y CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y -CONFIG_FONT_AUTOSELECT=y CONFIG_SG_POOL=y CONFIG_ARCH_HAS_PMEM_API=y CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y diff --git a/npmi.sh b/npmi.sh new file mode 100755 index 0000000..5d32a6f --- /dev/null +++ b/npmi.sh @@ -0,0 +1,7 @@ +if [ "$EUID" = 0 ] +then echo "Please don't run as root" + exit +fi + +npm i +cd rootfs\ overrides/chibrax && npm i && cd - \ No newline at end of file diff --git a/rootfs overrides/chibrax/.gitignore b/rootfs overrides/chibrax/.gitignore index 3018483..e47f72a 100644 --- a/rootfs overrides/chibrax/.gitignore +++ b/rootfs overrides/chibrax/.gitignore @@ -1,4 +1,6 @@ syscall.node ioctl.node mount.node -file.node \ No newline at end of file +file.node +node_modules +package-lock.json \ No newline at end of file diff --git a/rootfs overrides/chibrax/graphics.js b/rootfs overrides/chibrax/graphics.js new file mode 100644 index 0000000..f4f434f --- /dev/null +++ b/rootfs overrides/chibrax/graphics.js @@ -0,0 +1,150 @@ +//@ts-check +const fs = require('fs') +const jimp = require('jimp') + +const screen = getScreenDimensions() +const buffer = Buffer.alloc(screen.width * screen.height * screen.byteDepth) +//TODO: implement automatic cache cleanup +/** + * @type {{ [key: string]: import('@jimp/core').Bitmap }} + */ +const imageCache = {} + +function getScreenDimensions() { + const vsize = fs.readFileSync('/sys/class/graphics/fb0/virtual_size', { encoding: 'utf-8' }).split(',') + const byteDepth = parseInt(fs.readFileSync('/sys/class/graphics/fb0/bits_per_pixel').toString()) / 8 + + return { + width: parseInt(vsize[0]), + height: parseInt(vsize[1]), + byteDepth + } +} + +/** + * @param { Buffer } data + */ +function flip(data = buffer) { + try { + fs.writeFileSync('/dev/fb0', data, { encoding: 'binary' }) + } catch(e) { + console.log("could not write to /dev/fb0") + console.log(e) + } +} + +function clear() { + buffer.fill(0) +} + +/** + * @param {string} filepath + */ +function removeFromCache(filepath) { + delete imageCache[filepath] +} + +/** + * @param { number } x + * @param { number } y + * @param { string } filepath + * //!\\ THE CACHE DOESN'T CLEAN ITSELF UP //!\\ + * once you finished displaying a image use removeFromCache to free the associated memory + */ +async function drawImgFile(x, y, filepath) { + let bitmap + //not caching would imply reading the image each time we want to write it to the screen even for small movement + if(!imageCache[filepath]) { + const img = await jimp.read(filepath) + bitmap = img.bitmap + bitmap.data = rgbaTObgra(bitmap.data) + imageCache[filepath] = bitmap + } else { + bitmap = imageCache[filepath] + } + + + + for(let dy = 0; dy < bitmap.height; dy++) { + let bitmapLineEnd = bitmap.width * screen.byteDepth * (dy + 1) + let bitmapLineStart = bitmap.width * screen.byteDepth * dy + let dx = x + + const offscreenRight = dx + bitmap.width - screen.width + if(offscreenRight > 0) { + bitmapLineEnd -= offscreenRight*4 + } + + const offscreenLeft = -dx + if(offscreenLeft > 0) { + bitmapLineStart += offscreenLeft*4 + dx = 0 + } + + const offscreenTop = -y + if(offscreenTop >= dy) { + dy = offscreenTop + continue + } + + const offscreenBottom = bitmap.height + y - screen.height + if(offscreenBottom > 0 && bitmap.height - offscreenBottom <= dy) { + break + } + + if(bitmapLineEnd < bitmapLineStart) { + continue + } + + + const line = bitmap.data.subarray(bitmapLineStart, bitmapLineEnd) + buffer.set(Array.from(line), dx * screen.byteDepth + screen.width * (dy + y) * screen.byteDepth) + } +} + +/** + * @param { Buffer } buff + */ +function rgbaTObgra(buff) { + for(let i=0; i < buff.length; i += 4) { + const r = buff.readUInt8(i) + const b = buff.readUInt8(i+2) + + buff.set([b], i) + buff.set([r], i+2) + } + return buff +} + +/** + * @param { string } color + * @returns { number[] } + */ +function parseHexColor(color) { + if(!color.startsWith('#') || color.length !== 7) { + throw new Error('invalid hex color code') + } + const r = parseInt(color.substring(1,2), 16) + const v = parseInt(color.substring(3,4), 16) + const b = parseInt(color.substring(5,6), 16) + return [b, v, r, 0] +} + +/** + * + * @param { number } x + * @param { number } y + * @param { string | number[] } colorCode + */ +function setPixel(x, y, colorCode) { + if (screen.byteDepth !== 4) { + throw new Error('Depth not supported yet') + } + + if(typeof colorCode === 'string') { + colorCode = parseHexColor(colorCode) + } + buffer.set(colorCode, (x + y * screen.width) * screen.byteDepth) +} + +module.exports = { flip, clear, getScreenDimensions, drawImgFile, parseHexColor, setPixel } \ No newline at end of file diff --git a/rootfs overrides/chibrax/package.json b/rootfs overrides/chibrax/package.json index 6b09ba8..41b697f 100644 --- a/rootfs overrides/chibrax/package.json +++ b/rootfs overrides/chibrax/package.json @@ -1,5 +1,8 @@ { "devDependencies": { - "@types/node": "^16.11.10" + "@types/node": "^16.11.21" + }, + "dependencies": { + "jimp": "^0.16.1" } } diff --git a/rootfs overrides/usr/bin/framebuffer-demo.js b/rootfs overrides/usr/bin/framebuffer-demo.js new file mode 100644 index 0000000..3535029 --- /dev/null +++ b/rootfs overrides/usr/bin/framebuffer-demo.js @@ -0,0 +1,135 @@ +//@ts-check +const graphics = require('../../chibrax/graphics') + +graphics.clear() +drawChibrax() + +graphics.flip() + +function drawChibrax() { + //LA LETTRE C + for(let i = 0; i < 100; i++) { + for(let j = 0; j < 10; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 0; i < 20; i++) { + for(let j = 10; j < 110; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + for(let i = 0; i < 100; i++) { + for(let j = 110; j < 120; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + + //LA LETTRE H + for(let i = 110; i < 130; i++) { + for(let j = 0; j < 100; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 110; i < 210; i++) { + for(let j = 50; j < 60; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + for(let i = 210; i < 230; i++) { + for(let j = 0; j < 100; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + //LA LETTRE I + for(let i = 240; i < 260; i++) { + for(let j = 0; j < 100; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + //LA LETTRE B + for(let i = 270; i < 280; i++) { + for(let j = 0; j < 100; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 380; i < 390; i++) { + for(let j = 0; j < 100; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 270; i < 390; i++) { + for(let j = 0; j < 10; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 270; i < 390; i++) { + for(let j = 50; j < 60; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 270; i < 390; i++) { + for(let j = 90; j < 100; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + //LA LETTRE R + for(let i = 400; i < 410; i++) { + for(let j = 0; j < 100; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 510; i < 520; i++) { + for(let j = 0; j < 100; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 400; i < 520; i++) { + for(let j = 0; j < 10; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 400; i < 520; i++) { + for(let j = 50; j < 60; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + //LA LETTRE E + for(let i = 530; i < 630; i++) { + for(let j = 0; j < 10; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 530; i < 550; i++) { + for(let j = 10; j < 110; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 530; i < 630; i++) { + for(let j = 50; j < 60; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + + for(let i = 530; i < 630; i++) { + for(let j = 110; j < 120; j++) { + graphics.setPixel(i,j, [0,0,255,0]) + } + } + +} \ No newline at end of file