add files

This commit is contained in:
Kizarm 2023-12-16 16:17:02 +01:00
parent 3c917c1e04
commit 3ae526b8b9
26 changed files with 1683 additions and 0 deletions

6
.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
# kdevelop
.kde*
*.kdev4
bin/*
lib/libWASM.a
*.o

21
lib/Makefile Normal file
View file

@ -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

350
lib/hack.c Normal file
View file

@ -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<n; i++) d[i] = s[i];
return dest;
}
void *memset (void *s, int c, size_t n) {
char *p = (char *) s;
int i;
for (i=0; i<n; i++) p[i] = c;
return s;
}
char *strtok (char *s, const char *delim) {
static char *lasts[1];
register char *spanp;
register int c, sc;
char *tok;
if (s == NULL && (s = *lasts) == NULL)
return (NULL);
/*
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
*/
cont:
c = *s++;
for (spanp = (char *) delim; (sc = *spanp++) != 0;) {
if (c == sc) {
if (/*skip_leading_delim*/ 1) {
goto cont;
} else {
*lasts = s;
s[-1] = 0;
return (s - 1);
}
}
}
if (c == 0) { /* no non-delimiter characters */
*lasts = NULL;
return (NULL);
}
tok = s - 1;
/*
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
* Note that delim must have one NUL; we stop if we see that, too.
*/
for (;;) {
c = *s++;
spanp = (char *) delim;
do {
if ( (sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*lasts = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
/* *************************************************************/
//------------------------------------------------------------------------------
/// Writes a character inside the given string. Returns 1.
/// \param pStr Storage string.
/// \param c Character to write.
//------------------------------------------------------------------------------
static signed int PutChar (char *pStr, char c) {
*pStr = c;
return 1;
}
//------------------------------------------------------------------------------
/// Writes a string inside the given string.
/// Returns the size of the written
/// string.
/// \param pStr Storage string.
/// \param pSource Source string.
//------------------------------------------------------------------------------
static signed int PutString (char *pStr, const char *pSource) {
signed int num = 0;
while (*pSource != 0) {
*pStr++ = *pSource++;
num++;
}
return num;
}
//------------------------------------------------------------------------------
/// Writes an unsigned int inside the given string, using the provided fill &
/// width parameters.
/// Returns the size in characters of the written integer.
/// \param pStr Storage string.
/// \param fill Fill character.
/// \param width Minimum integer width.
/// \param value Integer value.
//------------------------------------------------------------------------------
static signed int PutUnsignedInt (
char *pStr,
char fill,
signed int width,
unsigned int value) {
signed int num = 0;
// Take current digit into account when calculating width
width--;
// Recursively write upper digits
if ( (value / 10) > 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;
}

127
lib/heap.c Normal file
View file

@ -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<req; i++) clr[i] = 0;
return res;
}
/// pouze zkraceni, pri prodlozeni to muze cist nekde kde nema
void *realloc(void *ptr, unsigned long size) {
unsigned char* nptr = malloc (size);
unsigned char* optr = (unsigned char*) ptr;
int i;
for (i=0; i<size; i++) nptr[i] = optr[i];
free (ptr);
return (void*) nptr;
}

40
lib/libwasm.h Normal file
View file

@ -0,0 +1,40 @@
#ifndef MY_EMLIB_H
#define MY_EMLIB_H
#include <stdarg.h>
#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

44
lib/math.c Normal file
View file

@ -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;
}

23
lib/newdel.cpp Normal file
View file

@ -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);
}

32
lib/printf.c Normal file
View file

@ -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;
}

34
osc/Makefile Normal file
View file

@ -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

93
osc/canvas.cpp Normal file
View file

@ -0,0 +1,93 @@
/*#include "math.h"
#include <vector>
#include <string>*/
#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<height; y++) {
for (int x=0; x<width; x++) {
at (x, y) = c;
}
}
}
Color & Canvas::at (const int x, const int y) {
if (!bound(x, y)) return outpixel;
const int result = x + y * width;
return data [result];
}
bool Canvas::bound (const int x, const int y) const {
if (x < 0) return false;
if (y < 0) return false;
if (x >= 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<y1; y++) {
for (int x=x0; x<x1; x++) {
at(x, y) = current;
}
}
}
void Canvas::line (const FPoint & begin, const FPoint & end, const bool doted) {
const FPoint b (matrix * begin);
const FPoint e (matrix * end );
const int x0 = (const int) round (b.x);
const int y0 = (const int) round (b.y);
const int x1 = (const int) round (e.x);
const int y1 = (const int) round (e.y);
// printf("%d:%d - %d:%d\n", x0, y0, x1, y1);
line (x0, y0, x1, y1, doted);
}
void Canvas::circ (const FPoint & center, const real radius) {
if (radius == 0) return;
double x = radius, y = 0.0;
const double dx = 1.0 / radius;
const double ms = radius * 6.3;
real count = 0.0;
// kruh se da nakreslit i bez sin a cos, rychle ale trochu nepresne
for (;;) {
x += y * dx; y -= x * dx;
const FPoint e (center.x + x, center.y + y);
const FPoint t (matrix * e);
at ((int) round (t.x), (int) round (t.y)) = current;
count += 1.0;
if (count > ms) break;
}
}
void Canvas::setMatrix (const Matrix& m) {
matrix = m;
}

