diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7f4ca0c --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# kdevelop +.kde* +*.kdev4 +bin/* +lib/libWASM.a +*.o diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000..50525df --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,21 @@ +LIB = libWASM.a +CC = clang -fPIC +CX = clang++ -std=c++14 -fno-exceptions -fno-rtti -fPIC +AR = llvm-ar +INCLUDES = -I. +TARGET = --target=wasm32-unknown-unknown +CFLAGS = -Oz -flto -Wall $(TARGET) -ffunction-sections -fdata-sections $(INCLUDES) + +OBJS = heap.o newdel.o hack.o math.o printf.o + +all: $(LIB) + +%.o: %.cpp + $(CX) -c $(CFLAGS) $< -o $@ + +$(LIB): $(OBJS) + rm -f $(LIB) + $(AR) rcs $(LIB) $(OBJS) +clean: + rm -f *.o $(LIB) +.PHONY: all clean diff --git a/lib/hack.c b/lib/hack.c new file mode 100644 index 0000000..424a92f --- /dev/null +++ b/lib/hack.c @@ -0,0 +1,350 @@ +#include "libwasm.h" + +size_t strlen (const char *s) { + size_t l = 0; + while (*s++) l++; + return l; +} +char *strncpy (char *dst0, const char *src0, size_t count) { + char *dscan; + const char *sscan; + + dscan = dst0; + sscan = src0; + while (count > 0) { + --count; + if ((*dscan++ = *sscan++) == '\0') + break; + } + while (count-- > 0) + *dscan++ = '\0'; + + return dst0; +} +int strncmp (const char *s1, const char *s2, size_t n) { + if (n == 0) return 0; + while (n-- != 0 && *s1 == *s2) { + if (n == 0 || *s1 == '\0') break; + s1++; + s2++; + } + return (* (unsigned char *) s1) - (* (unsigned char *) s2); +} +int strcmp (const char *s1, const char *s2) { + while (*s1 != '\0' && *s1 == *s2) { + s1++; + s2++; + } + return (* (unsigned char *) s1) - (* (unsigned char *) s2); +} + +void *memcpy (void *dest, const void *src, size_t n) { + const char *s = (const char *) src; + char *d = (char *) dest; + int i; + for (i=0; i 0) { + num = PutUnsignedInt (pStr, fill, width, value / 10); + pStr += num; + } + // Write filler characters + else { + while (width > 0) { + PutChar (pStr, fill); + pStr++; + num++; + width--; + } + } + // Write lower digit + num += PutChar (pStr, (value % 10) + '0'); + return num; +} + +////------------------------------------------------------------------------------ +/// Writes a signed int inside the given string, using the provided fill & width +/// parameters. +/// Returns the size of the written integer. +/// \param pStr Storage string. +/// \param fill Fill character. +/// \param width Minimum integer width. +/// \param value Signed integer value. +////------------------------------------------------------------------------------ +static signed int PutSignedInt ( + char *pStr, + char fill, + signed int width, + signed int value) { + signed int num = 0; + unsigned int absolute; + // Compute absolute value + if (value < 0) { + absolute = -value; + } else { + absolute = value; + } + // Take current digit into account when calculating width + width--; + // Recursively write upper digits + if ( (absolute / 10) > 0) { + if (value < 0) { + num = PutSignedInt (pStr, fill, width, - (absolute / 10)); + } else { + num = PutSignedInt (pStr, fill, width, absolute / 10); + } + pStr += num; + } else { + // Reserve space for sign + if (value < 0) { + width--; + } + // Write filler characters + while (width > 0) { + PutChar (pStr, fill); + pStr++; + num++; + width--; + } + // Write sign + if (value < 0) { + num += PutChar (pStr, '-'); + pStr++; + } + } + // Write lower digit + num += PutChar (pStr, (absolute % 10) + '0'); + return num; +} + +//------------------------------------------------------------------------------ +/// Writes an hexadecimal value into a string, using the given fill, width & +/// capital parameters. +/// Returns the number of char written. +/// \param pStr Storage string. +/// \param fill Fill character. +/// \param width Minimum integer width. +/// \param maj Indicates if the letters must be printed in lower- or upper-case. +/// \param value Hexadecimal value. +//------------------------------------------------------------------------------ +static signed int PutHexa ( + char *pStr, + char fill, + signed int width, + unsigned char maj, + unsigned int value) { + signed int num = 0; + // Decrement width + width--; + // Recursively output upper digits + if ( (value >> 4) > 0) { + num += PutHexa (pStr, fill, width, maj, value >> 4); + pStr += num; + } + // Write filler chars + else { + while (width > 0) { + PutChar (pStr, fill); + pStr++; + num++; + width--; + } + } + // Write current digit + if ( (value & 0xF) < 10) { + PutChar (pStr, (value & 0xF) + '0'); + } else if (maj) { + PutChar (pStr, (value & 0xF) - 10 + 'A'); + } else { + PutChar (pStr, (value & 0xF) - 10 + 'a'); + } + num++; + return num; +} +static signed int PutPointer (char * pStr, void * ptr) { + int num = PutString(pStr, "0x"); + pStr += num; + num += PutHexa(pStr, '0', 8, 0, (unsigned int) ptr); + return num; +} + +signed int vsnprintf (char *pStr, size_t length, const char *pFormat, va_list ap) { + char fill; + unsigned char width; + signed int num = 0; + signed int size = 0; + // Clear the string + if (pStr) { * pStr = 0; } + // Phase string + while (*pFormat != 0 && size < length) { + // Normal character + if (*pFormat != '%') { + *pStr++ = *pFormat++; + size++; + } else if (* (pFormat + 1) == '%') { // Escaped '%' + *pStr++ = '%'; + pFormat += 2; + size++; + } else { // Token delimiter + fill = ' '; + width = 0; + pFormat++; + if (*pFormat == '0') { // Parse filler + fill = '0'; + pFormat++; + } + while ((*pFormat >= '0') && (*pFormat <= '9')) { // Parse width + width = (width * 10) + *pFormat - '0'; + pFormat++; + } + // Check if there is enough space + if (size + width > length) { + width = length - size; + } + // Parse type +type_spec: + switch (*pFormat) { + case 'z': // modifikatory z,l jsou zbytečné - size long a int jsou stejne + case 'l': + pFormat++; + goto type_spec; + case 'd': + case 'i': + num = PutSignedInt (pStr, fill, width, va_arg (ap, signed int)); + break; + case 'u': + num = PutUnsignedInt (pStr, fill, width, va_arg (ap, unsigned int)); + break; + case 'x': + num = PutHexa (pStr, fill, width, 0, va_arg (ap, unsigned int)); + break; + case 'X': + num = PutHexa (pStr, fill, width, 1, va_arg (ap, unsigned int)); + break; + case 's': + num = PutString (pStr, va_arg (ap, char *)); + break; + case 'c': + num = PutChar (pStr, va_arg (ap, unsigned int)); + break; + case 'p': + num = PutPointer (pStr, va_arg (ap, void *)); + break; + default: + return 0; + } + pFormat++; + pStr += num; + size += num; + } + } + // NULL-terminated (final \0 is not counted) + if (size < length) { + *pStr = 0; + } else { + * (--pStr) = 0; + size--; + } + return size; +} diff --git a/lib/heap.c b/lib/heap.c new file mode 100644 index 0000000..3379708 --- /dev/null +++ b/lib/heap.c @@ -0,0 +1,127 @@ +#include "libwasm.h" +extern void IMPORT(memoryGrow) (const int block); +extern char __heap_base; + +static const char * _HEAP_START = &__heap_base; +char * _HEAP_MAX = &__heap_base; +#define NULL ((void *)0) +typedef unsigned long ALIGN; + +union header { + struct { + union header * ptr; + unsigned long size; + } s; + ALIGN x; +}; + +typedef union header HEADER; + +static HEADER base; +static HEADER * allocp = NULL; + +#define NALLOC 64 + +static HEADER * morecore (unsigned long); +/* K&R allocator */ +void * malloc (unsigned long nbytes) { + HEADER *p, *q; // K&R called q, prevp + unsigned nunits; + + nunits = (nbytes + sizeof (HEADER) - 1) / sizeof (HEADER) + 1; + + if ((q = allocp) == NULL) { // no free list yet + base.s.ptr = allocp = q = &base; + base.s.size = 0; + } + for (p = q->s.ptr;; q = p, p = p->s.ptr) { + if (p->s.size >= nunits) { // big enough + if (p->s.size == nunits) // exactly + q->s.ptr = p->s.ptr; + else { // allocate tail end + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + allocp = q; + return ((char *) (p + 1)); + } + if (p == allocp) { + if ((p = morecore (nunits)) == NULL) return NULL; + } + } +} +void free (void *ap) { + HEADER *p, *q; + p = (HEADER *) ap - 1; + for (q = allocp; ! (p > q && p < q->s.ptr); q = q->s.ptr) + if (q >= q->s.ptr && (p > q || p < q->s.ptr)) + break; + + if (p + p->s.size == q->s.ptr) { + p->s.size += q->s.ptr->s.size; + p->s.ptr = q->s.ptr->s.ptr; + } else + p->s.ptr = q->s.ptr; + if (q + q->s.size == p) { + q->s.size += p->s.size; + q->s.ptr = p->s.ptr; + } else + q->s.ptr = p; + allocp = q; +} + +static void * sbrk (unsigned long size) { + static const char * heap_ptr; + const char * old_heap_ptr; + static unsigned int init_sbrk = 0; + /* heap_ptr is initialized to HEAP_START */ + if (init_sbrk == 0) { + heap_ptr = _HEAP_START; + init_sbrk = 1; + } + old_heap_ptr = heap_ptr; + /* Tohle je jen zkusmo, uvidíme, zatím se zdá, že to chodí. + * Těžko říct, co to udělá, když dojde paměť, ale pár MiB to zvládne. + */ + if ((heap_ptr + size) > _HEAP_MAX) { + const int blocks = (((heap_ptr + size) - _HEAP_MAX) >> 16) + 1; + memoryGrow (blocks); + _HEAP_MAX += blocks << 16; + } + heap_ptr += size; + return (void *)old_heap_ptr; +} + +static HEADER * morecore (unsigned long nu) { + char * cp; + HEADER * up; + int rnu; + + rnu = NALLOC * ((nu + NALLOC - 1) / NALLOC); + //printf("morecore %ld units, %d rnu\n", nu, rnu); + cp = sbrk (rnu * sizeof (HEADER)); + if (cp == NULL) return NULL; + up = (HEADER *) cp; + up->s.size = rnu; + free ((char *) (up + 1)); + return (allocp); +} +void* calloc (unsigned long nmemb, unsigned long size) { + unsigned long i, req = nmemb * size; + if (!req) req++; + void* res = malloc(req); + char* clr = (char*) res; + for (i=0; i +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus +// "imports" odpovídá importObject.imports v JS, default je to importObject.env +#define IMPORT(name) __attribute__((import_module("imports"),import_name(#name))) name +#define EXPORT(name) __attribute__((used, export_name(#name))) name +void * malloc (unsigned long n); +void free (void * p); +extern char * _HEAP_MAX; +/** Pozor - vše je _velmi_ zjednodušeno. Zase je to docela malé. + * fmt v printf a vsnprintf umí jen (unsigned) int formáty + * */ + extern void * calloc (unsigned long nmemb, unsigned long size); + extern void * realloc(void *ptr, unsigned long size); + + typedef __SIZE_TYPE__ size_t; + #define NULL ((void *)0) + size_t strlen (const char *s); + extern char * strncpy (char *dst0, const char *src0, size_t count); + extern int strncmp (const char *s1, const char *s2, size_t n); + extern int strcmp (const char *s1, const char *s2); + extern void * memcpy (void *dest, const void *src, size_t n); + extern void * memset (void *s, int c, size_t n); + extern char * strtok (char *s, const char *delim); + + extern signed int vsnprintf (char *pStr, size_t length, const char *fmt, va_list ap); + extern signed int snprintf (char *pStr, size_t length, const char *fmt, ...); + extern int puts (const char * ptr); + extern int printf (const char *__restrict fmt, ...) __attribute__((__format__(__printf__, 1, 2))); + + extern double exp (const double a); + extern double sqrt (const double a); + extern double fabs (const double a); +#ifdef __cplusplus +}; +#endif //__cplusplus +#endif // MY_EMLIB_H diff --git a/lib/math.c b/lib/math.c new file mode 100644 index 0000000..fcb6588 --- /dev/null +++ b/lib/math.c @@ -0,0 +1,44 @@ +#include "libwasm.h" + +#define EULER 2.7182818284 +#define EPS 1.0e-9 + +double exp(const double a) { + if (a < 0.0) return 1.0 / exp (-a); + int ip = a; + const double dp = a - ip; + double result = 1.0, m = dp, f = 1.0, s = 1.0; + for (;;) { + const double e = m / f; + result += e; + if (e < EPS) break; + m *= dp; + s += 1.0; + f *= s; + } + m = EULER; + for (;;) { + const int n = ip & 1; + if (n) result *= m; + ip >>= 1; + if (!ip) break; + m *= m; + } + return result; +} +double fabs (const double a) { + if (a < 0.0) return -a; + return a; +} +double sqrt(const double a) { + if (a <= 0.0) return 0; + double x = a; + double root; + while (1) { + root = 0.5 * (x + (a / x)); + if (fabs(root - x) < EPS) break; + x = root; + } + return root; +} + diff --git a/lib/newdel.cpp b/lib/newdel.cpp new file mode 100644 index 0000000..dcdd4db --- /dev/null +++ b/lib/newdel.cpp @@ -0,0 +1,23 @@ +#include "libwasm.h" + + +void* operator new (unsigned long size) { + return calloc(1,size); +} +void operator delete (void* p) { + free (p); +} + +void* operator new[] (unsigned long size) { + return calloc(1,size); +} + +void operator delete[] (void* p) { + free (p); +} + +void operator delete (void* p, unsigned size) { + (void) size; + free (p); +} + diff --git a/lib/printf.c b/lib/printf.c new file mode 100644 index 0000000..c86feb0 --- /dev/null +++ b/lib/printf.c @@ -0,0 +1,32 @@ +#include "libwasm.h" +extern void IMPORT(PrintOut) (const char * ptr, const int len); // external javascript function +int puts (const char * ptr) { + const int len = strlen (ptr); + char * out = malloc (len); + strncpy(out, ptr, len); + PrintOut (out, len); + free (out); + return len; +} +#define MAXSTRINGSIZE 0x1000 +int printf (const char *fmt, ...) { + char * p = malloc(MAXSTRINGSIZE); + va_list ap; + va_start(ap, fmt); + int size = vsnprintf(p, MAXSTRINGSIZE, fmt, ap); + va_end(ap); + if (size < 0) return 0; + p [size] = '\0'; + PrintOut(p, size); + free(p); + return size; +} +signed int snprintf (char *pStr, size_t length, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int size = vsnprintf(pStr, length, fmt, ap); + va_end(ap); + if (size < 0) return 0; + pStr [size] = '\0'; + return size; +} diff --git a/osc/Makefile b/osc/Makefile new file mode 100644 index 0000000..062cb78 --- /dev/null +++ b/osc/Makefile @@ -0,0 +1,34 @@ +PR = ../bin/oscilator.wasm +VPATH = . +CC = clang +CX = clang++ +# V Ubuntu 20.04 není v default LLVM wasm-ld, jinak by šlo použít clang jako ld +LD = wasm-ld-10 +TARGET = --target=wasm32-unknown-unknown + +OBJS = main.o canvas.o complex.o drawings.o +#OBJS += +CFLAGS = -Wall -Oz -flto $(TARGET) -I. -I../lib +CFLAGS+= -ffunction-sections -fdata-sections +#CFLAGS+= -Wno-incompatible-library-redeclaration +# Pro clang by muselo ještě přibýt -nostartfiles $(TARGET) a flagy by byly -Wl, +LFLAGS = --no-entry --import-memory --lto-O3 --gc-sections +LFLAGS+= --print-gc-sections +#LFLAGS+= --export-all +# vetsi stack znamena zvetsit i WebAssembly.Memory({ initial: n 64K block }) +#LFLAGS+= -z stack-size=65536 +#LFLAGS+= --allow-undefined +LFLAGS+= --allow-undefined-file=symbols.txt +LDLIBS = -L../lib -lWASM + +all: $(PR) +%.o: %.cpp + $(CX) -std=c++14 -c $(CFLAGS) -fno-exceptions -fno-rtti $< -o $@ +%.o: %.c + $(CC) -c $(CFLAGS) $< -o $@ +$(PR): $(OBJS) ../lib/libWASM.a + $(LD) $(LFLAGS) $(OBJS) -o $(PR) $(LDLIBS) +../lib/libWASM.a: + cd ../lib && $(MAKE) all +clean: + rm -f *.o diff --git a/osc/canvas.cpp b/osc/canvas.cpp new file mode 100644 index 0000000..13bdb4e --- /dev/null +++ b/osc/canvas.cpp @@ -0,0 +1,93 @@ +/*#include "math.h" +#include +#include */ +#include "canvas.h" +int round (const double a) { + return int (a + 0.5); +} + +Canvas::Canvas(const int w, const int h) : width(w), height(h), + outpixel(0u), current(0xFF000000), matrix (1.0, 0.0, 0.0, -1.0, 0.5 * (real) w, 0.5 * (real) (h)) { + data = new Color [w * h]; +} + +Canvas::~Canvas() { + delete [] data; +} +void Canvas::fill (const Color & c) { + for (int y=0; y= width) return false; + if (y >= height) return false; + return true; +} +void Canvas::line (const int xp, const int yp, const int xe, const int ye, const bool doted) { + bool dot = true; + int x1 = xp, y1 = yp; + const int x2 = xe, y2 = ye; + bool done = false; + int mx = 0, my = 0; + // Determine direction and distance + const int xd = (x1 < x2) ? 1 : -1; + const int yd = (y1 < y2) ? 1 : -1; + const int xl = (x1 < x2) ? (x2 - x1) : (x1 - x2); + const int yl = (y1 < y2) ? (y2 - y1) : (y1 - y2); + while (!done) { + if (x1 == x2 && y1 == y2) done = true; + if (dot) at(x1,y1) = current; // Plot pixel + if (doted) dot = !dot; + mx += xl; + if (x1 != x2 && mx > yl) x1 += xd, mx -= yl; + my += yl; + if (y1 != y2 && my > xl) y1 += yd, my -= xl; + } +} +void Canvas::rect (const int x0, const int y0, const int x1, const int y1) { + for (int y=y0; y ms) break; + } +} +void Canvas::setMatrix (const Matrix& m) { + matrix = m; +} diff --git a/osc/canvas.h b/osc/canvas.h new file mode 100644 index 0000000..b7fcc99 --- /dev/null +++ b/osc/canvas.h @@ -0,0 +1,69 @@ +#ifndef CANVAS_H +#define CANVAS_H +#include +//#include +typedef __SIZE_TYPE__ size_t; + +typedef double real; +/** + * Velmi jednoduché kreslení úseček a kruhů. + */ +struct FPoint { + real x,y; + FPoint () : x(0), y(0) {}; + FPoint (const real x0, const real y0) : x(x0), y(y0) {}; + FPoint (const FPoint & other) : x(other.x), y(other.y) {}; + FPoint & operator= (const FPoint & other) { x = other.x; y = other.y; return * this; }; +}; +class Matrix { + real m11, m12, m21, m22, ox, oy; + public: + Matrix (const real a11 = 1.0, const real a12 = 0.0, const real a21 = 0.0, const real a22 = -1.0, const real ax = 0, const real ay = 0) : + m11(a11), m12(a12), m21(a21), m22(a22), ox(ax), oy(ay) {}; + const FPoint operator* (const FPoint & right) const { + const real x = m11 * right.x + m12 * right.y + ox; + const real y = m21 * right.x + m22 * right.y + oy; + const FPoint result (x, y); + return result; + } +}; + +union Color { + struct { + uint8_t r,g,b,a; + }; + uint32_t color; + Color () {color = 0u; }; + Color (const uint8_t rr, const uint8_t gg, const uint8_t bb, const uint8_t aa = 0xFF) : r(rr), g(gg), b(bb), a(aa) {}; + Color (const uint32_t c) : color(c) {}; + Color (const Color & other) { color = other.color; }; + Color & operator= (const Color & other) { color = other.color; return * this; }; + operator uint32_t () const { return color; }; +}; + +class Canvas { + const int width, height; + Color outpixel; + Color current; + Matrix matrix; + Color * data; + public: + Canvas (const int w, const int h); + ~Canvas(); + uint8_t * getData () const { return reinterpret_cast(data); }; + size_t getSize () const { return (width * height * sizeof(Color)); }; + int getMaxX () const { return width; }; + int getMaxY () const { return height; }; + void setMatrix (const Matrix & m); + void fill (const Color & c); + void setColor (const Color & c) { current = c; }; + void line (const FPoint & begin, const FPoint & end, const bool doted = false); + void circ (const FPoint & center, const real radius); + protected: + Color & at (const int x, const int y); + bool bound (const int x, const int y) const; + void line (const int x0, const int y0, const int x1, const int y1, const bool doted = false); + void rect (const int x0, const int y0, const int x1, const int y1); +}; + +#endif // CANVAS_H diff --git a/osc/complex.cpp b/osc/complex.cpp new file mode 100644 index 0000000..59e4e69 --- /dev/null +++ b/osc/complex.cpp @@ -0,0 +1,56 @@ +#include "complex.h" + +static const double common_table [] = { + +0.00000000, +0.02454123, +0.04906767, +0.07356456, +0.09801714, +0.12241068, +0.14673047, +0.17096189, + +0.19509032, +0.21910124, +0.24298018, +0.26671276, +0.29028468, +0.31368174, +0.33688985, +0.35989504, + +0.38268343, +0.40524131, +0.42755509, +0.44961133, +0.47139674, +0.49289819, +0.51410274, +0.53499762, + +0.55557023, +0.57580819, +0.59569930, +0.61523159, +0.63439328, +0.65317284, +0.67155895, +0.68954054, + +0.70710678, +0.72424708, +0.74095113, +0.75720885, +0.77301045, +0.78834643, +0.80320753, +0.81758481, + +0.83146961, +0.84485357, +0.85772861, +0.87008699, +0.88192126, +0.89322430, +0.90398929, +0.91420976, + +0.92387953, +0.93299280, +0.94154407, +0.94952818, +0.95694034, +0.96377607, +0.97003125, +0.97570213, + +0.98078528, +0.98527764, +0.98917651, +0.99247953, +0.99518473, +0.99729046, +0.99879546, +0.99969882, + +1.00000000, +0.99969882, +0.99879546, +0.99729046, +0.99518473, +0.99247953, +0.98917651, +0.98527764, + +0.98078528, +0.97570213, +0.97003125, +0.96377607, +0.95694034, +0.94952818, +0.94154407, +0.93299280, + +0.92387953, +0.91420976, +0.90398929, +0.89322430, +0.88192126, +0.87008699, +0.85772861, +0.84485357, + +0.83146961, +0.81758481, +0.80320753, +0.78834643, +0.77301045, +0.75720885, +0.74095113, +0.72424708, + +0.70710678, +0.68954054, +0.67155895, +0.65317284, +0.63439328, +0.61523159, +0.59569930, +0.57580819, + +0.55557023, +0.53499762, +0.51410274, +0.49289819, +0.47139674, +0.44961133, +0.42755509, +0.40524131, + +0.38268343, +0.35989504, +0.33688985, +0.31368174, +0.29028468, +0.26671276, +0.24298018, +0.21910124, + +0.19509032, +0.17096189, +0.14673047, +0.12241068, +0.09801714, +0.07356456, +0.04906767, +0.02454123, + +0.00000000, -0.02454123, -0.04906767, -0.07356456, -0.09801714, -0.12241068, -0.14673047, -0.17096189, + -0.19509032, -0.21910124, -0.24298018, -0.26671276, -0.29028468, -0.31368174, -0.33688985, -0.35989504, + -0.38268343, -0.40524131, -0.42755509, -0.44961133, -0.47139674, -0.49289819, -0.51410274, -0.53499762, + -0.55557023, -0.57580819, -0.59569930, -0.61523159, -0.63439328, -0.65317284, -0.67155895, -0.68954054, + -0.70710678, -0.72424708, -0.74095113, -0.75720885, -0.77301045, -0.78834643, -0.80320753, -0.81758481, + -0.83146961, -0.84485357, -0.85772861, -0.87008699, -0.88192126, -0.89322430, -0.90398929, -0.91420976, + -0.92387953, -0.93299280, -0.94154407, -0.94952818, -0.95694034, -0.96377607, -0.97003125, -0.97570213, + -0.98078528, -0.98527764, -0.98917651, -0.99247953, -0.99518473, -0.99729046, -0.99879546, -0.99969882, + -1.00000000, -0.99969882, -0.99879546, -0.99729046, -0.99518473, -0.99247953, -0.98917651, -0.98527764, + -0.98078528, -0.97570213, -0.97003125, -0.96377607, -0.95694034, -0.94952818, -0.94154407, -0.93299280, + -0.92387953, -0.91420976, -0.90398929, -0.89322430, -0.88192126, -0.87008699, -0.85772861, -0.84485357, + -0.83146961, -0.81758481, -0.80320753, -0.78834643, -0.77301045, -0.75720885, -0.74095113, -0.72424708, + -0.70710678, -0.68954054, -0.67155895, -0.65317284, -0.63439328, -0.61523159, -0.59569930, -0.57580819, + -0.55557023, -0.53499762, -0.51410274, -0.49289819, -0.47139674, -0.44961133, -0.42755509, -0.40524131, + -0.38268343, -0.35989504, -0.33688985, -0.31368174, -0.29028468, -0.26671276, -0.24298018, -0.21910124, + -0.19509032, -0.17096189, -0.14673047, -0.12241068, -0.09801714, -0.07356456, -0.04906767, -0.02454123, + -0.00000000, +0.02454123, +0.04906767, +0.07356456, +0.09801714, +0.12241068, +0.14673047, +0.17096189, + +0.19509032, +0.21910124, +0.24298018, +0.26671276, +0.29028468, +0.31368174, +0.33688985, +0.35989504, + +0.38268343, +0.40524131, +0.42755509, +0.44961133, +0.47139674, +0.49289819, +0.51410274, +0.53499762, + +0.55557023, +0.57580819, +0.59569930, +0.61523159, +0.63439328, +0.65317284, +0.67155895, +0.68954054, + +0.70710678, +0.72424708, +0.74095113, +0.75720885, +0.77301045, +0.78834643, +0.80320753, +0.81758481, + +0.83146961, +0.84485357, +0.85772861, +0.87008699, +0.88192126, +0.89322430, +0.90398929, +0.91420976, + +0.92387953, +0.93299280, +0.94154407, +0.94952818, +0.95694034, +0.96377607, +0.97003125, +0.97570213, + +0.98078528, +0.98527764, +0.98917651, +0.99247953, +0.99518473, +0.99729046, +0.99879546, +0.99969882 +}; +static const double * sintab = common_table; +static const double * costab = common_table + 64; + +complex::complex(const double x, const double y) : re(x), im(y) { + +} +complex & complex::exp (const unsigned int n) { + const unsigned a = n & 0xFF; + re = costab [a]; + im = sintab [a]; + return * this; +} diff --git a/osc/complex.h b/osc/complex.h new file mode 100644 index 0000000..edc1a00 --- /dev/null +++ b/osc/complex.h @@ -0,0 +1,23 @@ +#ifndef COMPLEX_H +#define COMPLEX_H + +class complex { + public: + double re, im; + public: + complex (const double x=0.0, const double y=0.0); + complex & operator*= (const double a) { + re *= a; im *= a; + return * this; + } + complex & operator+= (const complex & a) { + re += a.re; im += a.im; + return * this; + } + complex & exp (const unsigned n); + double abs () const { + return re * re + im * im; + } +}; + +#endif // COMPLEX_H diff --git a/osc/drawings.cpp b/osc/drawings.cpp new file mode 100644 index 0000000..40077be --- /dev/null +++ b/osc/drawings.cpp @@ -0,0 +1,106 @@ +#include "libwasm.h" +#include "drawings.h" +#include "complex.h" + +//using namespace std; + + +/*********************************************************************************/ +void BackGround::drawings() { + const real maxx = getMaxX(), maxy = getMaxY(); + fill (Color(0, 0, 0, 0xFF)); + + const real hx = 0.5 * maxx, margin = 5.0; + const Matrix m (hx-2.0*margin, 0.0, 0.0, -(maxy-2*margin), hx, maxy - margin); + setMatrix (m); + setColor (Color (0x60, 0x60, 0x60)); + const real st = 0.1; + for (real x=-1.0; x<+1.0; x+=st) { + line (FPoint(+x,-1.0), FPoint(+x,+1.0), true); + } + for (real y=st; y<1.0; y+=st) { + line (FPoint(-1.0,+y), FPoint(+1.0,+y), true); + } + setColor (Color (0x80, 0x80, 0)); + line (FPoint(-1.0, 0.0), FPoint(1.0, 0.0)); + line (FPoint( 0.0, 0.0), FPoint(0.0, 1.0)); + FPoint o (-1.0, 1.0); + setColor (Color (0xFF, 0xFF, 0)); + for (real x=-1.0; x<+1.0; x+=0.05) { + const real y = x * x; + FPoint n (x, y); + line (o, n); + o = n; + } +} +/////////////////////////////////////////////////////////////////////////////////// +void ForeGround::drawings() { + const real maxx = getMaxX(), maxy = getMaxY(); + fill (Color(0xFF, 0xFF, 0xFF, 0)); + const real hx = 0.5 * maxx, margin = 5.0, zx = hx - 2.0 * margin, ix = 1.0 / zx; + const Matrix m (zx, 0.0, 0.0, -(maxy - 2 * margin), hx, maxy - margin); + setMatrix (m); + const double w = 6.0; + for (real a=-1.0; a<+1.0; a+=ix) { + const double x = w * a; + const double y = probality (x); + const double cz = y * 255.0; + int c = 0; + if (cz > 255.0) c = 0xFF; + else if (cz < 0.0) c = 0; + else c = cz; + setColor (Color(c, 0xFF -c, 0xFF - c, 0xE0)); + line (FPoint (a, 0.0), FPoint (a, y)); + } +} +/** + * Výpočty vlnových funkcí viz + * https://www.aldebaran.cz/studium/tf.pdf str. 142, + * časový vývoj tamtéž str. 182, výraz (2.183) + * */ +double ForeGround::probality (const double x) const { + double H [NumWeight]; // Hermitovy polynomy + H [0] = 1.0; + H [1] = 2.0 * x; + for (unsigned n=2; n + y *= fac; // |Ψ> + psi += y; // sčítají se komplexní vlnové funkce + } + return psi.abs(); // vrací se <Ψ*|Ψ> +} +void ForeGround::normalize() { + index = 0; speed = 1u; + double fact = 1.0, pow2 = 1.0; + const double hp = sqrt (M_PI); + for (unsigned n=0; n je pro všechna |n> stejná (mělo by být 1) + normals [n] = 1.0 / sqrt (hp * fact * pow2); + const double m = n + 1; + fact *= m; + pow2 *= 2.0; + } +} +void ForeGround::step() { + drawings(); + phase(); + index += speed; +} +void ForeGround::phase() { + complex c, o (-0.8, 0.9); + c.exp (index); + c *= 0.1; + c += o; + const FPoint a (o.re, o.im), b (c.re, c.im); + setColor (Color(0xFF, 0x80, 0, 0xFF)); + line (a, b); +} diff --git a/osc/drawings.h b/osc/drawings.h new file mode 100644 index 0000000..b04dab0 --- /dev/null +++ b/osc/drawings.h @@ -0,0 +1,59 @@ +#ifndef ELEMENT_H +#define ELEMENT_H +/* +#include +#include +#include */ +#include "canvas.h" + +static constexpr unsigned NumWeight = 10; +static constexpr double M_PI = 3.1415926; + +class BackGround : public Canvas { + public: + BackGround (const int w, const int h) : Canvas (w, h) {}; + virtual ~BackGround (){}; + void drawings (); +}; +class ForeGround : public Canvas { + unsigned index, speed; + double weights [NumWeight]; + double normals [NumWeight]; + public: + ForeGround (const int w, const int h) : Canvas (w, h) { + normalize (); + }; + virtual ~ForeGround (){}; + void drawings (); + void setWeight (const int n, const int w) { + weights [n] = (double) w * 0.01; + } + void changeSpeed (int s) { speed = s; }; + void step (); + void reset () { + index = 0; + } + protected: + double probality (const double x) const; + void normalize (); + void phase (); +}; +struct CommonPlots { + int maxx, maxy; + bool StartStop; + BackGround * bg; + ForeGround * fg; + CommonPlots (const int w, const int h) : maxx (w), maxy(h) { + bg = new BackGround (w,h); + fg = new ForeGround (w,h); + bg->drawings(); + fg->drawings(); + StartStop = false; + } + ~CommonPlots () { + delete bg; + delete fg; + } +}; + +#endif // ELEMENT_H diff --git a/osc/main.cpp b/osc/main.cpp new file mode 100644 index 0000000..203963e --- /dev/null +++ b/osc/main.cpp @@ -0,0 +1,76 @@ +#include "libwasm.h" +#include "drawings.h" +extern "C" { + extern void __wasm_call_ctors(); + extern void EXPORT(Init) (const int memlen); + extern void EXPORT(setWeight)(const int n, const int val); + extern void EXPORT(setSpeed) (const int n); + extern void EXPORT(graph) (int w, int h); + extern int EXPORT(gEnabled) (); + extern void EXPORT(Reset) (); + + extern void * EXPORT(bg_data)(); + extern void * EXPORT(fg_data)(); + extern void * EXPORT(gStep) (); + +// extern void IMPORT(drawPass) (); +}; + +static CommonPlots * pContainer = nullptr; + +void Init (int memlen) { + _HEAP_MAX = reinterpret_cast (memlen); // před prvním voláním malloc() - může být i v konstruktorech + __wasm_call_ctors(); // nutné volání statických konstruktorů pokud máme statické třídy + printf("Module Init()"); +}; +void setWeight (const int n, const int val) { +//printf ("slider %d to %d\n", n, val); + if (pContainer) { + pContainer->fg->setWeight (n, val); + pContainer->fg->drawings (); + // drawPass (); + } +} +void setSpeed (const int n) { + if (pContainer) pContainer->fg->changeSpeed(n); +} +void graph (int w, int h) { + + if (pContainer) { + delete pContainer; + pContainer = nullptr; + } + pContainer = new CommonPlots (w, h); + + printf("Create pContainer %d x %d\n", w, h); +} +int gEnabled () { + pContainer->StartStop = ! pContainer->StartStop; + return pContainer->StartStop ? 1 : 0; +} +void Reset () { + if (pContainer) pContainer->fg->reset(); +} +struct PtrLen { + void * ptr; + int len; +}; +void * bg_data () { + static PtrLen pl; + pl.ptr = pContainer->bg->getData(); + pl.len = pContainer->bg->getSize(); + return & pl; +} +void * fg_data () { + static PtrLen pl; + pl.ptr = pContainer->fg->getData(); + pl.len = pContainer->fg->getSize(); + return & pl; +} +void * gStep () { + pContainer->fg->step(); + static PtrLen pl; + pl.ptr = pContainer->fg->getData(); + pl.len = pContainer->fg->getSize(); + return & pl; +} diff --git a/osc/symbols.txt b/osc/symbols.txt new file mode 100644 index 0000000..e4f0ffd --- /dev/null +++ b/osc/symbols.txt @@ -0,0 +1,3 @@ +PrintOut +memoryGrow + diff --git a/well/Makefile b/well/Makefile new file mode 100644 index 0000000..5c748ca --- /dev/null +++ b/well/Makefile @@ -0,0 +1,34 @@ +PR = ../bin/well.wasm +VPATH = . +CC = clang +CX = clang++ +# V Ubuntu 20.04 není v default LLVM wasm-ld, jinak by šlo použít clang jako ld +LD = wasm-ld-10 +TARGET = --target=wasm32-unknown-unknown + +OBJS = main.o canvas.o complex.o drawings.o +#OBJS += +CFLAGS = -Wall -Oz -flto $(TARGET) -I. -I../lib +CFLAGS+= -ffunction-sections -fdata-sections +#CFLAGS+= -Wno-incompatible-library-redeclaration +# Pro clang by muselo ještě přibýt -nostartfiles $(TARGET) a flagy by byly -Wl, +LFLAGS = --no-entry --import-memory --lto-O3 --gc-sections +LFLAGS+= --print-gc-sections +#LFLAGS+= --export-all +# vetsi stack znamena zvetsit i WebAssembly.Memory({ initial: n 64K block }) +#LFLAGS+= -z stack-size=65536 +#LFLAGS+= --allow-undefined +LFLAGS+= --allow-undefined-file=symbols.txt +LDLIBS = -L../lib -lWASM + +all: $(PR) +%.o: %.cpp + $(CX) -std=c++14 -c $(CFLAGS) -fno-exceptions -fno-rtti $< -o $@ +%.o: %.c + $(CC) -c $(CFLAGS) $< -o $@ +$(PR): $(OBJS) ../lib/libWASM.a + $(LD) $(LFLAGS) $(OBJS) -o $(PR) $(LDLIBS) +../lib/libWASM.a: + cd ../lib && $(MAKE) all +clean: + rm -f *.o diff --git a/well/canvas.cpp b/well/canvas.cpp new file mode 100644 index 0000000..3cd0f51 --- /dev/null +++ b/well/canvas.cpp @@ -0,0 +1,92 @@ +#include "libwasm.h" +#include "canvas.h" + +int round (const double a) { + return int (a + 0.5); +} + +Canvas::Canvas(const int w, const int h) : width(w), height(h), + outpixel(0u), current(0xFF000000), matrix (1.0, 0.0, 0.0, -1.0, 0.5 * (real) w, 0.5 * (real) (h)) { + data = new Color [w * h]; +} + +Canvas::~Canvas() { + delete [] data; +} +void Canvas::fill (const Color & c) { + for (int y=0; y= width) return false; + if (y >= height) return false; + return true; +} +void Canvas::line (const int xp, const int yp, const int xe, const int ye, const bool doted) { + bool dot = true; + int x1 = xp, y1 = yp; + const int x2 = xe, y2 = ye; + bool done = false; + int mx = 0, my = 0; + // Determine direction and distance + const int xd = (x1 < x2) ? 1 : -1; + const int yd = (y1 < y2) ? 1 : -1; + const int xl = (x1 < x2) ? (x2 - x1) : (x1 - x2); + const int yl = (y1 < y2) ? (y2 - y1) : (y1 - y2); + while (!done) { + if (x1 == x2 && y1 == y2) done = true; + if (dot) at(x1,y1) = current; // Plot pixel + if (doted) dot = !dot; + mx += xl; + if (x1 != x2 && mx > yl) x1 += xd, mx -= yl; + my += yl; + if (y1 != y2 && my > xl) y1 += yd, my -= xl; + } +} +void Canvas::rect (const int x0, const int y0, const int x1, const int y1) { + for (int y=y0; y ms) break; + } +} +void Canvas::setMatrix (const Matrix& m) { + matrix = m; +} diff --git a/well/canvas.h b/well/canvas.h new file mode 100644 index 0000000..d68a31f --- /dev/null +++ b/well/canvas.h @@ -0,0 +1,67 @@ +#ifndef CANVAS_H +#define CANVAS_H +#include + +typedef double real; +/** + * Velmi jednoduché kreslení úseček a kruhů. + */ +struct FPoint { + real x,y; + FPoint () : x(0), y(0) {}; + FPoint (const real x0, const real y0) : x(x0), y(y0) {}; + FPoint (const FPoint & other) : x(other.x), y(other.y) {}; + FPoint & operator= (const FPoint & other) { x = other.x; y = other.y; return * this; }; +}; +class Matrix { + real m11, m12, m21, m22, ox, oy; + public: + Matrix (const real a11 = 1.0, const real a12 = 0.0, const real a21 = 0.0, const real a22 = -1.0, const real ax = 0, const real ay = 0) : + m11(a11), m12(a12), m21(a21), m22(a22), ox(ax), oy(ay) {}; + const FPoint operator* (const FPoint & right) const { + const real x = m11 * right.x + m12 * right.y + ox; + const real y = m21 * right.x + m22 * right.y + oy; + const FPoint result (x, y); + return result; + } +}; + +union Color { + struct { + uint8_t r,g,b,a; + }; + uint32_t color; + Color () {color = 0u; }; + Color (const uint8_t rr, const uint8_t gg, const uint8_t bb, const uint8_t aa = 0xFF) : r(rr), g(gg), b(bb), a(aa) {}; + Color (const uint32_t c) : color(c) {}; + Color (const Color & other) { color = other.color; }; + Color & operator= (const Color & other) { color = other.color; return * this; }; + operator uint32_t () const { return color; }; +}; + +class Canvas { + const int width, height; + Color outpixel; + Color current; + Matrix matrix; + Color * data; + public: + Canvas (const int w, const int h); + ~Canvas(); + uint8_t * getData () const { return reinterpret_cast(data); }; + size_t getSize () const { return (width * height * sizeof(Color)); }; + int getMaxX () const { return width; }; + int getMaxY () const { return height; }; + void setMatrix (const Matrix & m); + void fill (const Color & c); + void setColor (const Color & c) { current = c; }; + void line (const FPoint & begin, const FPoint & end, const bool doted = false); + void circ (const FPoint & center, const real radius); + protected: + Color & at (const int x, const int y); + bool bound (const int x, const int y) const; + void line (const int x0, const int y0, const int x1, const int y1, const bool doted = false); + void rect (const int x0, const int y0, const int x1, const int y1); +}; + +#endif // CANVAS_H diff --git a/well/complex.cpp b/well/complex.cpp new file mode 100644 index 0000000..59e4e69 --- /dev/null +++ b/well/complex.cpp @@ -0,0 +1,56 @@ +#include "complex.h" + +static const double common_table [] = { + +0.00000000, +0.02454123, +0.04906767, +0.07356456, +0.09801714, +0.12241068, +0.14673047, +0.17096189, + +0.19509032, +0.21910124, +0.24298018, +0.26671276, +0.29028468, +0.31368174, +0.33688985, +0.35989504, + +0.38268343, +0.40524131, +0.42755509, +0.44961133, +0.47139674, +0.49289819, +0.51410274, +0.53499762, + +0.55557023, +0.57580819, +0.59569930, +0.61523159, +0.63439328, +0.65317284, +0.67155895, +0.68954054, + +0.70710678, +0.72424708, +0.74095113, +0.75720885, +0.77301045, +0.78834643, +0.80320753, +0.81758481, + +0.83146961, +0.84485357, +0.85772861, +0.87008699, +0.88192126, +0.89322430, +0.90398929, +0.91420976, + +0.92387953, +0.93299280, +0.94154407, +0.94952818, +0.95694034, +0.96377607, +0.97003125, +0.97570213, + +0.98078528, +0.98527764, +0.98917651, +0.99247953, +0.99518473, +0.99729046, +0.99879546, +0.99969882, + +1.00000000, +0.99969882, +0.99879546, +0.99729046, +0.99518473, +0.99247953, +0.98917651, +0.98527764, + +0.98078528, +0.97570213, +0.97003125, +0.96377607, +0.95694034, +0.94952818, +0.94154407, +0.93299280, + +0.92387953, +0.91420976, +0.90398929, +0.89322430, +0.88192126, +0.87008699, +0.85772861, +0.84485357, + +0.83146961, +0.81758481, +0.80320753, +0.78834643, +0.77301045, +0.75720885, +0.74095113, +0.72424708, + +0.70710678, +0.68954054, +0.67155895, +0.65317284, +0.63439328, +0.61523159, +0.59569930, +0.57580819, + +0.55557023, +0.53499762, +0.51410274, +0.49289819, +0.47139674, +0.44961133, +0.42755509, +0.40524131, + +0.38268343, +0.35989504, +0.33688985, +0.31368174, +0.29028468, +0.26671276, +0.24298018, +0.21910124, + +0.19509032, +0.17096189, +0.14673047, +0.12241068, +0.09801714, +0.07356456, +0.04906767, +0.02454123, + +0.00000000, -0.02454123, -0.04906767, -0.07356456, -0.09801714, -0.12241068, -0.14673047, -0.17096189, + -0.19509032, -0.21910124, -0.24298018, -0.26671276, -0.29028468, -0.31368174, -0.33688985, -0.35989504, + -0.38268343, -0.40524131, -0.42755509, -0.44961133, -0.47139674, -0.49289819, -0.51410274, -0.53499762, + -0.55557023, -0.57580819, -0.59569930, -0.61523159, -0.63439328, -0.65317284, -0.67155895, -0.68954054, + -0.70710678, -0.72424708, -0.74095113, -0.75720885, -0.77301045, -0.78834643, -0.80320753, -0.81758481, + -0.83146961, -0.84485357, -0.85772861, -0.87008699, -0.88192126, -0.89322430, -0.90398929, -0.91420976, + -0.92387953, -0.93299280, -0.94154407, -0.94952818, -0.95694034, -0.96377607, -0.97003125, -0.97570213, + -0.98078528, -0.98527764, -0.98917651, -0.99247953, -0.99518473, -0.99729046, -0.99879546, -0.99969882, + -1.00000000, -0.99969882, -0.99879546, -0.99729046, -0.99518473, -0.99247953, -0.98917651, -0.98527764, + -0.98078528, -0.97570213, -0.97003125, -0.96377607, -0.95694034, -0.94952818, -0.94154407, -0.93299280, + -0.92387953, -0.91420976, -0.90398929, -0.89322430, -0.88192126, -0.87008699, -0.85772861, -0.84485357, + -0.83146961, -0.81758481, -0.80320753, -0.78834643, -0.77301045, -0.75720885, -0.74095113, -0.72424708, + -0.70710678, -0.68954054, -0.67155895, -0.65317284, -0.63439328, -0.61523159, -0.59569930, -0.57580819, + -0.55557023, -0.53499762, -0.51410274, -0.49289819, -0.47139674, -0.44961133, -0.42755509, -0.40524131, + -0.38268343, -0.35989504, -0.33688985, -0.31368174, -0.29028468, -0.26671276, -0.24298018, -0.21910124, + -0.19509032, -0.17096189, -0.14673047, -0.12241068, -0.09801714, -0.07356456, -0.04906767, -0.02454123, + -0.00000000, +0.02454123, +0.04906767, +0.07356456, +0.09801714, +0.12241068, +0.14673047, +0.17096189, + +0.19509032, +0.21910124, +0.24298018, +0.26671276, +0.29028468, +0.31368174, +0.33688985, +0.35989504, + +0.38268343, +0.40524131, +0.42755509, +0.44961133, +0.47139674, +0.49289819, +0.51410274, +0.53499762, + +0.55557023, +0.57580819, +0.59569930, +0.61523159, +0.63439328, +0.65317284, +0.67155895, +0.68954054, + +0.70710678, +0.72424708, +0.74095113, +0.75720885, +0.77301045, +0.78834643, +0.80320753, +0.81758481, + +0.83146961, +0.84485357, +0.85772861, +0.87008699, +0.88192126, +0.89322430, +0.90398929, +0.91420976, + +0.92387953, +0.93299280, +0.94154407, +0.94952818, +0.95694034, +0.96377607, +0.97003125, +0.97570213, + +0.98078528, +0.98527764, +0.98917651, +0.99247953, +0.99518473, +0.99729046, +0.99879546, +0.99969882 +}; +static const double * sintab = common_table; +static const double * costab = common_table + 64; + +complex::complex(const double x, const double y) : re(x), im(y) { + +} +complex & complex::exp (const unsigned int n) { + const unsigned a = n & 0xFF; + re = costab [a]; + im = sintab [a]; + return * this; +} diff --git a/well/complex.h b/well/complex.h new file mode 100644 index 0000000..edc1a00 --- /dev/null +++ b/well/complex.h @@ -0,0 +1,23 @@ +#ifndef COMPLEX_H +#define COMPLEX_H + +class complex { + public: + double re, im; + public: + complex (const double x=0.0, const double y=0.0); + complex & operator*= (const double a) { + re *= a; im *= a; + return * this; + } + complex & operator+= (const complex & a) { + re += a.re; im += a.im; + return * this; + } + complex & exp (const unsigned n); + double abs () const { + return re * re + im * im; + } +}; + +#endif // COMPLEX_H diff --git a/well/drawings.cpp b/well/drawings.cpp new file mode 100644 index 0000000..3ccb952 --- /dev/null +++ b/well/drawings.cpp @@ -0,0 +1,120 @@ +#include "libwasm.h" +#include "drawings.h" +#include "complex.h" + + +static constexpr double sincos (const double x, const bool even) { + double result (0.0), element(1.0), divider(0.0); + if (even) { element *= x; divider += 1.0; } + constexpr double eps = 1.0e-9; // maximální chyba výpočtu + const double aa = - (x * x); + for (;;) { + result += element; + if (fabs (element) < eps) break; + divider += 1.0; + double fact = divider; + divider += 1.0; + fact *= divider; + element *= aa / fact; + } + return result; +} + +/*********************************************************************************/ +void BackGround::drawings() { + const real maxx = getMaxX(), maxy = getMaxY(); + fill (Color(0, 0, 0, 0xFF)); + + const real hx = 0.5 * maxx, margin = 5.0; + const Matrix m (hx-2.0*margin, 0.0, 0.0, -(maxy-2*margin), hx, maxy - margin); + setMatrix (m); + setColor (Color (0x60, 0x60, 0x60)); + const real st = 0.1; + for (real x=-1.0; x<+1.0; x+=st) { + line (FPoint(+x,-1.0), FPoint(+x,+1.0), true); + } + for (real y=st; y<1.0; y+=st) { + line (FPoint(-1.0,+y), FPoint(+1.0,+y), true); + } + setColor (Color (0x80, 0x80, 0)); + line (FPoint(-1.0, 0.0), FPoint(1.0, 0.0)); + line (FPoint( 0.0, 0.0), FPoint(0.0, 1.0)); + FPoint o (-1.0, 1.0); + setColor (Color (0xFF, 0xFF, 0)); + /* + for (real x=-1.0; x<+1.0; x+=0.05) { + const real y = x * x; + FPoint n (x, y); + line (o, n); + o = n; + } + */ + line (FPoint (-1.0, 0.0), FPoint (+1.0, 0.0)); + line (FPoint (-1.0, 0.0), FPoint (-1.0, 1.0)); + line (FPoint (+1.0, 0.0), FPoint (+1.0, 1.0)); +} +/////////////////////////////////////////////////////////////////////////////////// +void ForeGround::drawings() { + const real maxx = getMaxX(), maxy = getMaxY(); + fill (Color(0xFF, 0xFF, 0xFF, 0)); + const real hx = 0.5 * maxx, margin = 5.0, zx = hx - 2.0 * margin, ix = 1.0 / zx; + const Matrix m (zx, 0.0, 0.0, -(maxy - 2 * margin), hx, maxy - margin); + setMatrix (m); + for (real a=-1.0; a<+1.0; a+=ix) { + const double y = probality (a); + const double cz = y * 255.0; + int c = 0; + if (cz > 255.0) c = 0xFF; + else if (cz < 0.0) c = 0; + else c = cz; + setColor (Color(c, 0xFF -c, 0xFF - c, 0xE0)); + line (FPoint (a, 0.0), FPoint (a, y)); + } +} +/** + * Výpočty vlnových funkcí viz + * https://en.wikipedia.org/wiki/Quantum_well, + * časový vývoj https://www.aldebaran.cz/studium/tf.pdf str. 182, výraz (2.183) + * */ +static const unsigned EN [NumWeight] = { +//1, 4, 9, 16, 25, 36, 49, 64, 81, 100, // energie roste kvadraticky, ale je to moc divoké + 1, 2, 3, 4, 5, 7, 9, 11, 13, 16, // tohle sice není úplně správně, ale zase se na to dá koukat +}; +double ForeGround::probality (const double x) const { + const double z = 0.5 * (x + 1.0); // jáma je od -1 do 1 + double fz [NumWeight]; + for (unsigned n=0; n + y *= fac; // |Ψ> + psi += y; // sčítají se komplexní vlnové funkce + } + return psi.abs(); // vrací se <Ψ*|Ψ> +} +void ForeGround::step() { + drawings(); + phase(); + index += speed; +} +// jen čárka ukazující fázi základního stavu +void ForeGround::phase() { + complex c, o (-0.8, 0.9); + c.exp (index); + c *= 0.1; + c += o; + const FPoint a (o.re, o.im), b (c.re, c.im); + setColor (Color(0xFF, 0x80, 0, 0xFF)); + line (a, b); +} +void ForeGround::normalize() { + index = 0; speed = 1u; + for (unsigned n=0; ndrawings(); + fg->drawings(); + StartStop = false; + } + ~CommonPlots () { + delete bg; + delete fg; + } +}; + +#endif // ELEMENT_H diff --git a/well/main.cpp b/well/main.cpp new file mode 100644 index 0000000..900e2dc --- /dev/null +++ b/well/main.cpp @@ -0,0 +1,71 @@ +#include "libwasm.h" +#include "drawings.h" +extern "C" { + extern void __wasm_call_ctors(); + extern void EXPORT(Init) (const int memlen); + extern void EXPORT(setWeight)(const int n, const int val); + extern void EXPORT(setSpeed) (const int n); + extern void EXPORT(graph) (int w, int h); + extern int EXPORT(gEnabled) (); + extern void EXPORT(Reset) (); + + extern void * EXPORT(bg_data)(); + extern void * EXPORT(fg_data)(); + extern void * EXPORT(gStep) (); +}; + +static CommonPlots * pContainer = nullptr; + +void Init (const int memlen) { + _HEAP_MAX = reinterpret_cast (memlen); // před prvním voláním malloc() - může být i v konstruktorech + __wasm_call_ctors(); // nutné volání statických konstruktorů pokud máme statické třídy + printf("Module Init()"); +}; +void setWeight (const int n, const int val) { +//printf ("slider %d to %d\n", n, val); + if (pContainer) { + pContainer->fg->setWeight (n, val); + pContainer->fg->drawings (); + } +} +void setSpeed (const int n) { + if (pContainer) pContainer->fg->changeSpeed(n); +} +void graph (int w, int h) { + if (pContainer) { + delete pContainer; + pContainer = nullptr; + } + pContainer = new CommonPlots (w, h); + printf("Create pContainer %d x %d\n", w, h); +} +int gEnabled () { + pContainer->StartStop = ! pContainer->StartStop; + return pContainer->StartStop ? 1 : 0; +} +void Reset () { + if (pContainer) pContainer->fg->reset(); +} +struct PtrLen { + void * ptr; + int len; +}; +void * bg_data () { + static PtrLen pl; + pl.ptr = pContainer->bg->getData(); + pl.len = pContainer->bg->getSize(); + return & pl; +} +void * fg_data () { + static PtrLen pl; + pl.ptr = pContainer->fg->getData(); + pl.len = pContainer->fg->getSize(); + return & pl; +} +void * gStep () { + pContainer->fg->step(); + static PtrLen pl; + pl.ptr = pContainer->fg->getData(); + pl.len = pContainer->fg->getSize(); + return & pl; +} diff --git a/well/symbols.txt b/well/symbols.txt new file mode 100644 index 0000000..e4f0ffd --- /dev/null +++ b/well/symbols.txt @@ -0,0 +1,3 @@ +PrintOut +memoryGrow +