mirror of
https://github.com/exoticorn/microw8.git
synced 2026-01-20 11:16:42 +01:00
new commented examples
This commit is contained in:
254
examples/curlywas/cube_wireframe.cwa
Normal file
254
examples/curlywas/cube_wireframe.cwa
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
This program renders a rotating 3D wireframe cube on a 2D screen using the MicroW8 platform.
|
||||
|
||||
code : zbyti
|
||||
date : 2025.04.15
|
||||
platform : MicroW8 0.4.1
|
||||
|
||||
https://exoticorn.github.io/microw8/
|
||||
https://exoticorn.github.io/microw8/docs/
|
||||
|
||||
https://github.com/exoticorn/microw8
|
||||
https://github.com/exoticorn/curlywas
|
||||
|
||||
https://developer.mozilla.org/en-US/docs/WebAssembly
|
||||
|
||||
https://en.wikipedia.org/wiki/Rotation_matrix
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MicroW8 API
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//include "../include/microw8-api.cwa"
|
||||
|
||||
// Import memory allocation: 4 pages (64KB) of memory (256KB total)
|
||||
import "env.memory" memory(4);
|
||||
|
||||
// Import MicroW8 API functions for graphics and math operations
|
||||
import "env.cls" fn cls(i32); // Clears the screen
|
||||
import "env.time" fn time() -> f32; // Returns the current time as a float for animation
|
||||
import "env.sin" fn sin(f32) -> f32; // Computes the sine of an angle (in radians)
|
||||
import "env.cos" fn cos(f32) -> f32; // Computes the cosine of an angle (in radians)
|
||||
import "env.line" fn line(f32, f32, f32, f32, i32); // Draws a line between two 2D points with a color
|
||||
|
||||
// Define the starting address for user memory
|
||||
const USER_MEM = 0x14000;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CONSTANTS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Screen and rendering constants
|
||||
const CENTER_X = 320.0 / 2.0; // X-coordinate of the screen center (320px width)
|
||||
const CENTER_Y = 240.0 / 2.0; // Y-coordinate of the screen center (240px height)
|
||||
const ROTATE_SPEED = 0.5; // Speed at which the cube rotates
|
||||
const PI = 3.14159265; // Mathematical constant Pi for angle conversions
|
||||
const RADIAN = PI / 180.0; // Conversion factor from degrees to radians
|
||||
const SCALE = 65.0; // Scaling factor to adjust the size of the cube on screen
|
||||
const PERSPECTIVE = SCALE * 0.5; // Perspective factor
|
||||
const LINE_COLOR = 0xBF; // Color value for drawing the cube's edges (hexadecimal)
|
||||
|
||||
// Memory layout for vertex data
|
||||
const V_BASE = USER_MEM; // Base vertices stored as 8-bit integers (i8)
|
||||
const V_ROT = V_BASE + (3 * 8); // Rotated vertices stored as 32-bit floats (f32), offset after V_BASE
|
||||
|
||||
// Offsets for accessing X, Y, Z coordinates in memory (in bytes)
|
||||
const X = 0; // Offset for X coordinate
|
||||
const Y = 4; // Offset for Y coordinate
|
||||
const Z = 8; // Offset for Z coordinate
|
||||
|
||||
// Memory offsets for each rotated vertex (8 vertices, 3 floats each, 12 bytes per vertex)
|
||||
const VA = V_ROT + (0 * 3 * 4); // Vertex A (front-top-left)
|
||||
const VB = V_ROT + (1 * 3 * 4); // Vertex B (front-top-right)
|
||||
const VC = V_ROT + (2 * 3 * 4); // Vertex C (front-bottom-right)
|
||||
const VD = V_ROT + (3 * 3 * 4); // Vertex D (front-bottom-left)
|
||||
const VE = V_ROT + (4 * 3 * 4); // Vertex E (back-top-left)
|
||||
const VF = V_ROT + (5 * 3 * 4); // Vertex F (back-top-right)
|
||||
const VG = V_ROT + (6 * 3 * 4); // Vertex G (back-bottom-right)
|
||||
const VH = V_ROT + (7 * 3 * 4); // Vertex H (back-bottom-left)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Function to rotate the cube around X, Y, and Z axes based on time
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
fn rotate() {
|
||||
// Calculate the rotation angle using the current time for continuous animation
|
||||
let angle = time() * ROTATE_SPEED;
|
||||
|
||||
// Precompute sine and cosine values once for efficiency
|
||||
let sn = sin(angle);
|
||||
let cs = cos(angle);
|
||||
|
||||
let calc = 0;
|
||||
loop calc { // Iterate over all 8 vertices
|
||||
// Calculate memory offset for current vertex (12 bytes per vertex: 4 bytes each for X, Y, Z)
|
||||
let v = calc * 12;
|
||||
let inline vX = v + X;
|
||||
let inline vY = v + Y;
|
||||
let inline vZ = v + Z;
|
||||
|
||||
// Load original vertex coordinates from V_BASE (stored as i8, converted to f32)
|
||||
let x = i32.load8_s(V_BASE+(calc * 3 + 0)) as f32; // X coordinate
|
||||
let y = i32.load8_s(V_BASE+(calc * 3 + 1)) as f32; // Y coordinate
|
||||
let z = i32.load8_s(V_BASE+(calc * 3 + 2)) as f32; // Z coordinate
|
||||
|
||||
// Rotate around Z-axis: updates X and Y, Z stays the same
|
||||
(vX)$V_ROT = x * cs - y * sn;
|
||||
(vY)$V_ROT = x * sn + y * cs;
|
||||
(vZ)$V_ROT = z;
|
||||
|
||||
// Rotate around Y-axis: updates X and Z, Y stays the same
|
||||
x = (vX)$V_ROT;
|
||||
z = (vZ)$V_ROT;
|
||||
(vX)$V_ROT = x * cs + z * sn;
|
||||
(vZ)$V_ROT = z * cs - x * sn;
|
||||
|
||||
// Rotate around X-axis: updates Y and Z, X stays the same
|
||||
y = (vY)$V_ROT;
|
||||
z = (vZ)$V_ROT;
|
||||
(vY)$V_ROT = y * cs - z * sn;
|
||||
(vZ)$V_ROT = y * sn + z * cs;
|
||||
|
||||
// Move to the next vertex until all 8 are processed
|
||||
branch_if (calc +:= 1) < 8: calc;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Function to project 3D vertices to 2D screen space and draw the cube's edges
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
fn drawLines() {
|
||||
let scale = 0;
|
||||
loop scale { // Scale and center each vertex for 2D projection
|
||||
// Calculate memory offset for current vertex (12 bytes per vertex: 4 bytes each for X, Y, Z)
|
||||
let v = scale * 12;
|
||||
let inline vX = v + X;
|
||||
let inline vY = v + Y;
|
||||
|
||||
// Load Z coordinate of current vertex (from rotated vertex data)
|
||||
let inline z = (v + Z)$V_ROT;
|
||||
|
||||
// Calculate perspective factor:
|
||||
// - When z=0 (midpoint), factor=1.0 (no scaling)
|
||||
// - Positive z (farther away) → factor<1.0 (objects appear smaller)
|
||||
// - Negative z (closer) → factor>1.0 (objects appear larger)
|
||||
let lazy factor = PERSPECTIVE / (PERSPECTIVE + z) * SCALE;
|
||||
|
||||
// Apply perspective projection, scaling and shift to center for X and Y coordinats:
|
||||
// 1. Multiply by perspective factor
|
||||
// 2. Apply global scaling (SCALE constant)
|
||||
// 3. Center on screen (CENTER_X, CENTER_Y)
|
||||
(vX)$V_ROT = (vX)$V_ROT * factor + CENTER_X; // X
|
||||
(vY)$V_ROT = (vY)$V_ROT * factor + CENTER_Y; // Y
|
||||
|
||||
// Continue until all 8 vertices are scaled
|
||||
branch_if (scale +:= 1) < 8: scale;
|
||||
}
|
||||
|
||||
// Draw the front face of the cube (vertices A-B-C-D)
|
||||
line(VA$X, VA$Y, VB$X, VB$Y, LINE_COLOR);
|
||||
line(VB$X, VB$Y, VC$X, VC$Y, LINE_COLOR);
|
||||
line(VC$X, VC$Y, VD$X, VD$Y, LINE_COLOR);
|
||||
line(VD$X, VD$Y, VA$X, VA$Y, LINE_COLOR);
|
||||
|
||||
// Draw the back face of the cube (vertices E-F-G-H)
|
||||
line(VE$X, VE$Y, VF$X, VF$Y, LINE_COLOR);
|
||||
line(VF$X, VF$Y, VG$X, VG$Y, LINE_COLOR);
|
||||
line(VG$X, VG$Y, VH$X, VH$Y, LINE_COLOR);
|
||||
line(VH$X, VH$Y, VE$X, VE$Y, LINE_COLOR);
|
||||
|
||||
// Draw edges connecting front and back faces
|
||||
line(VA$X, VA$Y, VE$X, VE$Y, LINE_COLOR);
|
||||
line(VB$X, VB$Y, VF$X, VF$Y, LINE_COLOR);
|
||||
line(VC$X, VC$Y, VG$X, VG$Y, LINE_COLOR);
|
||||
line(VD$X, VD$Y, VH$X, VH$Y, LINE_COLOR);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Entry point for INIT type function, starts first
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
export fn start() {
|
||||
let init = 0;
|
||||
loop init {
|
||||
// Calculate memory offset for current vertex (12 bytes per vertex: 4 bytes each for X, Y, Z)
|
||||
let v = init * 12;
|
||||
|
||||
(v + X)$V_ROT = i32.load8_s(V_BASE+(init * 3) + 0) as f32;
|
||||
(v + Y)$V_ROT = i32.load8_s(V_BASE+(init * 3) + 1) as f32;
|
||||
(v + Z)$V_ROT = i32.load8_s(V_BASE+(init * 3) + 2) as f32;
|
||||
branch_if (init +:= 1) < 8: init;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main update function called every frame to refresh the screen
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
export fn upd() {
|
||||
cls(0); // Clear the screen with color 0 (black)
|
||||
rotate(); // Perform cube rotation calculations
|
||||
drawLines(); // Draw the rotated cube on the screen
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DATA
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Initial vertex data for the cube (8 vertices, each with X, Y, Z as 8-bit signed integers)
|
||||
Each vertex represents a corner of a unit cube centered at the origin
|
||||
|
||||
F - front, B - back, L - left, R - right, U - up, D - down
|
||||
*/
|
||||
data V_BASE { // 3 * 8 -> 3 bytes per vertex * 8 vertices = 24 bytes
|
||||
i8(
|
||||
// X Y Z
|
||||
-1, -1, 1, // FLU Vertex A
|
||||
1, -1, 1, // FRU Vertex B
|
||||
1, 1, 1, // FRD Vertex C
|
||||
-1, 1, 1, // FLD Vertex D
|
||||
-1, -1, -1, // BLU Vertex E
|
||||
1, -1, -1, // BRU Vertex F
|
||||
1, 1, -1, // BRD Vertex G
|
||||
-1, 1, -1 // BLD Vertex H
|
||||
)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Storage for rotated vertex data (8 vertices, each with X, Y, Z as 32-bit signed floats)
|
||||
Initialized to zero and updated during rotation
|
||||
*/
|
||||
data V_ROT { // 4 * 3 * 8 -> 12 bytes per vertex * 8 vertices = 96 bytes
|
||||
f32(
|
||||
// X Y Z
|
||||
0.0, 0.0, 0.0, // VA -> Vertex A
|
||||
0.0, 0.0, 0.0, // VB -> Vertex B
|
||||
0.0, 0.0, 0.0, // VC -> Vertex C
|
||||
0.0, 0.0, 0.0, // VD -> Vertex D
|
||||
0.0, 0.0, 0.0, // VE -> Vertex E
|
||||
0.0, 0.0, 0.0, // VF -> Vertex F
|
||||
0.0, 0.0, 0.0, // VG -> Vertex G
|
||||
0.0, 0.0, 0.0 // VH -> Vertex H
|
||||
)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SNIPPETS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
let tmp: f32;
|
||||
tmp = -123.0;
|
||||
f32.store(tmp, V_ROT);
|
||||
tmp = f32.load(V_ROT);
|
||||
printInt(tmp as i32);
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
51
examples/curlywas/plasma.cwa
Normal file
51
examples/curlywas/plasma.cwa
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Plasma effect (sizecoding)
|
||||
|
||||
Combines sine waves to create a 2D pixel pattern with intensity-based colors.
|
||||
|
||||
code : zbyti & Grok 3
|
||||
date : 2025.04.17
|
||||
platform : MicroW8 0.4.1
|
||||
*/
|
||||
|
||||
include "../include/microw8-api.cwa"
|
||||
|
||||
// Constants for color, math, and screen dimensions
|
||||
const BASE_COLOR = 0xF0; // Base color value for pixel coloring
|
||||
const PI = 3.14159265; // Mathematical constant π
|
||||
const RAD = PI / 180.0; // Conversion factor from degrees to radians
|
||||
const SCR_X = 320; // Screen width in pixels
|
||||
const SCR_Y = 240; // Screen height in pixels
|
||||
const SCR_SIZE = SCR_X * SCR_Y; // Screen size in bytes
|
||||
|
||||
// Global variables to track animation phases
|
||||
global mut phaseX = 0; // Phase offset for X-axis wave animation
|
||||
global mut phaseY = 0; // Phase offset for Y-axis wave animation
|
||||
|
||||
// Update function called each frame to render the plasma effect
|
||||
export fn upd() {
|
||||
let i = 0;
|
||||
loop i {
|
||||
// Calculate pixel coordinates from linear index
|
||||
let lazy x = i % SCR_X; // X-coordinate (column)
|
||||
let lazy y = i / SCR_X; // Y-coordinate (row)
|
||||
|
||||
// Compute three sine waves with different frequencies and phases
|
||||
let inline val1 = sin(RAD * 2.25 * (x + phaseX) as f32); // Wave along X-axis
|
||||
let inline val2 = sin(RAD * 3.25 * (y + phaseY) as f32); // Wave along Y-axis
|
||||
let inline val3 = sin(RAD * 1.25 * (x + y + phaseX) as f32); // Diagonal wave
|
||||
|
||||
// Combine waves, scale to color range, and convert to integer
|
||||
let inline c = BASE_COLOR + ((val1 + val2 + val3) * 4.75) as i32;
|
||||
|
||||
// Set pixel color based on computed intensity
|
||||
setPixel(x, y, c);
|
||||
|
||||
// Continue loop until all pixels are processed
|
||||
branch_if (i +:= 1) < (SCR_SIZE): i;
|
||||
}
|
||||
|
||||
// Update phase offsets for animation (different speeds for dynamic effect)
|
||||
phaseX += 1; // Increment X-phase for horizontal wave movement
|
||||
phaseY += 2; // Increment Y-phase for vertical wave movement
|
||||
}
|
||||
168
examples/curlywas/plasma_chars.cwa
Normal file
168
examples/curlywas/plasma_chars.cwa
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
Plasma effect (chars)
|
||||
|
||||
Combines sine waves to create a 2D pattern, maps to custom characters,
|
||||
and renders to the 40x30 character grid with intensity-based colors.
|
||||
|
||||
code : zbyti (conversion & optimizations)
|
||||
original : https://github.com/tebe6502/Mad-Pascal/blob/origin/samples/a8/demoeffects/plasma_2.pas
|
||||
date : 2025.04.16
|
||||
platform : MicroW8 0.4.1
|
||||
*/
|
||||
|
||||
include "../include/microw8-api.cwa"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants defining memory layout, screen dimensions, and effect parameters
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const MEM_END = 0x40000;
|
||||
|
||||
const CUSTOM_FONT = FONT + 0x100;
|
||||
const CHARS = 0x20;
|
||||
const BASE_COLOR = 0xF0;
|
||||
|
||||
const PI = 3.14159265;
|
||||
const RAD = PI / 180.0;
|
||||
|
||||
const SCR_X = 320;
|
||||
const SCR_Y = 240;
|
||||
const SCR_W = SCR_X / 8; // 40
|
||||
const SCR_H = SCR_Y / 8; // 30
|
||||
const SCR_SIZE = SCR_X * SCR_Y;
|
||||
|
||||
const SIN_TABLE_SIZE = 128; // Number of entries in the sine lookup table
|
||||
const SIN_TABLE_MASK = SIN_TABLE_SIZE - 1;
|
||||
|
||||
const SIN_TABLE = MEM_END - SIN_TABLE_SIZE; // Memory address for sine table
|
||||
const ROW_BUFFER = SIN_TABLE - SCR_W; // Memory address for precomputed row buffer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Global variables to track animation state
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
global mut phaseA = 1; // Phase offset for the first sine wave, controls animation
|
||||
global mut phaseB = 5; // Phase offset for the second sine wave, controls animation
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Logs a value to the console (STDOUT) with a prefix for debugging purposes
|
||||
|
||||
Args:
|
||||
prefix : 4-character identifier (i32) to label the output
|
||||
log : Integer value to log (i32)
|
||||
|
||||
Prints to console and returns to screen output
|
||||
*/
|
||||
fn console(prefix: i32, log: i32) {
|
||||
printChar('\6'); // Switch output to console
|
||||
printChar(prefix); // Print the prefix
|
||||
printInt(log); // Print the integer value
|
||||
printChar('\n\4'); // Print newline and switch back to screen output
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
/*
|
||||
Fills a sine table with precomputed values for fast lookups
|
||||
|
||||
Args:
|
||||
adr : Memory address where the sine table is stored
|
||||
size : Number of entries in the table
|
||||
|
||||
Computes: sin(i * 180/size * radians) * 255 for i = 0 to size-1, scaled to 0-255
|
||||
*/
|
||||
fn fillSin(adr: i32, size: i32) {
|
||||
let i = 0;
|
||||
let inline f = 180.00 / size as f32 * RAD;
|
||||
loop i {
|
||||
(adr+i)?0 = (sin(f * i as f32) * 255.0) as i32;
|
||||
branch_if (i +:= 1) < size: i;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Initialization function called when the program starts
|
||||
*/
|
||||
export fn start() {
|
||||
// Populate the sine table with values for fast wave calculations
|
||||
fillSin(SIN_TABLE, SIN_TABLE_SIZE);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
/*
|
||||
Update function called each frame to render the plasma effect
|
||||
*/
|
||||
export fn upd() {
|
||||
let pA = phaseA; // Local copy of phaseA to avoid modifying global during frame
|
||||
let pB = phaseB; // Local copy of phaseB for the same reason
|
||||
|
||||
let i = 0;
|
||||
loop i {
|
||||
// Wrap phase values to stay within sine table bounds using bitwise AND
|
||||
pA &= SIN_TABLE_MASK;
|
||||
pB &= SIN_TABLE_MASK;
|
||||
|
||||
// Combine two sine waves and store in row buffer
|
||||
i?ROW_BUFFER = pA?SIN_TABLE + pB?SIN_TABLE;
|
||||
|
||||
pA += 3; // Shift phase for first sine wave (controls wave speed)
|
||||
pB += 7; // Shift phase for second sine wave (different speed for variety)
|
||||
|
||||
branch_if (i +:= 1) < SCR_W: i;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
loop i {
|
||||
let j = 0;
|
||||
loop j {
|
||||
// Combine wave values from row buffer for current position
|
||||
// Use bitwise AND to clamp to 0-255, then scale to 0-15 for character index
|
||||
let c = ((j?ROW_BUFFER + i?ROW_BUFFER) & 255) >> 4;
|
||||
|
||||
// Set text color based on intensity (base color + scaled value)
|
||||
setTextColor(BASE_COLOR + c);
|
||||
// Draw custom character corresponding to intensity
|
||||
printChar(CHARS + c);
|
||||
|
||||
branch_if (j +:= 1) < SCR_W: j;
|
||||
}
|
||||
branch_if (i +:= 1) < SCR_H: i;
|
||||
}
|
||||
|
||||
// Update global phase offsets for the next frame to animate the pattern
|
||||
phaseA += 0; // Increment phaseA to shift the pattern (+/- speed move)
|
||||
phaseB += 1; // Increment phaseB to shift the pattern (+/- right/left move)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Custom font data defining 16 characters (8x8 pixels each)
|
||||
Each character represents a different intensity level for the plasma effect
|
||||
Pixels range from empty (0x00) to nearly full (0xFE or 0x7F) to simulate gradients
|
||||
*/
|
||||
data CUSTOM_FONT {
|
||||
i8(
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
|
||||
0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00,
|
||||
0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00,
|
||||
0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
||||
0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00,
|
||||
0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user