69
osc/canvas.h Normal file
View file

@ -0,0 +1,69 @@
#ifndef CANVAS_H
#define CANVAS_H
#include <stdint.h>
//#include <stdlib.h>
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<uint8_t*>(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

56
osc/complex.cpp Normal file
View file

@ -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;
}

23
osc/complex.h Normal file
View file

@ -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

106
osc/drawings.cpp Normal file
View file

@ -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<NumWeight; n++) {
const double m = n - 1.0;
H [n] = 2.0 * (x * H [n - 1] - m * H [n - 2]);
}
const double fexp = exp (-0.5 * (x*x));
complex psi;
for (unsigned n=0; n<NumWeight; n++) {
complex y;
y.exp (index * n); // otočení komplexní jednotky - proměnná index představuje čas
const double fac = weights [n] * normals [n] * H [n] * fexp; // |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<NumWeight; n++) {
weights [n] = 0.0;
// Normovací koeficienty zaručí, že <n*|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);
}

59
osc/drawings.h Normal file
View file

@ -0,0 +1,59 @@
#ifndef ELEMENT_H
#define ELEMENT_H
/*
#include <vector>
#include <string>
#include <functional>*/
#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

76
osc/main.cpp Normal file
View file

@ -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<char*> (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;
}

3
osc/symbols.txt Normal file
View file

@ -0,0 +1,3 @@
PrintOut
memoryGrow

34
well/Makefile Normal file
View file

@ -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

92
well/canvas.cpp Normal file
View file

@ -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<height; y++) {
for (int x=0; x<width; x++) {
at (x, y) = c;
}
}
}
Color & Canvas::at (const int x, const int y) {
if (!bound(x, y)) return outpixel;
const int result = x + y * width;
return data [result];
}
bool Canvas::bound (const int x, const int y) const {
if (x < 0) return false;
if (y < 0) return false;
if (x >= 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<y1; y++) {
for (int x=x0; x<x1; x++) {
at(x, y) = current;
}
}
}
void Canvas::line (const FPoint & begin, const FPoint & end, const bool doted) {
const FPoint b (matrix * begin);
const FPoint e (matrix * end );
const int x0 = (const int) round (b.x);
const int y0 = (const int) round (b.y);
const int x1 = (const int) round (e.x);
const int y1 = (const int) round (e.y);
// printf("%d:%d - %d:%d\n", x0, y0, x1, y1);
line (x0, y0, x1, y1, doted);
}
void Canvas::circ (const FPoint & center, const real radius) {
if (radius == 0) return;
double x = radius, y = 0.0;
const double dx = 1.0 / radius;
const double ms = radius * 6.3;
real count = 0.0;
// kruh se da nakreslit i bez sin a cos, rychle ale trochu nepresne
for (;;) {
x += y * dx; y -= x * dx;
const FPoint e (center.x + x, center.y + y);
const FPoint t (matrix * e);
at ((int) round (t.x), (int) round (t.y)) = current;
count += 1.0;
if (count > ms) break;
}
}
void Canvas::setMatrix (const Matrix& m) {
matrix = m;
}

67
well/canvas.h Normal file
View file

@ -0,0 +1,67 @@
#ifndef CANVAS_H
#define CANVAS_H
#include <stdint.h>
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<uint8_t*>(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

56
well/complex.cpp Normal file
View file

@ -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;
}

23
well/complex.h Normal file
View file

@ -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

120
well/drawings.cpp Normal file
View file

@ -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<NumWeight; n++) {
const double a = (double) (n+1) * M_PI * z;
fz [n] = sincos (a, true);
}
complex psi;
for (unsigned n=0; n<NumWeight; n++) {
complex y;
y.exp (index * EN[n]); // otočení komplexní jednotky - proměnná index představuje čas
const double fac = weights [n] * fz [n]; // |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; n<NumWeight; n++) {
weights [n] = 0.0;
}
}

55
well/drawings.h Normal file
View file

@ -0,0 +1,55 @@
#ifndef ELEMENT_H
#define ELEMENT_H
#include "canvas.h"
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];
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 phase ();
void normalize ();
};
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

71
well/main.cpp Normal file
View file

@ -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<char*> (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;
}

3
well/symbols.txt Normal file
View file

@ -0,0 +1,3 @@
PrintOut
memoryGrow