From ddf419f7024d1174fb555c2d3ffc7a2b94154900 Mon Sep 17 00:00:00 2001 From: ZennDev1337 Date: Tue, 3 Oct 2023 08:50:48 +0200 Subject: [PATCH] added ArduboyFx begin drawBitmap and display to the crate also added a fxdata-converter.html file to the docs --- Project/game/src/lib.rs | 23 +- arduboy-rust/src/lib.rs | 1 + arduboy-rust/src/library/arduboy2.rs | 4 +- arduboy-rust/src/library/arduboyfx.rs | 28 +- docs/arduboy-file-converter.html | 39 +- docs/fxdata-converter.html | 363 +++ docs/image-converter.html | 786 +++--- docs/index.html | 40 +- docs/sprite-converter.html | 3664 +++++++++++++------------ docs/tile-converter.html | 952 +++---- 10 files changed, 3218 insertions(+), 2682 deletions(-) create mode 100644 docs/fxdata-converter.html diff --git a/Project/game/src/lib.rs b/Project/game/src/lib.rs index 96d724c..331b90b 100644 --- a/Project/game/src/lib.rs +++ b/Project/game/src/lib.rs @@ -2,6 +2,7 @@ #![allow(non_upper_case_globals)] //Include the Arduboy Library +use arduboy_rust::arduboyfx::*; #[allow(unused_imports)] use arduboy_rust::prelude::*; @@ -11,14 +12,23 @@ const arduboy: Arduboy2 = Arduboy2::new(); // Progmem data // dynamic ram variables +const FX_DATA_PAGE: u16 = 0xffff; +const FX_DATA_BYTES: u32 = 234; +const FXlogo: u32 = 0x000000; +const FXlogoWith: i16 = 115; +const FXlogoHeight: i16 = 16; +static mut x: i16 = (WIDTH - FXlogoWith) / 2; +static mut y: i16 = 25; +static mut xDir: i8 = 1; +static mut yDir: i8 = 1; // The setup() function runs once when you turn your Arduboy on #[no_mangle] pub unsafe extern "C" fn setup() { // put your setup code here, to run once: arduboy.begin(); arduboy.set_frame_rate(30); - arduboy.clear(); + arduboyfx_begin_data(FX_DATA_PAGE); } // The loop() function repeats forever after setup() is done #[no_mangle] @@ -28,5 +38,14 @@ pub unsafe extern "C" fn loop_() { if !arduboy.next_frame() { return; } - arduboy.display(); + arduboyfx_draw_bitmap(x, y, FXlogo, 0, 0); + x += xDir as i16; + y += yDir as i16; + if x == 0 || x == WIDTH - FXlogoWith { + xDir = -xDir; + } + if y == 0 || y == HEIGHT - FXlogoHeight { + yDir = -yDir; + } + arduboyfx_display_clear(); } diff --git a/arduboy-rust/src/lib.rs b/arduboy-rust/src/lib.rs index e2547ea..493bfaf 100644 --- a/arduboy-rust/src/lib.rs +++ b/arduboy-rust/src/lib.rs @@ -37,5 +37,6 @@ pub use crate::library::arduboy_tone::{self, ArduboyTones}; pub use crate::library::ardvoice::{self, ArdVoice}; pub use crate::library::eeprom::{EEPROM, EEPROMBYTE}; pub use crate::library::{arduino, c, sprites}; +pub use crate::library::arduboyfx; pub mod serial_print; diff --git a/arduboy-rust/src/library/arduboy2.rs b/arduboy-rust/src/library/arduboy2.rs index e9dde88..b0b94da 100644 --- a/arduboy-rust/src/library/arduboy2.rs +++ b/arduboy-rust/src/library/arduboy2.rs @@ -14,11 +14,11 @@ pub const FONT_SIZE: u8 = 6; /// The standard width of the arduboy /// /// this is to calculate with it. -pub const WIDTH: u8 = 128; +pub const WIDTH: i16 = 128; /// The standard height of the arduboy /// /// this is to calculate with it. -pub const HEIGHT: u8 = 64; +pub const HEIGHT: i16 = 64; /// This item is to chose between Black or White #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] diff --git a/arduboy-rust/src/library/arduboyfx.rs b/arduboy-rust/src/library/arduboyfx.rs index ee09729..2544e63 100644 --- a/arduboy-rust/src/library/arduboyfx.rs +++ b/arduboy-rust/src/library/arduboyfx.rs @@ -1,8 +1,26 @@ +#![allow(non_upper_case_globals)] +use core::ffi::{c_int, c_long, c_uchar, c_uint, c_ulong}; - - +pub const dbmNormal: u8 = 0; +pub const dbmOverwrite: u8 = 0; +pub const dbmMasked: u8 = 1; extern "C" { #[link_name = "arduboyfx_begin"] - fn arduboyfx_begin(); - -} \ No newline at end of file + pub fn arduboyfx_begin(); + #[link_name = "arduboyfx_begin_data"] + pub fn arduboyfx_begin_data(datapage: c_uint); + #[link_name = "arduboyfx_begin_data_save"] + pub fn arduboyfx_begin_data_save(datapage: c_uint, savepage: c_uint); + #[link_name = "arduboyfx_display"] + pub fn arduboyfx_display(); + #[link_name = "arduboyfx_display_clear"] + pub fn arduboyfx_display_clear(); + #[link_name = "arduboyfx_draw_bitmap"] + pub fn arduboyfx_draw_bitmap( + x: c_int, + y: c_int, + address: c_ulong, + frame: c_uchar, + mode: c_uchar, + ); +} diff --git a/docs/arduboy-file-converter.html b/docs/arduboy-file-converter.html index e4aacdd..7af0c30 100644 --- a/docs/arduboy-file-converter.html +++ b/docs/arduboy-file-converter.html @@ -100,7 +100,6 @@ .topnav { background-color: #000000; - overflow: hidden; height: 47px; } @@ -126,7 +125,7 @@ display: none; } - @media screen and (max-width: 1049px) { + @media screen and (max-width: 800px) { .topnav a:not(:first-child) { display: none; } @@ -137,10 +136,10 @@ } } - @media screen and (max-width: 1049px) { + @media screen and (max-width: 800px) { .topnav.responsive { position: relative; - height: 247px; + height: auto; } .topnav { @@ -215,13 +214,31 @@
- Rust for Arduboy - Image - Converter - Tile Converter - Sprite Converter - .arduboy - Generator + Rust for Arduboy + Image Converter + Tile Converter + Sprite Converter + .arduboy Generator + fxdata.h Converter diff --git a/docs/fxdata-converter.html b/docs/fxdata-converter.html new file mode 100644 index 0000000..54525a4 --- /dev/null +++ b/docs/fxdata-converter.html @@ -0,0 +1,363 @@ + + + + + + ZennDev1337 Image Converter + + + + + + + + + + + diff --git a/docs/image-converter.html b/docs/image-converter.html index be7dfb6..0893ad8 100644 --- a/docs/image-converter.html +++ b/docs/image-converter.html @@ -1,403 +1,435 @@ + + + + ZennDev1337 Image Converter + - - - - ZennDev1337 Image Converter - - - - - - - - + - + // Create image element + var droppedImage = new Image(); + droppedImage.src = event.target.result; + // add delay so the image can be loaded properly before accessing it + setTimeout(function () { + // Create canvas for image + var droppedImageCanvas = + document.createElement("canvas"); + droppedImageCanvas.width = droppedImage.naturalWidth; + droppedImageCanvas.height = droppedImage.naturalHeight; - \ No newline at end of file + // Create code container + var droppedImageCode = + document.createElement("textarea"); + droppedImageCode.className = "code"; + + droppedImageCode.style.width = "698px"; + droppedImageCode.rows = "20"; + + // Create div container + var droppedImageDiv = document.createElement("div"); + droppedImageDiv.className = "image-view"; + droppedImageDiv.appendChild(droppedImageCanvas); + + var imageContainer = + document.getElementById("image-container"); + imageContainer.innerHTML = ""; + imageContainer.appendChild(droppedImageDiv); + imageContainer.appendChild( + document.createElement("br") + ); + imageContainer.appendChild(droppedImageCode); + + // Create context for drawing + var droppedImageContext = + droppedImageCanvas.getContext("2d"); + + // Draw the image + droppedImageContext.drawImage(droppedImage, 0, 0); + + // Generate the sprite string + var spriteString = + "static " + + imageData.name.split(/_|\./)[0] + + ": [u8;_] = " + + "[\n" + + droppedImage.naturalWidth + + ", " + + droppedImage.naturalHeight + + ", // width, height,\n"; + + var pageCount = Math.ceil( + droppedImage.naturalHeight / 8 + ); + var columnCount = droppedImage.naturalWidth; + var currentByte = 0; + + // Read the sprite page-by-page + for (var page = 0; page < pageCount; page++) { + // Read the page column-by-column + for ( + var column = 0; + column < columnCount; + column++ + ) { + // Read the column into a byte + var spriteByte = 0; + for (var yPixel = 0; yPixel < 8; yPixel++) { + // If the color of the pixel is not black, count it as white + var pixelColor = + droppedImageContext.getImageData( + column, + page * 8 + yPixel, + 1, + 1 + ).data; + if ( + pixelColor[0] > 0 || + pixelColor[1] > 0 || + pixelColor[2] > 0 + ) { + spriteByte |= 1 << yPixel; + } + } + + // Print the column in hex notation, add a comma for formatting + var digitStr = spriteByte.toString(16); + if (digitStr.length == 1) { + digitStr = "0" + digitStr; + } + spriteString += "0x" + digitStr + ", "; + if ( + currentByte % droppedImage.naturalWidth == + droppedImage.naturalWidth - 1 + ) { + spriteString += "\n"; + } + currentByte++; + } + } + // Terminate the array + spriteString += "];"; + // Create an invisible element containing the string + droppedImageCode.innerHTML = spriteString; + + // Resize canvas to show 2x scaled image + droppedImageCanvas.width = + droppedImage.naturalWidth * 2; + droppedImageCanvas.height = + droppedImage.naturalHeight * 2; + droppedImageContext = + droppedImageCanvas.getContext("2d"); + droppedImageContext.imageSmoothingEnabled = false; + droppedImageContext.drawImage( + droppedImage, + 0, + 0, + droppedImage.naturalWidth * 2, + droppedImage.naturalHeight * 2 + ); + }, 50); + }; + reader.readAsDataURL(imageData); + } + + + diff --git a/docs/index.html b/docs/index.html index 62eb9d2..b162fbf 100644 --- a/docs/index.html +++ b/docs/index.html @@ -99,8 +99,7 @@ .topnav { background-color: #000000; - overflow: hidden; - height: 47px; + min-height: 47px; } .topnav a { @@ -125,7 +124,7 @@ display: none; } - @media screen and (max-width: 1049px) { + @media screen and (max-width: 800px) { .topnav a:not(:first-child) { display: none; } @@ -136,10 +135,10 @@ } } - @media screen and (max-width: 1049px) { + @media screen and (max-width: 800px) { .topnav.responsive { position: relative; - height: 247px; + height: auto; } .topnav { @@ -167,12 +166,31 @@
- Rust for Arduboy - Image Converter - Tile Converter - Sprite Converter - .arduboy - Generator + Rust for Arduboy + Image Converter + Tile Converter + Sprite Converter + .arduboy Generator + fxdata.h Converter diff --git a/docs/sprite-converter.html b/docs/sprite-converter.html index c688dc8..8f2190b 100644 --- a/docs/sprite-converter.html +++ b/docs/sprite-converter.html @@ -1,1958 +1,1992 @@ + + + + ZennDev1337 Sprite Converter + - - - - ZennDev1337 Sprite Converter - - - - -
-
- Rust for Arduboy - Image Converter - Tile Converter - Sprite - Converter - .arduboy - Generator - - - - - + + .topnav a.active { + background-color: #281c1c; + color: white; + } + + .topnav .icon { + display: none; + } + + @media screen and (max-width: 800px) { + .topnav a:not(:first-child) { + display: none; + } + + .topnav a.icon { + float: right; + display: block; + } + } + + @media screen and (max-width: 800px) { + .topnav.responsive { + position: relative; + height: auto; + } + + .topnav { + text-align: left; + } + + .topnav.responsive a.icon { + position: absolute; + right: 0; + top: 0; + } + + .topnav.responsive a { + float: none; + display: block; + text-align: left; + } + } + + -
-

Drop your sprite here

-
-
-
-
-
-
-
- - - + + - - + - + - - + + - - - \ No newline at end of file + // Put the code in the text field + droppedImageCode.innerHTML = spriteString; + droppedMaskCode.innerHTML = maskString; + droppedComboCode.innerHTML = comboString; + }, 50); + }; + reader.readAsDataURL(imageData); + } + + + diff --git a/docs/tile-converter.html b/docs/tile-converter.html index 1f539b0..bc67e76 100644 --- a/docs/tile-converter.html +++ b/docs/tile-converter.html @@ -1,489 +1,523 @@ + + + + ZennDev1337 Tile Converter + - - - - ZennDev1337 Tile Converter - - - - -
- -
-

Drop your tile sheet here

-
-
-
-
-
-
-
- - - + - - - \ No newline at end of file + // Draw raster between tiles on the canvas + droppedImageContext.beginPath(); + for ( + var j = 1; + j <= Math.floor(700 / (tileW + 2)); + j++ + ) { + droppedImageContext.moveTo( + j * tileW + 1 + (j - 1) * 2, + 0 + ); + droppedImageContext.lineTo( + j * tileW + 1 + (j - 1) * 2, + canvasHeight + ); + } + for ( + var k = 1; + k <= + Math.ceil( + imgNH / imgNW / Math.floor(700 / tileW + 2) + ); + k++ + ) { + droppedImageContext.moveTo( + 0, + k * tileW + 1 + (k - 1) * 2 + ); + droppedImageContext.lineTo( + canvasWidth, + k * tileW + 1 + (k - 1) * 2 + ); + } + droppedImageContext.strokeStyle = "#281c1c"; + droppedImageContext.lineWidth = 2; + droppedImageContext.stroke(); + let sep = + window.document.getElementsByClassName("separator"); + for (let item of sep) { + item.style.borderColor = "#ce422b"; + } + // Generate the sprite string + var spriteString = + "static " + + imageData.name.split("_")[0] + + ": [u8;_] = " + + "[\n" + + imgNW + + ", " + + imgNW + + ", // width, height,\n" + + "// TILE 00\n"; + var pageCount = Math.ceil(imgNH / 8); + var columnCount = imgNW; + var currentByte = 0; + var rowCounter = 0; + var tileCounter = 0; + // Read the sprite page-by-page + for (var page = 0; page < pageCount; page++) { + // Read the page column-by-column + for ( + var column = 0; + column < columnCount; + column++ + ) { + // Read the column into a byte + var spriteByte = 0; + for (var yPixel = 0; yPixel < 8; yPixel++) { + // If the color of the pixel is not black, count it as white + var pixelColor = + invisImageContext.getImageData( + column, + page * 8 + yPixel, + 1, + 1 + ).data; + if ( + pixelColor[0] > 0 || + pixelColor[1] > 0 || + pixelColor[2] > 0 + ) { + spriteByte |= 1 << yPixel; + } + } + // Print the column in hex notation, add a comma for formatting + var digitStr = spriteByte.toString(16); + if (digitStr.length == 1) { + digitStr = "0" + digitStr; + } + spriteString += "0x" + digitStr + ", "; + if (currentByte % imgNW == imgNW - 1) { + spriteString += "\n"; + rowCounter++; + if ( + rowCounter == imgNW / 8 && + tileCounter < imgNH / imgNW - 1 + ) { + tileCounter++; + var tileNumber = + tileCounter.toString().length === 1 + ? "0" + tileCounter.toString() + : tileCounter.toString(); + spriteString += + "// TILE " + tileNumber + "\n"; + rowCounter = 0; + } + } + currentByte++; + } + } + // Terminate the array + spriteString += "];"; + // Create an invisible element containing the string + droppedImageCode.innerHTML = spriteString; + }, 50); + }; + reader.readAsDataURL(imageData); + } + + +