shorepine / tulipcc Goto Github PK
View Code? Open in Web Editor NEWThe Tulip Creative Computer - a portable Python synthesizer for music and graphics
Home Page: https://tulip.computer/
License: Other
The Tulip Creative Computer - a portable Python synthesizer for music and graphics
Home Page: https://tulip.computer/
License: Other
A python or C script to run on a computer with minimal requirements that takes in a PNG file (any kind) and converts it to 256 color RGB332 indexed color with the correct alpha settings. Maybe it asks if you want to dither or find closest color. Maybe it also offers to resize an image. It also should remove big PNG preview chunks that Tulip would ignore.
tulip.circle(4,400,10,10,1) will draw part of the circle where expected but the part offscreen will be drawn elsewhere on screen.
Before more people use it:
The docs say:
(h_res, v_res, h_offscreen_px, v_offscreen_px,
hsync_back_porch, hsync_front_porch, hsync_pulse_width,
vsync_back_porch, vsync_front_porch, vsync_pulse_width) = tulip.timing() # returns current
tulip.timing(1024, 600, 256, 150, 139, 140, 20, 20, 12, 20) # sets, will erase all display RAM
but I get:
tulip.timing()
(1024, 600, 256, 150)
this will crash the desktop app:
tulip.circle(0,0,5,1,1)
any coordinate <= 0 crashes
Double clicking on Tulip CC.app opens the window but it's just a blank blue BG, no TFB.
Running tulip like ./dev/Tulip\ CC.app/Contents/MacOS/tulip
works fine.
It will overflow the space we have on the partition, but it might be helpful
I can probably help out with this. I might even be able to get it running on Windows via Windows Subsystem for Linux, but I can't make any guarantees about audio performance or USB connectivity.
We should make a tar_create()
to pair with tar_extract()
. I think we can borrow it from cPython's https://github.com/python/cpython/blob/3.11/Lib/tarfile.py
Someone has a usb keyboard with an embedded trackball. Tulip throws errors about the hub and doesn't return key events reliably.
Magical thinking has this getting resolved with an IDF upgrade. #25
No particular challenge, just not done yet
Would be in /ports/macos/virtualmidi.m
import machine
c = 0
def handle(timer):
global c
c+=1
timer = machine.Timer(0)
timer.init(period=1000, mode=machine.Timer.PERIODIC,callback=handle)
crashes with
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x40384448 PS : 0x00060033 A0 : 0x82008826 A1 : 0x3fc9b8b0
0x40384448: vTaskGenericNotifyGiveFromISR at /Users/bwhitman/outside/tulipcc/esp-idf/components/freertos/tasks.c:5818
A2 : 0x00000000 A3 : 0x00000000 A4 : 0x3fc9b8d0 A5 : 0x3fc9b950
A6 : 0x00060423 A7 : 0x00000003 A8 : 0x00000168 A9 : 0x00000168
A10 : 0x00000002 A11 : 0x3fc9e6e4 A12 : 0x00060023 A13 : 0x00060023
A14 : 0x00000004 A15 : 0x0000abab SAR : 0x00000020 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000168 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
Backtrace:0x40384445:0x3fc9b8b00x42008823:0x3fc9b8d0 0x420088cf:0x3fc9b900 0x40376c46:0x3fc9b920 0x420f85eb:0x3fcf5af0 0x4200322f:0x3fcf5b10 0x40382898:0x3fcf5b30
0x40384445: vTaskGenericNotifyGiveFromISR at /Users/bwhitman/outside/tulipcc/esp-idf/components/freertos/tasks.c:5818
0x42008823: mp_hal_wake_main_task_from_isr at /Users/bwhitman/outside/tulipcc/ports/esp32s3/mphalport.c:198
0x420088cf: machine_timer_isr at /Users/bwhitman/outside/tulipcc/ports/esp32s3/machine_timer.c:169
0x40376c46: _xt_lowint1 at /Users/bwhitman/outside/tulipcc/esp-idf/components/freertos/port/xtensa/xtensa_vectors.S:1111
0x420f85eb: cpu_ll_waiti at /Users/bwhitman/outside/tulipcc/esp-idf/components/hal/esp32s3/include/hal/cpu_ll.h:182
(inlined by) esp_pm_impl_waiti at /Users/bwhitman/outside/tulipcc/esp-idf/components/esp_pm/pm_impl.c:837
0x4200322f: esp_vApplicationIdleHook at /Users/bwhitman/outside/tulipcc/esp-idf/components/esp_system/freertos_hooks.c:63
0x40382898: prvIdleTask at /Users/bwhitman/outside/tulipcc/esp-idf/components/freertos/tasks.c:3974
Desktop ./build.sh
creates tulip/amy/src
and tulip/micropython/ports/unix
and puts the .P
files in there. it's harmless but annoying. It looks like the culprit is an arcane regex in micropython/py/mkrules.mk
for .P
files.
Trying to build tulipcc for the first time on an M2 MacBook Air running latest Ventura with the following verbose error. Don't think I missed a step in the setup. Any suggestions?
dean@lucky13 macos % ./build.sh
python3 ../../py/makeversionhdr.py build-standard/genhdr/mpversion.h
GEN build-standard/genhdr/qstr.i.last
python3 ../../py/makeqstrdefs.py pp clang -E output build-standard/genhdr/qstr.i.last cflags -I../../lib/berkeley-db-1.xx/PORT/include -I. -I../.. -Ibuild-standard -I./SDL2.framework/Headers -I./soundio -I../../shared/readline -I../../extmod/tulip -I../../extmod/amy/src/ -Wall -Werror -Wextra -Wno-unused-parameter -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -std=gnu99 -DUNIX -DFFCONF_H=\"lib/oofatfs/ffconf.h\" -DMICROPY_PY_USSL=1 -DMICROPY_SSL_MBEDTLS=1 -I../../lib/mbedtls/include -DMICROPY_PY_BTREE=1 -DMICROPY_USE_READLINE=1 -DMICROPY_PY_TERMIOS=1 -DMICROPY_PY_SOCKET=1 -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0 "-I/usr/local/homebrew/opt/libffi/include" -DMICROPY_PY_FFI=1 -Og -fdata-sections -ffunction-sections -Ivariants/standard -target x86_64-apple-macos10.15 -g -DVIRTUAL_MIDI -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool -DMICROPY_MODULE_FROZEN_MPY -DMPZ_DIG_SIZE=16 -DMICROPY_MODULE_FROZEN_STR -DMICROPY_HW_MCU_NAME="\"`sysctl -n machdep.cpu.brand_string`\"" -Wno-double-promotion -Wno-unused-function -DNO_QSTR cxxflags -I../../lib/berkeley-db-1.xx/PORT/include -I. -I../.. -Ibuild-standard -I./SDL2.framework/Headers -I./soundio -I../../shared/readline -I../../extmod/tulip -I../../extmod/amy/src/ -Wall -Werror -Wextra -Wno-unused-parameter -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -DUNIX -DFFCONF_H=\"lib/oofatfs/ffconf.h\" -DMICROPY_PY_USSL=1 -DMICROPY_SSL_MBEDTLS=1 -I../../lib/mbedtls/include -DMICROPY_PY_BTREE=1 -DMICROPY_USE_READLINE=1 -DMICROPY_PY_TERMIOS=1 -DMICROPY_PY_SOCKET=1 -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0 "-I/usr/local/homebrew/opt/libffi/include" -DMICROPY_PY_FFI=1 -Og -fdata-sections -ffunction-sections -Ivariants/standard -target x86_64-apple-macos10.15 -g -DVIRTUAL_MIDI -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool -DMICROPY_MODULE_FROZEN_MPY -DMPZ_DIG_SIZE=16 -DMICROPY_MODULE_FROZEN_STR -DMICROPY_HW_MCU_NAME="\"`sysctl -n machdep.cpu.brand_string`\"" -Wno-unused-function -DNO_QSTR sources ../../lib/mbedtls/library/aes.c ../../lib/mbedtls/library/aesni.c ../../lib/mbedtls/library/arc4.c ../../lib/mbedtls/library/asn1parse.c ../../lib/mbedtls/library/asn1write.c ../../lib/mbedtls/library/base64.c ../../lib/mbedtls/library/bignum.c ../../lib/mbedtls/library/blowfish.c ../../lib/mbedtls/library/camellia.c ../../lib/mbedtls/library/ccm.c ../../lib/mbedtls/library/certs.c ../../lib/mbedtls/library/chacha20.c ../../lib/mbedtls/library/chachapoly.c ../../lib/mbedtls/library/cipher.c ../../lib/mbedtls/library/cipher_wrap.c ../../lib/mbedtls/library/cmac.c ../../lib/mbedtls/library/ctr_drbg.c ../../lib/mbedtls/library/debug.c ../../lib/mbedtls/library/des.c ../../lib/mbedtls/library/dhm.c ../../lib/mbedtls/library/ecdh.c ../../lib/mbedtls/library/ecdsa.c ../../lib/mbedtls/library/ecjpake.c ../../lib/mbedtls/library/ecp.c ../../lib/mbedtls/library/ecp_curves.c ../../lib/mbedtls/library/entropy.c ../../lib/mbedtls/library/entropy_poll.c ../../lib/mbedtls/library/error.c ../../lib/mbedtls/library/gcm.c ../../lib/mbedtls/library/havege.c ../../lib/mbedtls/library/hmac_drbg.c ../../lib/mbedtls/library/md2.c ../../lib/mbedtls/library/md4.c ../../lib/mbedtls/library/md5.c ../../lib/mbedtls/library/md.c ../../lib/mbedtls/library/md_wrap.c ../../lib/mbedtls/library/oid.c ../../lib/mbedtls/library/padlock.c ../../lib/mbedtls/library/pem.c ../../lib/mbedtls/library/pk.c ../../lib/mbedtls/library/pkcs11.c ../../lib/mbedtls/library/pkcs12.c ../../lib/mbedtls/library/pkcs5.c ../../lib/mbedtls/library/pkparse.c ../../lib/mbedtls/library/pk_wrap.c ../../lib/mbedtls/library/pkwrite.c ../../lib/mbedtls/library/platform.c ../../lib/mbedtls/library/platform_util.c ../../lib/mbedtls/library/poly1305.c ../../lib/mbedtls/library/ripemd160.c ../../lib/mbedtls/library/rsa.c ../../lib/mbedtls/library/rsa_internal.c ../../lib/mbedtls/library/sha1.c ../../lib/mbedtls/library/sha256.c ../../lib/mbedtls/library/sha512.c ../../lib/mbedtls/library/ssl_cache.c ../../lib/mbedtls/library/ssl_ciphersuites.c ../../lib/mbedtls/library/ssl_cli.c ../../lib/mbedtls/library/ssl_cookie.c ../../lib/mbedtls/library/ssl_srv.c ../../lib/mbedtls/library/ssl_ticket.c ../../lib/mbedtls/library/ssl_tls.c ../../lib/mbedtls/library/timing.c ../../lib/mbedtls/library/x509.c ../../lib/mbedtls/library/x509_create.c ../../lib/mbedtls/library/x509_crl.c ../../lib/mbedtls/library/x509_crt.c ../../lib/mbedtls/library/x509_csr.c ../../lib/mbedtls/library/x509write_crt.c ../../lib/mbedtls/library/x509write_csr.c ../../lib/mbedtls/library/xtea.c ../../extmod/modbtree.c ../../lib/berkeley-db-1.xx/btree/bt_close.c ../../lib/berkeley-db-1.xx/btree/bt_conv.c ../../lib/berkeley-db-1.xx/btree/bt_debug.c ../../lib/berkeley-db-1.xx/btree/bt_delete.c ../../lib/berkeley-db-1.xx/btree/bt_get.c ../../lib/berkeley-db-1.xx/btree/bt_open.c ../../lib/berkeley-db-1.xx/btree/bt_overflow.c ../../lib/berkeley-db-1.xx/btree/bt_page.c ../../lib/berkeley-db-1.xx/btree/bt_put.c ../../lib/berkeley-db-1.xx/btree/bt_search.c ../../lib/berkeley-db-1.xx/btree/bt_seq.c ../../lib/berkeley-db-1.xx/btree/bt_split.c ../../lib/berkeley-db-1.xx/btree/bt_utils.c ../../lib/berkeley-db-1.xx/mpool/mpool.c modtermios.c modusocket.c modffi.c ../../py/mpstate.c ../../py/malloc.c ../../py/gc.c ../../py/pystack.c ../../py/qstr.c ../../py/vstr.c ../../py/mpprint.c ../../py/unicode.c ../../py/mpz.c ../../py/reader.c ../../py/lexer.c ../../py/parse.c ../../py/scope.c ../../py/compile.c ../../py/emitcommon.c ../../py/emitbc.c ../../py/asmbase.c ../../py/asmx64.c ../../py/emitnx64.c ../../py/asmx86.c ../../py/emitnx86.c ../../py/asmthumb.c ../../py/emitnthumb.c ../../py/emitinlinethumb.c ../../py/asmarm.c ../../py/emitnarm.c ../../py/asmxtensa.c ../../py/emitnxtensa.c ../../py/emitinlinextensa.c ../../py/emitnxtensawin.c ../../py/formatfloat.c ../../py/parsenumbase.c ../../py/parsenum.c ../../py/emitglue.c ../../py/persistentcode.c ../../py/runtime.c ../../py/runtime_utils.c ../../py/scheduler.c ../../py/nativeglue.c ../../py/pairheap.c ../../py/ringbuf.c ../../py/stackctrl.c ../../py/argcheck.c ../../py/warning.c ../../py/profile.c ../../py/map.c ../../py/obj.c ../../py/objarray.c ../../py/objattrtuple.c ../../py/objbool.c ../../py/objboundmeth.c ../../py/objcell.c ../../py/objclosure.c ../../py/objcomplex.c ../../py/objdeque.c ../../py/objdict.c ../../py/objenumerate.c ../../py/objexcept.c ../../py/objfilter.c ../../py/objfloat.c ../../py/objfun.c ../../py/objgenerator.c ../../py/objgetitemiter.c ../../py/objint.c ../../py/objint_longlong.c ../../py/objint_mpz.c ../../py/objlist.c ../../py/objmap.c ../../py/objmodule.c ../../py/objobject.c ../../py/objpolyiter.c ../../py/objproperty.c ../../py/objnone.c ../../py/objnamedtuple.c ../../py/objrange.c ../../py/objreversed.c ../../py/objset.c ../../py/objsingleton.c ../../py/objslice.c ../../py/objstr.c ../../py/objstrunicode.c ../../py/objstringio.c ../../py/objtuple.c ../../py/objtype.c ../../py/objzip.c ../../py/opmethods.c ../../py/sequence.c ../../py/stream.c ../../py/binary.c ../../py/builtinimport.c ../../py/builtinevex.c ../../py/builtinhelp.c ../../py/modarray.c ../../py/modbuiltins.c ../../py/modcollections.c ../../py/modgc.c ../../py/modio.c ../../py/modmath.c ../../py/modcmath.c ../../py/modmicropython.c ../../py/modstruct.c ../../py/modsys.c ../../py/moduerrno.c ../../py/modthread.c ../../py/vm.c ../../py/bc.c ../../py/showbc.c ../../py/repl.c ../../py/smallint.c ../../py/frozenmod.c ../../extmod/moduasyncio.c ../../extmod/moductypes.c ../../extmod/modujson.c ../../extmod/moduos.c ../../extmod/modure.c ../../extmod/moduzlib.c ../../extmod/moduheapq.c ../../extmod/modutimeq.c ../../extmod/moduhashlib.c ../../extmod/moducryptolib.c ../../extmod/modubinascii.c ../../extmod/virtpin.c ../../extmod/machine_bitstream.c ../../extmod/machine_mem.c ../../extmod/machine_pinbase.c ../../extmod/machine_signal.c ../../extmod/machine_pulse.c ../../extmod/machine_pwm.c ../../extmod/machine_i2c.c ../../extmod/machine_spi.c ../../extmod/modbluetooth.c ../../extmod/modussl_axtls.c ../../extmod/modussl_mbedtls.c ../../extmod/moduplatform.c ../../extmod/modurandom.c ../../extmod/moduselect.c ../../extmod/moduwebsocket.c ../../extmod/modwebrepl.c ../../extmod/modframebuf.c ../../extmod/vfs.c ../../extmod/vfs_blockdev.c ../../extmod/vfs_reader.c ../../extmod/vfs_posix.c ../../extmod/vfs_posix_file.c ../../extmod/vfs_fat.c ../../extmod/vfs_fat_diskio.c ../../extmod/vfs_fat_file.c ../../extmod/vfs_lfs.c ../../extmod/utime_mphal.c ../../extmod/uos_dupterm.c ../../shared/libc/abort_.c ../../shared/libc/printf.c main.c gccollect.c unix_mphal.c mpthreadport.c input.c modmachine.c modtime.c moduselect.c alloc.c fatfs_port.c mpbthciport.c mpbtstackport_common.c mpbtstackport_h4.c mpbtstackport_usb.c mpnimbleport.c unix_display.c multicast.c libsoundio-audio.c ../../shared/runtime/gchelper_generic.c ../../shared/runtime/pyexec.c ../../shared/runtime/interrupt_char.c ../../shared/timeutils/timeutils.c ../../shared/readline/readline.c ../../extmod/amy/src/amy.c ../../extmod/amy/src/algorithms.c ../../extmod/amy/src/envelope.c ../../extmod/amy/src/filters.c ../../extmod/amy/src/oscillators.c ../../extmod/amy/src/partials.c ../../extmod/amy/src/pcm.c ../../extmod/tulip/modtulip.c ../../extmod/tulip/polyfills.c ../../extmod/tulip/lodepng.c ../../extmod/tulip/bitmap_fonts.c ../../extmod/tulip/smallfont.c ../../extmod/tulip/display.c ../../extmod/tulip/bresenham.c ../../extmod/tulip/ui.c ../../extmod/tulip/help.c ../../extmod/tulip/tulip_helpers.c ../../extmod/tulip/editor.c ../../extmod/tulip/keyscan.c ../../extmod/tulip/midi.c ../../extmod/tulip/alles.c ../../extmod/tulip/sounds.c variants/standard/mpconfigvariant.h ../../py/mpconfig.h mpconfigport.h build-standard/genhdr/moduledefs.h dependencies variants/standard/mpconfigvariant.h ../../py/mpconfig.h mpconfigport.h changed_sources ../../lib/mbedtls/library/aes.c ../../lib/mbedtls/library/aesni.c ../../lib/mbedtls/library/arc4.c ../../lib/mbedtls/library/asn1parse.c ../../lib/mbedtls/library/asn1write.c ../../lib/mbedtls/library/base64.c ../../lib/mbedtls/library/bignum.c ../../lib/mbedtls/library/blowfish.c ../../lib/mbedtls/library/camellia.c ../../lib/mbedtls/library/ccm.c ../../lib/mbedtls/library/certs.c ../../lib/mbedtls/library/chacha20.c ../../lib/mbedtls/library/chachapoly.c ../../lib/mbedtls/library/cipher.c ../../lib/mbedtls/library/cipher_wrap.c ../../lib/mbedtls/library/cmac.c ../../lib/mbedtls/library/ctr_drbg.c ../../lib/mbedtls/library/debug.c ../../lib/mbedtls/library/des.c ../../lib/mbedtls/library/dhm.c ../../lib/mbedtls/library/ecdh.c ../../lib/mbedtls/library/ecdsa.c ../../lib/mbedtls/library/ecjpake.c ../../lib/mbedtls/library/ecp.c ../../lib/mbedtls/library/ecp_curves.c ../../lib/mbedtls/library/entropy.c ../../lib/mbedtls/library/entropy_poll.c ../../lib/mbedtls/library/error.c ../../lib/mbedtls/library/gcm.c ../../lib/mbedtls/library/havege.c ../../lib/mbedtls/library/hmac_drbg.c ../../lib/mbedtls/library/md2.c ../../lib/mbedtls/library/md4.c ../../lib/mbedtls/library/md5.c ../../lib/mbedtls/library/md.c ../../lib/mbedtls/library/md_wrap.c ../../lib/mbedtls/library/oid.c ../../lib/mbedtls/library/padlock.c ../../lib/mbedtls/library/pem.c ../../lib/mbedtls/library/pk.c ../../lib/mbedtls/library/pkcs11.c ../../lib/mbedtls/library/pkcs12.c ../../lib/mbedtls/library/pkcs5.c ../../lib/mbedtls/library/pkparse.c ../../lib/mbedtls/library/pk_wrap.c ../../lib/mbedtls/library/pkwrite.c ../../lib/mbedtls/library/platform.c ../../lib/mbedtls/library/platform_util.c ../../lib/mbedtls/library/poly1305.c ../../lib/mbedtls/library/ripemd160.c ../../lib/mbedtls/library/rsa.c ../../lib/mbedtls/library/rsa_internal.c ../../lib/mbedtls/library/sha1.c ../../lib/mbedtls/library/sha256.c ../../lib/mbedtls/library/sha512.c ../../lib/mbedtls/library/ssl_cache.c ../../lib/mbedtls/library/ssl_ciphersuites.c ../../lib/mbedtls/library/ssl_cli.c ../../lib/mbedtls/library/ssl_cookie.c ../../lib/mbedtls/library/ssl_srv.c ../../lib/mbedtls/library/ssl_ticket.c ../../lib/mbedtls/library/ssl_tls.c ../../lib/mbedtls/library/timing.c ../../lib/mbedtls/library/x509.c ../../lib/mbedtls/library/x509_create.c ../../lib/mbedtls/library/x509_crl.c ../../lib/mbedtls/library/x509_crt.c ../../lib/mbedtls/library/x509_csr.c ../../lib/mbedtls/library/x509write_crt.c ../../lib/mbedtls/library/x509write_csr.c ../../lib/mbedtls/library/xtea.c ../../extmod/modbtree.c ../../lib/berkeley-db-1.xx/btree/bt_close.c ../../lib/berkeley-db-1.xx/btree/bt_conv.c ../../lib/berkeley-db-1.xx/btree/bt_debug.c ../../lib/berkeley-db-1.xx/btree/bt_delete.c ../../lib/berkeley-db-1.xx/btree/bt_get.c ../../lib/berkeley-db-1.xx/btree/bt_open.c ../../lib/berkeley-db-1.xx/btree/bt_overflow.c ../../lib/berkeley-db-1.xx/btree/bt_page.c ../../lib/berkeley-db-1.xx/btree/bt_put.c ../../lib/berkeley-db-1.xx/btree/bt_search.c ../../lib/berkeley-db-1.xx/btree/bt_seq.c ../../lib/berkeley-db-1.xx/btree/bt_split.c ../../lib/berkeley-db-1.xx/btree/bt_utils.c ../../lib/berkeley-db-1.xx/mpool/mpool.c modtermios.c modusocket.c modffi.c ../../py/mpstate.c ../../py/malloc.c ../../py/gc.c ../../py/pystack.c ../../py/qstr.c ../../py/vstr.c ../../py/mpprint.c ../../py/unicode.c ../../py/mpz.c ../../py/reader.c ../../py/lexer.c ../../py/parse.c ../../py/scope.c ../../py/compile.c ../../py/emitcommon.c ../../py/emitbc.c ../../py/asmbase.c ../../py/asmx64.c ../../py/emitnx64.c ../../py/asmx86.c ../../py/emitnx86.c ../../py/asmthumb.c ../../py/emitnthumb.c ../../py/emitinlinethumb.c ../../py/asmarm.c ../../py/emitnarm.c ../../py/asmxtensa.c ../../py/emitnxtensa.c ../../py/emitinlinextensa.c ../../py/emitnxtensawin.c ../../py/formatfloat.c ../../py/parsenumbase.c ../../py/parsenum.c ../../py/emitglue.c ../../py/persistentcode.c ../../py/runtime.c ../../py/runtime_utils.c ../../py/scheduler.c ../../py/nativeglue.c ../../py/pairheap.c ../../py/ringbuf.c ../../py/stackctrl.c ../../py/argcheck.c ../../py/warning.c ../../py/profile.c ../../py/map.c ../../py/obj.c ../../py/objarray.c ../../py/objattrtuple.c ../../py/objbool.c ../../py/objboundmeth.c ../../py/objcell.c ../../py/objclosure.c ../../py/objcomplex.c ../../py/objdeque.c ../../py/objdict.c ../../py/objenumerate.c ../../py/objexcept.c ../../py/objfilter.c ../../py/objfloat.c ../../py/objfun.c ../../py/objgenerator.c ../../py/objgetitemiter.c ../../py/objint.c ../../py/objint_longlong.c ../../py/objint_mpz.c ../../py/objlist.c ../../py/objmap.c ../../py/objmodule.c ../../py/objobject.c ../../py/objpolyiter.c ../../py/objproperty.c ../../py/objnone.c ../../py/objnamedtuple.c ../../py/objrange.c ../../py/objreversed.c ../../py/objset.c ../../py/objsingleton.c ../../py/objslice.c ../../py/objstr.c ../../py/objstrunicode.c ../../py/objstringio.c ../../py/objtuple.c ../../py/objtype.c ../../py/objzip.c ../../py/opmethods.c ../../py/sequence.c ../../py/stream.c ../../py/binary.c ../../py/builtinimport.c ../../py/builtinevex.c ../../py/builtinhelp.c ../../py/modarray.c ../../py/modbuiltins.c ../../py/modcollections.c ../../py/modgc.c ../../py/modio.c ../../py/modmath.c ../../py/modcmath.c ../../py/modmicropython.c ../../py/modstruct.c ../../py/modsys.c ../../py/moduerrno.c ../../py/modthread.c ../../py/vm.c ../../py/bc.c ../../py/showbc.c ../../py/repl.c ../../py/smallint.c ../../py/frozenmod.c ../../extmod/moduasyncio.c ../../extmod/moductypes.c ../../extmod/modujson.c ../../extmod/moduos.c ../../extmod/modure.c ../../extmod/moduzlib.c ../../extmod/moduheapq.c ../../extmod/modutimeq.c ../../extmod/moduhashlib.c ../../extmod/moducryptolib.c ../../extmod/modubinascii.c ../../extmod/virtpin.c ../../extmod/machine_bitstream.c ../../extmod/machine_mem.c ../../extmod/machine_pinbase.c ../../extmod/machine_signal.c ../../extmod/machine_pulse.c ../../extmod/machine_pwm.c ../../extmod/machine_i2c.c ../../extmod/machine_spi.c ../../extmod/modbluetooth.c ../../extmod/modussl_axtls.c ../../extmod/modussl_mbedtls.c ../../extmod/moduplatform.c ../../extmod/modurandom.c ../../extmod/moduselect.c ../../extmod/moduwebsocket.c ../../extmod/modwebrepl.c ../../extmod/modframebuf.c ../../extmod/vfs.c ../../extmod/vfs_blockdev.c ../../extmod/vfs_reader.c ../../extmod/vfs_posix.c ../../extmod/vfs_posix_file.c ../../extmod/vfs_fat.c ../../extmod/vfs_fat_diskio.c ../../extmod/vfs_fat_file.c ../../extmod/vfs_lfs.c ../../extmod/utime_mphal.c ../../extmod/uos_dupterm.c ../../shared/libc/abort_.c ../../shared/libc/printf.c main.c gccollect.c unix_mphal.c mpthreadport.c input.c modmachine.c modtime.c moduselect.c alloc.c fatfs_port.c mpbthciport.c mpbtstackport_common.c mpbtstackport_h4.c mpbtstackport_usb.c mpnimbleport.c unix_display.c multicast.c libsoundio-audio.c ../../shared/runtime/gchelper_generic.c ../../shared/runtime/pyexec.c ../../shared/runtime/interrupt_char.c ../../shared/timeutils/timeutils.c ../../shared/readline/readline.c ../../extmod/amy/src/amy.c ../../extmod/amy/src/algorithms.c ../../extmod/amy/src/envelope.c ../../extmod/amy/src/filters.c ../../extmod/amy/src/oscillators.c ../../extmod/amy/src/partials.c ../../extmod/amy/src/pcm.c ../../extmod/tulip/modtulip.c ../../extmod/tulip/polyfills.c ../../extmod/tulip/lodepng.c ../../extmod/tulip/bitmap_fonts.c ../../extmod/tulip/smallfont.c ../../extmod/tulip/display.c ../../extmod/tulip/bresenham.c ../../extmod/tulip/ui.c ../../extmod/tulip/help.c ../../extmod/tulip/tulip_helpers.c ../../extmod/tulip/editor.c ../../extmod/tulip/keyscan.c ../../extmod/tulip/midi.c ../../extmod/tulip/alles.c ../../extmod/tulip/sounds.c variants/standard/mpconfigvariant.h ../../py/mpconfig.h mpconfigport.h build-standard/genhdr/moduledefs.h
modffi.c:32:10: fatal error: 'ffi.h' file not found
#include <ffi.h>
^~~~~~~
1 error generated.
Traceback (most recent call last):
File "/Users/dean/Downloads/tulipcc/ports/macos/../../py/makeqstrdefs.py", line 196, in <module>
preprocess()
File "/Users/dean/Downloads/tulipcc/ports/macos/../../py/makeqstrdefs.py", line 70, in preprocess
for output in p.imap(pp(flags), chunks):
File "/usr/local/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/pool.py", line 873, in next
raise value
File "/usr/local/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/pool.py", line 125, in worker
result = (True, func(*args, **kwds))
^^^^^^^^^^^^^^^^^^^
File "/Users/dean/Downloads/tulipcc/ports/macos/../../py/makeqstrdefs.py", line 54, in run
return subprocess.check_output(args.pp + flags + files)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/subprocess.py", line 466, in check_output
return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/subprocess.py", line 571, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['clang', '-E', '-I../../lib/berkeley-db-1.xx/PORT/include', '-I.', '-I../..', '-Ibuild-standard', '-I./SDL2.framework/Headers', '-I./soundio', '-I../../shared/readline', '-I../../extmod/tulip', '-I../../extmod/amy/src/', '-Wall', '-Werror', '-Wextra', '-Wno-unused-parameter', '-Wpointer-arith', '-Wdouble-promotion', '-Wfloat-conversion', '-std=gnu99', '-DUNIX', '-DFFCONF_H="lib/oofatfs/ffconf.h"', '-DMICROPY_PY_USSL=1', '-DMICROPY_SSL_MBEDTLS=1', '-I../../lib/mbedtls/include', '-DMICROPY_PY_BTREE=1', '-DMICROPY_USE_READLINE=1', '-DMICROPY_PY_TERMIOS=1', '-DMICROPY_PY_SOCKET=1', '-DMICROPY_PY_THREAD=1', '-DMICROPY_PY_THREAD_GIL=0', '-I/usr/local/homebrew/opt/libffi/include', '-DMICROPY_PY_FFI=1', '-Og', '-fdata-sections', '-ffunction-sections', '-Ivariants/standard', '-target', 'x86_64-apple-macos10.15', '-g', '-DVIRTUAL_MIDI', '-DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool', '-DMICROPY_MODULE_FROZEN_MPY', '-DMPZ_DIG_SIZE=16', '-DMICROPY_MODULE_FROZEN_STR', '-DMICROPY_HW_MCU_NAME="Apple M2"', '-Wno-double-promotion', '-Wno-unused-function', '-DNO_QSTR', '../../lib/berkeley-db-1.xx/btree/bt_close.c', '../../lib/berkeley-db-1.xx/btree/bt_conv.c', '../../lib/berkeley-db-1.xx/btree/bt_debug.c', '../../lib/berkeley-db-1.xx/btree/bt_delete.c', '../../lib/berkeley-db-1.xx/btree/bt_get.c', '../../lib/berkeley-db-1.xx/btree/bt_open.c', '../../lib/berkeley-db-1.xx/btree/bt_overflow.c', '../../lib/berkeley-db-1.xx/btree/bt_page.c', '../../lib/berkeley-db-1.xx/btree/bt_put.c', '../../lib/berkeley-db-1.xx/btree/bt_search.c', '../../lib/berkeley-db-1.xx/btree/bt_seq.c', '../../lib/berkeley-db-1.xx/btree/bt_split.c', '../../lib/berkeley-db-1.xx/btree/bt_utils.c', '../../lib/berkeley-db-1.xx/mpool/mpool.c', 'modtermios.c', 'modusocket.c', 'modffi.c', '../../py/mpstate.c', '../../py/malloc.c', '../../py/gc.c', '../../py/pystack.c', '../../py/qstr.c', '../../py/vstr.c', '../../py/mpprint.c', '../../py/unicode.c', '../../py/mpz.c', '../../py/reader.c', '../../py/lexer.c', '../../py/parse.c', '../../py/scope.c', '../../py/compile.c', '../../py/emitcommon.c', '../../py/emitbc.c', '../../py/asmbase.c', '../../py/asmx64.c', '../../py/emitnx64.c']' returned non-zero exit status 1.
error: write on a pipe with no reader
make: *** [build-standard/genhdr/qstr.i.last] Error 1
make: *** Deleting file `build-standard/genhdr/qstr.i.last'
error: write on a pipe with no reader
cp: tulip.i386: No such file or directory
error: write on a pipe with no reader
error: write on a pipe with no reader
error: /Library/Developer/CommandLineTools/usr/bin/install_name_tool: can't open file: dev/Tulip CC.app/Contents/MacOS/tulip (No such file or directory)
error: /Library/Developer/CommandLineTools/usr/bin/install_name_tool: can't open file: dev/Tulip CC.app/Contents/MacOS/tulip (No such file or directory)
Desktop builds show the computer that did the build in the "on" MICROPY_HW_MCU_NAME
. It would make more sense for Tulip to show the host "MCU" name when running, so we should figure out how to set MICROPY_HW_MCU_NAME
at runtime for Tulip Desktop
If a file ends with a printable character (not \n or \r\n or etc) it will be eaten by the editor if you make a change and save.
will track this longstanding issue here. for me, an easy way to replicate is to open the editor with a relatively long text file, make a change and save it.
the bounce buffers lose their starting position. there is logic to 'catch' this and restart the screen, but it does not work reliably.
a more solid solution would be to ensure the display task cannot be interrupted. but i believe network and flash access sits in freeRTOS at some untouchable priority level. slowing down disk & network is a solution.
Some USB keyboards do not yet work as they report a different transfer size.
Our USB handling in Tulip CC is very minimal and only set up to receive keyboard HID events.
Either we find a better library that works on the ESP32S3, or we continue to improve our keyboard library
Relevant code in /ports/esp32s3/usb_keyboard.c
I don't (yet) understand the USB code, but this looks suspect:
https://github.com/bwhitman/tulipcc/blob/main/ports/esp32s3/usb_keyboard.c#L312
At the top of the while(1)
loop, KeyboardTimer
gets set to the current esp32 system time in ms, but then in this clause (which appears to poll the keyboard by issuing usb_host_transfer_submit
), KeyboardTimer
gets set to zero. It is also part of a condition for entering the block.
I don't know what KeyboardInterval
(from endpoint->bInterval
) is supposed to be, but it looks like it's a minimum period between polling requests. In which case, shouldn't the entry condition be
(KeyboardTimer - last_poll_time_ms) > KeyboardInterval
and the reset in the block should be
last_poll_time_ms = KeyboardTimer
?
I think the result of this is that keyboard polling will be saturated, i.e. immediately isKeyboardPolling
is cleared in keyboard_transfer_cb
, another poll request will be issued.
e.g. urequests
, machine
(timer and pin, i2c, etc), upip
, etc
You can set audio device by running the app like ./dev/Tulip\ CC.app/Contents/MacOS/tulip -d 2
but on double clicking it'll use device -1
. For me, at least this is never the device i have set as my default. I don't know why.
Currently stops the python interpreter when there's nothing on the line. We should instead have it restart the interpreter.
This alles example crashes Tulip desktop on MacOS:
alles.send(wave=alles.PCM,vel=1,patch=35,feedback=1) # nice violin
It also crashes on any other patch >= 35
In addition, patches 29-34 are silent (but don't crash). Lower numbered patches work fine.
MacOS 12.6.5
Tulip OS 8252daa-dirty on 2023-05-04
We've upgraded to ESP 5.x but we still need to make Alles work. Local synthesis works fine, just not multi-speaker UDP stuff yet.
likely cause is screen gdma vs flash SPI. will start by disabling display before download and see if that helps.
Core 0 register dump:
PC : 0x403761b4 PS : 0x00060033 A0 : 0x40376c49 A1 : 0x3fc9b2e0
0x403761b4: shared_intr_isr at /Users/bwhitman/outside/tulipcc/esp-idf/components/esp_hw_support/intr_alloc.c:404
0x40376c49: _xt_lowint1 at /Users/bwhitman/outside/tulipcc/esp-idf/components/freertos/port/xtensa/xtensa_vectors.S:1111
A2 : 0x00000001 A3 : 0x3fc9a8d0 A4 : 0x80384d3c A5 : 0x403818e8
0x403818e8: _frxt_int_enter at /Users/bwhitman/outside/tulipcc/esp-idf/components/freertos/port/xtensa/portasm.S:119
A6 : 0x00000004 A7 : 0x00000003 A8 : 0x803761d0 A9 : 0x3fc9b2c0
A10 : 0x00000005 A11 : 0x00000001 A12 : 0x00060e21 A13 : 0x00060023
A14 : 0x600c0034 A15 : 0x00000001 SAR : 0x00000001 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000001 LBEG : 0x40056f5c LEND : 0x40056f72 LCOUNT : 0x00000000
Backtrace:0x403761b1:0x3fc9b2e00x40376c46:0x3fc9b300 0x4037b8b1:0x3fcf1e60 0x40384d2d:0x3fcf1e70 0x403763b7:0x3fcf1e90 0x4037bdf7:0x3fcf1eb0 0x403792d8:0x3fcf1ed0
0x403761b1: vPortEnterCritical at /Users/bwhitman/outside/tulipcc/esp-idf/components/freertos/port/xtensa/include/freertos/portmacro.h:578
(inlined by) shared_intr_isr at /Users/bwhitman/outside/tulipcc/esp-idf/components/esp_hw_support/intr_alloc.c:402
0x40376c46: _xt_lowint1 at /Users/bwhitman/outside/tulipcc/esp-idf/components/freertos/port/xtensa/xtensa_vectors.S:1111
0x4037b8b1: gdma_default_tx_isr at /Users/bwhitman/outside/tulipcc/esp-idf/components/driver/gdma.c:745
0x40384d2d: vPortClearInterruptMaskFromISR at /Users/bwhitman/outside/tulipcc/esp-idf/components/freertos/port/xtensa/include/freertos/portmacro.h:571
(inlined by) vPortExitCritical at /Users/bwhitman/outside/tulipcc/esp-idf/components/freertos/port/xtensa/port.c:319
0x403763b7: vPortExitCriticalSafe at /Users/bwhitman/outside/tulipcc/esp-idf/components/freertos/port/xtensa/include/freertos/portmacro.h:605
(inlined by) esp_intr_noniram_enable at /Users/bwhitman/outside/tulipcc/esp-idf/components/esp_hw_support/intr_alloc.c:808
0x4037bdf7: spi_flash_op_block_func at /Users/bwhitman/outside/tulipcc/esp-idf/components/spi_flash/cache_utils.c:129
0x403792d8: ipc_task at /Users/bwhitman/outside/tulipcc/esp-idf/components/esp_ipc/src/esp_ipc.c:77
Originally posted by drepetto May 19, 2023
Key repeat sometimes works in terminal, almost never works in edit.py. When it does work it's just for a bit then it konks out. I'm using an old Dell USB keyboard, no hub or anything fancy about it.
If you use default display_clock(22), and print something like world.files()
to the REPL, the TFB will flash on many of the lines. It's very distracting. A change to display_clock(18)
fixes it. This means the TFB can't quite keep up with timing if it has to draw glyphs on each column per line. Some ideas:
If using a WROOM-1 dev board (like the N8R8 one I suggest for the breakout or breadboard Tulip) you need to disable Octal Flash in menuconfig's Serial Flasher Config.
For the integrated board and a WROOM-2 dev board (N32R8) Octal flash needs to be on.
This is easily fixable but people are going to run into it. I should update the instructions, and/or provide a TULIP4_OCTAL and TULIP4 board in Micropython.
It would be nice to be able to turn off rendering of text in the terminal while a script is running, then turn it back on upon exit. That way the state of the user's terminal is preserved.
My screen is RGB666 and has a 3 line SPI initialization, can I also take the screen R[5:3],G[5:3],B[5:4] for connection.
But one more question, my screen needs an SPI initialization, where should I add it?
See tweet
https://twitter.com/matt_trentini/status/1625732568065904640?s=20
Questions with no answers yet
extmod/tulip
you can freely do like move_sprite(-100, -100) etc and tulip will happily crash.
I think in extmod/tulip/modtulip.c we should have bounds checking for all pixel value calls, that perhaps use the current timing settings for the offscreen w,h and onscreen w.h.
Key repeat sometimes works in terminal, almost never works in edit.py. When it does work it's just for a bit then it konks out. I'm using an old Dell USB keyboard, no hub or anything fancy about it.
uart print:
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x3fcd0108,len:0xe34
load:0x403b6000,len:0x9e8
load:0x403ba000,len:0x2be4
SHA-256 comparison failed:
Calculated: 3356bfb3cf5cdc8b9f12bd72c6d62aa0a5824e33f4c54cc5d72bbd54d9a0ad56
Expected: f8562e64c0a43395093d8bab1f4be4ea2db25043e3be49520448dc36ff4b5ca7
Attempting to boot anyway...
entry 0x403b61d4
Starting display on core 0
setting duty to 4000
Starting Alles on core 1
Starting MicroPython on core 1
St�.�I'm renderer #1 on core #0 and i'm handling oscs 32 up until 64
screen it reboot
what's the problem? Thanks
As I build more touch screen UI features, I'm noticing my calibration is off.
i propose a tulip.calibrate()
that shows Xs on random parts of the screen that the user has to tap and we figure it out from there
Currently we have this mess:
#define TOUCH_LEFT_X 473 // and goes down as X+ to 0 in the middle and then down from 65535 to 64997
#define TOUCH_TOP_Y 4
#define TOUCH_RIGHT_X 64997
#define TOUCH_MIDDLE_X 65535
#define TOUCH_BOTTOM_Y 591
and we compute x,y via
if(touch_info.curx[i] > 64000) { // right half of screen
last_touch_x[i] = (H_RES/2) + (TOUCH_MIDDLE_X - touch_info.curx[i]) * ((float)(H_RES/2) / (float)(TOUCH_MIDDLE_X-TOUCH_RIGHT_X));
} else {
last_touch_x[i] = (TOUCH_LEFT_X - touch_info.curx[i]) * ((float)(H_RES/2) / (float)(TOUCH_LEFT_X));
}
last_touch_y[i] = (touch_info.cury[i]-TOUCH_TOP_Y) * ((float)V_RES / (float) (TOUCH_BOTTOM_Y-TOUCH_TOP_Y));
Any interest in porting this to CircuitPython? I added the broadcom port for exactly this style of use on the pi 400. Biggest hurdle now is usb host over pcie.
This'll be a big and annoying task but it's worth it to fix a few issues we're having.
It does look like bounce_buffers were added to esp_lcd, so we may be able to get away with deleting our bw_esp_lcd component
I'm also excited to see native support for N32R8 and N16R8
Probably a lot of breaking API changes though.
Worth doing Micropython at the same time?
I think something about the LEDC clock is conflicting with UART_1's clock. If you set brightness(9) midi will start getting garbage inputs.
My plan is to use 5.0 inch 800x480 screen ,but now font is too small (8x12).
I find out the font file smallfont.c and the font setting #define FONT_HEIGHT 12 #define FONT_WIDTH 8.
So can I changed other bigger font?Maybe 12x24 font
The first line in smallfont.c is
const unsigned char font_8x12_r[256][12]
Where can I found font files in this format?Or can you provided a 12x24 font file or font convert tools? Thanks.
I'm playing with the buttons.py demo. It took me awhile to realize that the tulip.text() boxes are text inputs. A few ideas:
Douglas discovered that blitting was faster than bg_clear(), which made us realize the bg_clear was slower than just setting 0,0 to the color and copying that pixel 1024x600 times. We think it's because within SPIRAM copying is faster than writing from RAM to SPIRAM. (We think.) If that's the case, there's probably some other optimizations we can make around this. Maybe we can use SPIRAM for sprites? Or at least fix things like fillRect, or other x/y copy ops.
See bunny_bounce on tulip.world.
If i do tulip.wifi() at the top of my boot.py USB will fail to initialize. Putting a tulip.time.sleep(5) at the top of boot.py seems to solve this.
Rebooting...
?ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x39 (SPI_FAST_FLASH_BOOT)
Saved PC:0x420f8966
0x420f8966: esp_pm_impl_waiti at /Users/douglas/Documents/tulipcc/esp-idf/components/esp_pm/pm_impl.c:839
SPIWP:0xee
Octal Flash Mode Enabled
For OPI Flash, Use Default Flash Boot Mode
mode:SLOW_RD, clock div:1
load:0x3fcd0108,len:0xe34
load:0x403b6000,len:0x9e8
load:0x403ba000,len:0x2c08
entry 0x403b61d4
Starting MIDI on core 0
UART MIDI running on core 0
Starting USB host on core 1
Starting display on core 0
usb_host_install: 0
usb_host_client_register: 0
setting duty to 4000
ft5x06 device create successed
Startck
starting i2s: [ok]
I'm renderer #0 on core #1 and i'm handling oscs 0 up until 32
I'm renderer #1 on core #0 and i'm handling oscs 32 up until 64
E (1080) HUB: Bad transfer status: CHECK_ADDR
E (1080) HUB: Stage failed: CHECK_ADDR
I am seeing screen rolling (like bad-v-sync) on the latest main Tulip CC running an example like parallax.py
. It seems to be an interaction between flash reads and display writes. If i do tulip.display_stop()
before the disk loads and turn it back on before the game start, everything is fine. This seems like new behavior since last week, so i'll have to track this down with a git bisect.
Need to wire up whatever SDL uses for joystick into the macos port so that tulip.joy()
works.
Doesn't look too bad
https://www.libsdl.org/release/SDL-1.2.15/docs/html/joystick.html
Running ex/buttons.py
, In ui_button_draw()
we find that often the text is not written to the button. A rerun of, e.g. buttons.py
will often fix it. And more perplexing, this is happening on both Desktop and CC. A 100% fix is to add delay_ms(50)
before writing the text on the button.
Theory: the frame callback runs in the middle of the code. Double buffering? A thread mutex?
Seems like we have the hardware to support a bluetooth (wireless) keyboard. That would be neat, wouldn't it?
As it is setup, using a 32MB flash chip will only use 8MB for the filesystem. Our forked ESP-IDF does not support 32MB chips. I tried hacking it in but got timeouts when erasing the region. We'll have to upgrade our ESP-IDF to get this support.
Track this.. we could use the ota
partition like Alles does, and trigger it from python.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.