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