add files
This commit is contained in:
parent
3c917c1e04
commit
3ae526b8b9
26 changed files with 1683 additions and 0 deletions
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
# kdevelop
|
||||
.kde*
|
||||
*.kdev4
|
||||
bin/*
|
||||
lib/libWASM.a
|
||||
*.o
|
21
lib/Makefile
Normal file
21
lib/Makefile
Normal 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
350
lib/hack.c
Normal 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
127
lib/heap.c
Normal 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
40
lib/libwasm.h
Normal 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
44
lib/math.c
Normal 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
23
lib/newdel.cpp
Normal 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
32
lib/printf.c
Normal 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
34
osc/Makefile
Normal 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
93
osc/canvas.cpp
Normal 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
69
osc/canvas.h
Normal 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
56
osc/complex.cpp
Normal 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
23
osc/complex.h
Normal 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
106
osc/drawings.cpp
Normal 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
59
osc/drawings.h
Normal 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
76
osc/main.cpp
Normal 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
3
osc/symbols.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
PrintOut
|
||||
memoryGrow
|
||||
|
34
well/Makefile
Normal file
34
well/Makefile
Normal 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
92
well/canvas.cpp
Normal 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
67
well/canvas.h
Normal 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
56
well/complex.cpp
Normal 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
23
well/complex.h
Normal 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
120
well/drawings.cpp
Normal 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
55
well/drawings.h
Normal 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
71
well/main.cpp
Normal 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
3
well/symbols.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
PrintOut
|
||||
memoryGrow
|
||||
|
Loading…
Reference in a new issue