Merge remote-tracking branch 'slyvtt/numworks' into dev

This merges PR #14 with SlyVTT's Numworks support.
This commit is contained in:
Lephenixnoir 2024-03-03 13:17:10 +00:00
commit dfb73611f9
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
30 changed files with 2250 additions and 5 deletions

3
.gitignore vendored
View File

@ -23,3 +23,6 @@ user.props
# MacOS desktop metadata files
.DS_Store
# vscode
.vscode/

View File

@ -0,0 +1,120 @@
# Using Numworks' modules `kandinsky`, `ion` and `time` with PythonExtra
PythonExtra offers the possibility of using certain Numworks modules in order to make the scripts of this machine compatible as is on Casio fx-CG50 (no support on the fx9860G due to insufficient memory and lack of color screen ).
This is a Work in Progress (WIP) and the support is subject to extensive testing at this stage. The port concerns the Numworks `kandinsky`, `ion` and `time` modules which are machine specific and are now supported via this implementation. The `math`, `cmath`, `random` modules being identical between the `Numworks` version and the `builtins` modules of MicroPython, they are therefore not part of this implementation but are perfectly usable without modification in the scripts.
Note: the `turtle` and `matplotlib.pyplot` modules are not included in this implementation. It is possible to use the `turtle`, `matplotlib` and `casioplot` modules from Casio Education which are perfectly functional and provided as an example in `ports/sh/examples`.
## `kandinsky`
The `kandinsky` module provides support for graphics primitives via high-performance `gint` routines. All the functions of this module are available:
- `color(r,g,b)`: Generates the value of the color r,g,b. You can also simply use a tuple to define a color: (r,g,b).
- `get_pixel(x,y)`: Returns the color of the pixel at x,y coordinates as a tuple (r,g,b).
- `set_pixel(x,y,color)`: Lights the pixel x,y of the color color.
- `draw_string(text,x,y,[color1],[color2])`: Displays the text at x,y coordinates. The arguments color1 (text color) and color2 (text background color) are optional.
- `fill_rect(x,y,width,height,color)`: Fills a rectangle of width width and height height with the color color at the point of x and y coordinates.
The module also offers a certain number of colors explicitly named and accessible by a character string. The following values can be used instead of the color parameters of the `kandinsky` functions:
- "red", "r"
- "green", "g"
- "blue", "b"
- "black", "k"
- "white", "w"
- "yellow", "y"
- "pink"
- "magenta"
- "grey", "gray"
- "purple"
- "orange"
- "cyan"
- "brown"
The following functions are additions to take advantage of the wide screen of the fxCG and are therefore an extension of the `Kandinsky` module. They are therefore by definition not compatible with Python Numwork. These functions can be recognized by their names which all begin with `CGEXT_`:
- `CGEXT_Enable_Wide_Screen()`: Enables the fxCG wide screen, no settings are necessary. The x-coordinates of the physical screen can be negative to encroach on the left white stripe and greater than 319 pixels to encroach on the right white stripe;
- `CGEXT_Disable_Wide_Screen()`: Cancels the activation of the fxCG extended screen, no settings are necessary. The x coordinates of the physical screen will be constrained between 0 and 320 pixels. Beyond that, the route will not be carried out.
- `CGEXT_Is_Wide_Screen_Enabled()`: Returns `True` if the extended screen is active and `False` otherwise.
- `CGEXT_Set_Margin_Color( color )` : Paints the margin of the `Numworks` screen on fxCG with the specified color.
Note 1: after having made a plot in the extended area, it must be active to allow its deletion (typically via a call to the `fill_rect()` function with the appropriate parameters).
Note 2: In non-extended mode (by default when initializing the `Kandinsky` module) the screen coordinates go from (0,0) to (319,221) centered on the fxCG screen. In extended mode, the screen coordinates range from (-38,-1) to (358,223).
## `ion`
The `ion` module gives access to the `keydown(k)` function which returns True if the key k placed as an argument is pressed and False otherwise.
The “conversion” of the keys between the Numworks machine and Casio fxCG50 is done according to the following mapping:
| Numworks | Casio fxCG50 | Numworks Key # |
|----------|--------------|---------------------|
| KEY_LEFT | KEY_LEFT | 0 |
| KEY_UP | KEY_UP | 1 |
| KEY_DOWN | KEY_DOWN | 2 |
| KEY_RIGHT | KEY_RIGHT | 2 |
| KEY_OK | KEY_F1 | 4 |
| KEY_BACK | KEY_EXIT | 5 |
| KEY_HOME | KEY_MENU | 6 |
| KEY_ONOFF | KEY_ACON | 7 |
| ... | ... | ... |
| KEY_SHIFT | KEY_SHIFT | 12 |
| KEY_ALPHA | KEY_ALPHA | 13 |
| KEY_XNT | KEY_XOT | 14 |
| KEY_VAR | KEY_VARS | 15 |
| KEY_TOOLBOX | KEY_OPTN | 16 |
| KEY_BACKSPACE | KEY_DEL | 17 |
| KEY_EXP | KEY_EXP | 17 |
| KEY_LN | KEY_LN | 19 |
| KEY_LOG | KEY_LOG | 20 |
| KEY_IMAGINARY | KEY_F2 | 21 |
| KEY_COMMA | KEY_COMMA | 22 |
| KEY_POWER | KEY_POWER | 23 |
| KEY_SINE | KEY_SIN | 24 |
| KEY_COSINE | KEY_COS | 25 |
| KEY_TANGENT | KEY_TAN | 26 |
| KEY_PI | KEY_F3 | 27 |
| KEY_SQRT | KEY_F4 | 28 |
| KEY_SQUARE | KEY_SQUARE | 29 |
| KEY_SEVEN | KEY_7 | 30 |
| KEY_EIGHT | KEY_8 | 31 |
| KEY_NINE | KEY_9 | 32 |
| KEY_LEFTPARENTHESIS | KEY_LEFTP | 33 |
| KEY_RIGHTPARENTHESIS | KEY_RIGHTP | 34 |
| ... | ... | ... |
| KEY_FOUR | KEY_4 | 36 |
| KEY_FIVE | KEY_5 | 37 |
| KEY_SIX | KEY_6 | 38 |
| KEY_MULTIPLICATION | KEY_MUL | 39 |
| KEY_DIVISION | KEY_DIV | 40 |
| ... | ... | ... |
| KEY_ONE | KEY_1 | 42 |
| KEY_TWO | KEY_2 | 43 |
| KEY_THREE | KEY_3 | 44 |
| KEY_PLUS | KEY_ADD | 45 |
| KEY_MINUS | KEY_SUB | 46 |
| ... | ... | ... |
| KEY_ZERO | KEY_0 | 48 |
| KEY_DOT | KEY_DOT | 49 |
| KEY_EE | KEY_F5 | 50 |
| KEY_ANS | KEY_NEG | 51 |
| KEY_EXE | KEY_EXE | 52 |
## `time`
The `time` module gives access to two functions:
- `monotonic()`: Returns the clock value at the time the function is called.
- `sleep(t)`: Suspends execution for t seconds.

View File

@ -0,0 +1,120 @@
# Utilisation des modules `kandinsky`, `ion` et `time` de l'implémentation Python `Numworks`
PythonExtra offre la possibilité d'utiliser certains modules de la Numworks afin de rendre les scripts de cette machine compatible en l'état sur Casio fx-CG50 (pas de support sur la fx9860G pour cause de mémoire insuffisante et d'abence d'écran couleur).
Il s'agit d'un Work in Progress (WIP) et le support est sujet à tests approfondis à ce stade. Le port concerne les modules `kandinsky`, `ion` et `time` de la Numworks qui sont spécifiques à la machine et sont désormais supportés via cette implémentation. Les modules `math`, `cmath`, `random` étant identiques entre la version `Numworks` et les modules `builtins` de MicroPython, ils ne font donc pas partie de cette implémentation mais sont parfaitement utilisables sans modification dans les scripts.
Note : les modules `turtle` et `matplotlib.pyplot` ne sont pas repris dans cette implémentation. Il est possible d'utiliser les modules `turtle`, `matplotlib` et `casioplot` de Casio Education qui sont parfaitement fonctionnels et fournis en example dans `ports/sh/examples`.
## `kandinsky`
Le module `kandinsky` offre le support des primitives graphiques via les routines hautes performance de `gint`. Toutes les fonctions de ce module sont disponibles :
- `color(r,g,b)` : Génère la valeur de la couleur r,g,b. Vous pouvez aussi simplement utiliser un tuple pour définir une couleur : (r,g,b).
- `get_pixel(x,y)` : Renvoie la couleur du pixel aux coordonnées x,y sous forme de tuple (r,g,b).
- `set_pixel(x,y,color)` : Allume le pixel x,y de la couleur color.
- `draw_string(text,x,y,[color1],[color2])` : Affiche le texte text aux coordonnées x,y. Les arguments color1 (couleur du texte) et color2 (couleur de lʼarrière plan du texte) sont optionnels.
- `fill_rect(x,y,width,height,color)` : Remplit un rectangle de largeur width et de hauteur height avec la couleur color au point de coordonnées x et y.
Le module offre de plus un certain nombre de couleurs explicitement nommées et accessibles par une chaine de caractères. Les valeurs suivantes sont utilisables en lieu et place des paramètres de couleur des fonctions de `kandinsky` :
- "red", "r"
- "green", "g"
- "blue", "b"
- "black", "k"
- "white", "w"
- "yellow", "y"
- "pink"
- "magenta"
- "grey", "gray"
- "purple"
- "orange"
- "cyan"
- "brown"
Les fonctions suivantes sont des ajouts pour tirer partie de l'écran large de la fxCG et qui sont donc une extension du module `Kandinsky`. Elles ne sont donc par définition pas compatible avec le Python Numwork. Ces fonctions sont reconnaisables à leurs appellations qui commencent toutes par `CGEXT_` :
- `CGEXT_Enable_Wide_Screen()` : Active l'écran étendu de la fxCG, aucun paramètre n'est nécessaire. Les coordonnées x de l'écran physique peuvent être négatives pour empiéter sur la bande blanche de gauche et supérieures à 319 pixels pour empièter sur la bande blanche de droite;
- `CGEXT_Disable_Wide_Screen()` : Annule l'activation de l'écran étendu de la fxCG, aucun paramètre n'est nécessaire. Les coordonnées x de l'écran physique seront contraintes entre 0 et 320 pixels. Au-delà, le tracé ne sera pas effectué.
- `CGEXT_Is_Wide_Screen_Enabled()` : Retourne `True` si l'écran étendu est actif et `False` dans le cas contraire.
- `CGEXT_Set_Margin_Color( color )` : Trace les marge de la fxCG50 (pourtours de l'écran `Numworks`) de la couleur passée en argument.
Note 1 : après avoir réalisé un tracé dans la zone étendue, il faut que celle-ci soit active pour permettre son effacement (typiquement via un appel à la fonction `fill_rect()` avec les paramètres adéquats).
Note 2 : En mode non étendu (par défaut à l'initialisation du module `Kandinsky`) les coordonnées de l'écran vont de (0,0) à (319,221) centré sur l'écran de la fxCG. En mode étendu, les coordonnées de l'écran vont de (-38,-1) à (358,223).
## `ion`
Le module `ion` donne accès à la fonction `keydown(k)` qui renvoie True si la touche k placée en argument est appuyée et False sinon.
La "conversion" des touches entre la machine Numworks et Casio fxCG50 se fait selon le mapping suivant :
| Numworks | Casio fxCG50 | Numworks Key # |
|----------|--------------|---------------------|
| KEY_LEFT | KEY_LEFT | 0 |
| KEY_UP | KEY_UP | 1 |
| KEY_DOWN | KEY_DOWN | 2 |
| KEY_RIGHT | KEY_RIGHT | 2 |
| KEY_OK | KEY_F1 | 4 |
| KEY_BACK | KEY_EXIT | 5 |
| KEY_HOME | KEY_MENU | 6 |
| KEY_ONOFF | KEY_ACON | 7 |
| ... | ... | ... |
| KEY_SHIFT | KEY_SHIFT | 12 |
| KEY_ALPHA | KEY_ALPHA | 13 |
| KEY_XNT | KEY_XOT | 14 |
| KEY_VAR | KEY_VARS | 15 |
| KEY_TOOLBOX | KEY_OPTN | 16 |
| KEY_BACKSPACE | KEY_DEL | 17 |
| KEY_EXP | KEY_EXP | 17 |
| KEY_LN | KEY_LN | 19 |
| KEY_LOG | KEY_LOG | 20 |
| KEY_IMAGINARY | KEY_F2 | 21 |
| KEY_COMMA | KEY_COMMA | 22 |
| KEY_POWER | KEY_POWER | 23 |
| KEY_SINE | KEY_SIN | 24 |
| KEY_COSINE | KEY_COS | 25 |
| KEY_TANGENT | KEY_TAN | 26 |
| KEY_PI | KEY_F3 | 27 |
| KEY_SQRT | KEY_F4 | 28 |
| KEY_SQUARE | KEY_SQUARE | 29 |
| KEY_SEVEN | KEY_7 | 30 |
| KEY_EIGHT | KEY_8 | 31 |
| KEY_NINE | KEY_9 | 32 |
| KEY_LEFTPARENTHESIS | KEY_LEFTP | 33 |
| KEY_RIGHTPARENTHESIS | KEY_RIGHTP | 34 |
| ... | ... | ... |
| KEY_FOUR | KEY_4 | 36 |
| KEY_FIVE | KEY_5 | 37 |
| KEY_SIX | KEY_6 | 38 |
| KEY_MULTIPLICATION | KEY_MUL | 39 |
| KEY_DIVISION | KEY_DIV | 40 |
| ... | ... | ... |
| KEY_ONE | KEY_1 | 42 |
| KEY_TWO | KEY_2 | 43 |
| KEY_THREE | KEY_3 | 44 |
| KEY_PLUS | KEY_ADD | 45 |
| KEY_MINUS | KEY_SUB | 46 |
| ... | ... | ... |
| KEY_ZERO | KEY_0 | 48 |
| KEY_DOT | KEY_DOT | 49 |
| KEY_EE | KEY_F5 | 50 |
| KEY_ANS | KEY_NEG | 51 |
| KEY_EXE | KEY_EXE | 52 |
## `time`
Le module `time` donne accès à deux fonctions :
- `monotonic()` : Renvoie la valeur de lʼhorloge au moment où la fonction est appelée.
- `sleep(t)` : Suspend lʼexécution pendant t secondes.

View File

@ -1,6 +1,7 @@
include ../../py/mkenv.mk
SH_CFLAGS := -DFX9860G
TARGETCASIO := "FX9860G"
SH_LDFLAGS := -T fx9860g.ld -ljustui-fx -lm -lgint-fx -lc -lgint-fx -lgcc
SH_ASSETS := \

View File

@ -1,2 +1,2 @@
/icon.xcf
/PythonExtra.g3a
/*.g3a

View File

@ -1,16 +1,17 @@
include ../../py/mkenv.mk
SH_CFLAGS := -DFXCG50
TARGETCASIO := "FXCG50"
SH_LDFLAGS := -T fxcg50.ld -ljustui-cg -lm -lgint-cg -lc -lgint-cg -lgcc
SH_ASSETS := img_modifier_states.png font_9.png font_13.png font_19.png
SH_ASSETS := img_modifier_states.png font_9.png font_13.png font_19.png PoliceNW
SH_METADATA := fxconv-metadata.txt
SH_CONVFLAGS := --cg
all: PythonExtra.g3a
PythonExtra.g3a: $(BUILD)/firmware.bin icon-uns.png icon-sel.png
fxgxa --g3a -n PythonExtra --icon-uns=icon-uns.png --icon-sel=icon-sel.png $< -o $@
fxgxa --g3a -n PyExtra_NW --icon-uns=icon-uns.png --icon-sel=icon-sel.png $< -o $@
send: all
fxlink -sw PythonExtra.g3a

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -29,3 +29,12 @@ font_19.png:
grid.padding: 0
grid.border: 0
proportional: true
PoliceNW:
name: numworks
type: font
charset: unicode
grid.size: 10x16
grid.padding: 0
grid.border: 0
proportional: true

BIN
ports/fxcg50/icon-selNW.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
ports/fxcg50/icon-unsNW.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

1
ports/sh/.gitignore vendored
View File

@ -1,2 +1,3 @@
/exclude/
/PythonExtra*.zip
/numworks/ion_backup.c

View File

@ -32,6 +32,29 @@ SRC_QSTR += \
ports/sh/objgintimage.c \
ports/sh/pyexec.c \
ifeq ($(TARGETCASIO),"FXCG50")
$(info ************ FXCG50 VERSION ************ )
$(info ********* Add Numworks modules ********* )
SRC_C += \
ports/sh/numworks/modkandinsky.c \
ports/sh/numworks/ion.c \
ports/sh/numworks/time.c \
SRC_QSTR += \
ports/sh/numworks/modkandinsky.c \
ports/sh/numworks/ion.c \
ports/sh/numworks/time.c
endif
ifeq ($(TARGETCASIO),"FX9860G")
$(info *********** FX9860G VERSION *********** )
endif
ASSETS_O := $(SH_ASSETS:%=$(BUILD)/sh_assets/%.o)
OBJ = $(PY_O) $(ASSETS_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))

View File

@ -224,4 +224,9 @@ void pe_debug_run_videocapture(void)
}
}
void pe_debug_close(void)
{
usb_close();
}
#endif /* PE_DEBUG */

View File

@ -84,6 +84,9 @@ void pe_debug_toggle_videocapture(void);
/* Send a video capture frame if video capture is enabled. */
void pe_debug_run_videocapture(void);
/* Close the debugging ressources */
void pe_debug_close(void);
#if !PE_DEBUG
#define PE_DEBUG_NOOP do {} while(0)
#define pe_debug_init(...) PE_DEBUG_NOOP
@ -92,6 +95,7 @@ void pe_debug_run_videocapture(void);
#define pe_debug_screenshot(...) PE_DEBUG_NOOP
#define pe_debug_toggle_videocapture(...) PE_DEBUG_NOOP
#define pe_debug_run_videocapture(...) PE_DEBUG_NOOP
#define pe_debug_close(...) PE_DEBUG_NOOP
#endif
#endif /* __PYTHONEXTRA_DEBUG_H */

View File

@ -0,0 +1,223 @@
# PacMan par Kevin FEDYNA
# https://nsi.xyz/numapps/pac-man-en-python-numworks/
from kandinsky import fill_rect, draw_string
from ion import keydown
from math import sqrt
from random import randint
from time import monotonic
try:
from kandinsky import get_keys
color = (192, 53, 53)
except:
color = (255, 183, 52)
terrain = (262143,131841,187245,187245,131073,186285,135969,252783,249903,251823,1152,251823,249903,251823,131841,187245,147465,219051,135969,195453,131073,262143)
bits = 18
width = 320
height = 222
colors = ((0, 0, 0), (32, 48, 248), (248, 224, 8), tuple(color))
ghost_color = ((255, 184, 255), (255, 0,0), (255, 184, 82), (0, 255, 255))
pacgommes = [0,130302,9360,74898,131070,75858,126174,8208,8208,8208,8208,8208,8208,8208,130302,74898,49140,43092,126174,66690,131070,0]
superpacgommes = [0,0,65538,0,0,0,0,0,0,0,0,0,0,0,0,0,65538,0,0,0,0,0,0]
frightened = 0
lives = 2
won = 0
lvl = 0
score = 0
chained = 0
class Entity:
def __init__(self, x, y, clr, d=0):
self.x = x
self.y = y
self.d = d
self.nd = d
self.f = 0
self.out = 0
self.color = clr
fill_rect(int(self.x*10)+136,int(self.y*10)-3,8,8,self.color)
def espace(self,dx=-1,dy=-1):
if dx == dy:
dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[self.nd]
return not terrain[int(self.y + 5.5*dy)]>>(bits-1-int(self.x + 5.5*dx)) & 1 and ((dx != 0 and self.y%1 == 0.5) or (dy != 0 and self.x%1== 0.5))
def move(self):
global frightened, ghosts, score, chained, lives, total, won
dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[self.d]
if self.espace(dx,dy):
fill_rect(int(self.x*10)+136,int(self.y*10)-3,8,8,colors[0])
self.x = (round(self.x + dx, 1) - 0.5) % 16.5 + 0.5
self.y = round(self.y + dy, 1)
fill_rect(int(self.x*10)+136,int(self.y*10)-3,8,8,self.color)
if self.color == colors[2]:
if pacgommes[int(self.y)] >> (bits - 1 - int(self.x)) & 1:
pacgommes[int(self.y)] -= 1 << (bits - 1 - int(self.x))
score += 10
if superpacgommes[int(self.y)] >> (bits - 1 - int(self.x)) & 1:
superpacgommes[int(self.y)] -= 1 << (bits - 1 - int(self.x))
score += 50
chained = 0
frightened = monotonic()
for g in ghosts:
if g.out:
g.color = colors[1]
g.d = (3, 2, 1, 0)[g.d]
g.f = 1
for g in range(4):
if sqrt((self.x-ghosts[g].x)**2+(self.y-ghosts[g].y)**2) < 0.6:
if ghosts[g].f:
chained += 1
total += 1
score += (1 << chained)*100
ghosts[g].f = 0
ghosts[g].color = ghost_color[g]
ghosts[g].x = 9
ghosts[g].y = 8.5
if total == 16:
score += 12000
else:
for gp in range(4):
ghosts[gp].f = 0
ghosts[gp].color = ghost_color[gp]
ghosts[gp].x = 9
ghosts[gp].y = 10.5
ghosts[gp].out = 0
self.x = 9
self.y = 16.5
self.d, self.nd = 0, 0
lives -= 1
return render()
if not won and score > 10000:
lives += 1
won = 1
px, py = int(self.x - 5.5*dx), int(self.y - 5.5*dy)
if pacgommes[py]>>(bits-1-px) & 1:
fill_rect(px*10+144,py*10+5,2,2,(250, 207, 173))
if superpacgommes[py]>>(bits-1-px) & 1:
fill_rect(px*10+143,py*10+4,4,4,(250, 207, 173))
def ia(self,x,y):
if self.f:
while True:
d = randint(0,3)
dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[d]
if d != (3,2,1,0)[self.d] and self.espace(dx,dy):
self.d = d
break
else:
distances = [9999 for _ in range(4)]
for i in range(4):
if i != (3,2,1,0)[self.d]:
dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[i]
if self.espace(dx,dy):
distances[i] = sqrt((self.y + dy - y)**2 + (self.x + dx - x)**2)
self.d = distances.index(min(distances))
def prebuild():
fill_rect(0,0,width,height,colors[0])
fill_rect(138, 0, 2, height, colors[3])
draw_string("PAC-MAN", 35, 10, colors[3], colors[0])
draw_string("nsi.xyz/pacman", 0, 204,colors[0], colors[3])
draw_string("Score :", 35, 40, (255,)*3, colors[0])
draw_string("Niveau :", 30, 90, (255,)*3, colors[0])
def render():
global terrain, pacgommes, superpacgommes, lives, arrivee
if lives == -1:
return 42
draw_string(str(lvl),70-5*len(str(lvl)),110,(255,)*3,colors[0])
fill_rect(0,150,138,20,colors[0])
for i in range(lives):
fill_rect(60-(lives-1)*20+i*40,150,20,20,colors[2])
for l in range(len(terrain)):
for c in range(bits):
fill_rect(c*10+140,l*10+1,10,10,colors[0])
if pacgommes[l]>>(bits-1-c) & 1:
fill_rect(c*10+144,l*10+5,2,2,(250, 207, 173))
if superpacgommes[l]>>(bits-1-c) & 1:
fill_rect(c*10+143,l*10+4,4,4,(250, 207, 173))
if terrain[l]>>(bits-1-c) & 1:
for d in ((1,0),(0,1),(-1,0),(0,-1)):
if 0 <= l + d[0] <= len(terrain) - 1 and 0 <= c + d[1] <= bits - 1 and not terrain[l + d[0]]>>(bits-1-(c+d[1])) & 1:
fill_rect(c*10+140+9*(d[1]==1),l*10+1+9*(d[0]==1),1+9*(d[1]==0),1+9*(d[0]==0),colors[1])
arrivee = monotonic()
def engine():
global frightened, ghosts, pacgommes, superpacgommes, lvl, arrivee, total
while True:
pacgommes = [0,130302,9360,74898,131070,75858,126174,8208,8208,8208,8208,8208,8208,8208,130302,74898,49140,43092,126174,66690,131070,0]
superpacgommes = [0,0,65538,0,0,0,0,0,0,0,0,0,0,0,0,0,65538,0,0,0,0,0,0]
lvl += 1
total = 0
render()
pacman = Entity(9, 16.5, colors[2])
ghosts = [Entity(9, 10.5, ghost_color[i]) for i in range(4)]
while sum(pacgommes) + sum(superpacgommes):
depart = monotonic()
for i in range(4):
if keydown(i):
if i == (3,2,1,0)[pacman.d]:
pacman.d = i
pacman.nd = i
while monotonic() - depart < 0.01:
if pacman.espace():
pacman.d = pacman.nd
if pacman.move() == 42:
draw_string("GAME OVER",185,100,colors[3],colors[0])
return 69
draw_string(str(score),70-5*len(str(score)),60,(255,)*3,colors[0])
""" Fantomes """
if frightened:
if monotonic() - frightened > 6.5:
for g in ghosts:
if g.f:
g.color = (255,)*3
if monotonic() - frightened > 8.5:
frightened = 0
for g in range(4):
ghosts[g].color = ghost_color[g]
ghosts[g].f = 0
if arrivee:
if monotonic() - arrivee > 0 and not ghosts[1].out:
ghosts[1].out = 1
ghosts[1].y = 8.5
if monotonic() - arrivee > 2.5 and not ghosts[0].out:
ghosts[0].out = 1
ghosts[0].y = 8.5
if monotonic() - arrivee > 5 and not ghosts[3].out:
ghosts[3].out = 1
ghosts[3].y = 8.5
if monotonic() - arrivee > 7.5 and not ghosts[2].out:
ghosts[2].out = 1
ghosts[2].y = 8.5
fill_rect(220,101,20,10,colors[0])
arrivee = 0
pdx, pdy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[pacman.d]
# Pinky
ghosts[0].ia(pacman.x + 20 * pdx, pacman.y + 20 * pdy)
ghosts[0].move()
# Inky
ghosts[3].ia(max(min(ghosts[1].x + 2*(pacman.x + 20 * pdx - ghosts[1].x), 16.5), 1.5), max(min(ghosts[1].y +2*(pacman.y + 20 * pdy - ghosts[1].y), 21.5), 1.5))
ghosts[3].move()
# Blinky
ghosts[1].ia(pacman.x, pacman.y)
ghosts[1].move()
# Clyde
if sqrt((ghosts[2].x - pacman.x)**2 + (ghosts[2].y - pacman.y)**2) > 4:
ghosts[2].ia(pacman.x, pacman.y)
else:
ghosts[2].ia(1.5, 20.5)
ghosts[2].move()
prebuild()
engine()

View File

@ -0,0 +1,303 @@
# Snake from Golem64
# https://my.numworks.com/python/golem64/snake
#Version 1.7 STABLE
#Tip: You should try to press
#some keys in the menu...
from random import *
from kandinsky import *
from ion import *
from time import *
#from pomme import *
def oscolor():
try:
get_keys()
except:
return 'orange'
else:
return 'red'
def lastPos(i,x,y):
if i[-1]==3:
pos=[x-10,y]
elif i[-1]==2:
pos=[x,y-10]
elif i[-1]==0:
pos=[x+10,y]
elif i[-1]==1:
pos=[x,y+10]
pos[0],pos[1]=checkTeleport(pos[0],pos[1])
return pos
def newApple(appleC,bgC):
applex=randint(0,31)*10+4
appley=randint(0,21)*10+5
while get_pixel(applex,appley)!=bgC:
applex=randint(0,31)*10+4
appley=randint(0,21)*10+5
fill_rect(applex-4,appley-4,10,10,appleC)
return applex,appley
def checkTeleport(x,y):
if x<4:
x=314
if x>314:
x=4
if y<5:
y=215
if y>215:
y=5
return x,y
def getMove(u):
for k in range(4):
if keydown(k)==True and u+k!=3: return k
return u
def clearDraw(): fill_rect(0,0,320,222,(255,255,255))
def clearHome(): print("\n \n \n \n \n \n \n \n \n \n \n \n \n ")
def redraw():
draw_string("(DELETE to exit)",0,0)
printLetter([1,1,1,1,0,0,1,1,1,0,0,1,1,1,1],70,80,10,(0,204,0))
fill_rect(95,80,2,4,(0,0,0))
fill_rect(95,86,2,4,(0,0,0))
fill_rect(100,84,4,2,(255,0,0))
fill_rect(104,82,2,2,(255,0,0))
fill_rect(104,86,2,2,(255,0,0))
printLetter([1,1,1,1,0,1,1,0,1,1,0,1,1,0,1],110,80,10,(0,0,0))
printLetter([1,1,1,1,0,1,1,1,1,1,0,1,1,0,1],150,80,10,(0,0,0))
printLetter([1,0,1,1,0,1,1,1,0,1,0,1,1,0,1],190,80,10,(0,0,0))
printLetter([1,1,1,1,0,0,1,1,1,1,0,0,1,1,1],230,80,10,(0,0,0))
def printLetter(letter,x,y,size,color):
for yi in range(5):
for xi in range(3):
if letter[yi*3+xi]==1:
fill_rect(x+(xi*size),y+(yi*size),size,size,color)
def menu():
clearDraw()
printLetter([1,1,1,1,0,1,1,0,1,1,0,1,1,0,1],110,80,10,(0,0,0))
printLetter([1,1,1,1,0,1,1,1,1,1,0,1,1,0,1],150,80,10,(0,0,0))
printLetter([1,0,1,1,0,1,1,1,0,1,0,1,1,0,1],190,80,10,(0,0,0))
printLetter([1,1,1,1,0,0,1,1,1,1,0,0,1,1,1],230,80,10,(0,0,0))
anim=[1,1,1,1,1,1,1,1,1,4,4,3,3,4,4,1,1]
ax=0
ay=120
aendx=-110
aendy=120
u=1
aback=0
for i in range(len(anim)):
ax=ax+((anim[i]==1)-(anim[i]==3))*10
ay=ay+((anim[i]==2)-(anim[i]==4))*10
if aendx<0:
aendx=aendx+10
else:
aendx=aendx+((anim[i-11]==1)-(anim[i-11]==3))*10
aendy=aendy+((anim[i-11]==2)-(anim[i-11]==4))*10
fill_rect(aendx,aendy,10,10,(255,255,255))
fill_rect(ax,ay,10,10,(0,204,0))
# aback=lastPos(anim,ax,ay)
# if u==26 or u==24:
# fill_rect(ax-1,ay-1,3,1,(0,0,0))
# fill_rect(ax-1,ay+1,3,1,(0,0,0))
# fill_rect(aback[0],aback[1],10,10,(0,204,0))
# elif u==34 or u==25:
# fill_rect(ax-1,ay-1,1,3,(0,0,0))
# fill_rect(ax+1,ay-1,1,3,(0,0,0))
# fill_rect(aback[0]-2,aback[1]-2,5,5,(0,204,0))
sleep(0.05)
fill_rect(ax+5,ay,2,4,(0,0,0))
fill_rect(ax+5,ay+6,2,4,(0,0,0))
fill_rect(ax+10,ay+4,4,2,(255,0,0))
fill_rect(ax+14,ay+2,2,2,(255,0,0))
fill_rect(ax+14,ay+6,2,2,(255,0,0))
draw_string("(DELETE to exit)",0,0)
draw_string("> Play <",125,140,oscolor())
draw_string(" Options ",110,165)
darkMode=0
Speed=0.05
power=5
score=1
exit=0
sel=1
while keydown(KEY_OK)!=True and exit==0:
if keydown(KEY_DOWN) and sel==1:
draw_string(" Play ",125,140)
draw_string("> Options <",110,165,oscolor())
sel=2
elif keydown(KEY_UP) and sel==2:
draw_string("> Play <",125,140,oscolor())
draw_string(" Options ",110,165)
sel=1
if keydown(KEY_LEFTPARENTHESIS) and keydown(KEY_RIGHTPARENTHESIS):
draw_string("Dark mode enabled !",80,195)
darkMode=1
if keydown(KEY_BACKSPACE):
exit=1
sleep(0.1)
if sel==2 and exit!=1:
fill_rect(0,130,300,60,(255,255,255))
Speed=0.05
power=5
score=1
draw_string("Speed:"+str(Speed),50,140,oscolor(),'white')
draw_string("Power:+"+str(power),200,140)
draw_string("Score:+"+str(score),50,170)
draw_string("Play",220,170)
sel=1
sleep(0.2)
while keydown(KEY_OK)!=True or sel!=4:
if keydown(KEY_RIGHT):
sel=sel+1
elif keydown(KEY_DOWN):
sel=sel+2
elif keydown(KEY_LEFT):
sel=sel-1
elif keydown(KEY_UP):
sel=sel-2
if sel<0:
sel=0
if sel>4:
sel=4
if sel==1:
draw_string("Speed:"+str(Speed),50,140,oscolor(),'white')
draw_string("Power:+"+str(power),200,140)
draw_string("Score:+"+str(score),50,170)
draw_string("Play",220,170)
if keydown(KEY_OK):
clearHome()
Speed=input("Speed:")
redraw()
elif sel==2:
draw_string("Speed:"+str(Speed),50,140)
draw_string("Power:+"+str(power),200,140,oscolor(),'white')
draw_string("Score:+"+str(score),50,170)
draw_string("Play",220,170)
if keydown(KEY_OK):
clearHome()
power=int(input("Power:+"))
redraw()
elif sel==3:
draw_string("Speed:"+str(Speed),50,140)
draw_string("Power:+"+str(power),200,140)
draw_string("Score:+"+str(score),50,170,oscolor(),'white')
draw_string("Play",220,170)
if keydown(KEY_OK):
clearHome()
score=int(input("Score:"))
redraw()
elif sel==4:
draw_string("Speed:"+str(Speed),50,140)
draw_string("Power:+"+str(power),200,140)
draw_string("Score:+"+str(score),50,170)
draw_string("Play",220,170,oscolor(),'white')
if (keydown(KEY_LEFTPARENTHESIS) and keydown(KEY_RIGHTPARENTHESIS)) or darkMode==1:
draw_string("Dark mode enabled !",80,195)
darkMode=1
if keydown(KEY_BACKSPACE):
exit=1
break
sleep(0.1)
if exit!=1:
if darkMode==1:
launch(1,Speed,power,score)
elif darkMode==0:
launch(0,Speed,power,score)
elif exit==1:
clearDraw()
return
def launch(darkmode=0,speed=0.05,applePower=5,appleScore=1):
bgC=(248,252,248)
borderC=(0,0,0)
snakeC=(0,204,0)
appleC=(248,0,0)
if darkmode==1:
bgC=(0,0,0)
borderC=(0,0,204)
fill_rect(0,0,320,222,bgC)
# fill_rect(315,0,5,222,borderC)
# fill_rect(0,0,5,222,borderC)
# fill_rect(0,0,320,1,(197,52,49))
fill_rect(0,221,320,1,(0,0,0))
try:
get_keys()
except:
fill_rect(0,0,320,1,(255,181,49))
else:
fill_rect(0,0,320,1,(197,52,49))
snake=[3,3,3,3,3]
x=154
y=115
endx=104
endy=115
u,v=3,3
length=5
applex,appley=newApple(appleC,bgC)
score,touched=0,0
while touched!=borderC and touched!=snakeC:
if keydown(0) or keydown(1) or keydown(2) or keydown(3):
u=getMove(u)
if keydown(KEY_BACKSPACE):
while keydown(KEY_BACKSPACE):
sleep(0.1)
while keydown(KEY_BACKSPACE)!=True:
sleep(0.1)
while keydown(KEY_BACKSPACE):
sleep(0.1)
snake.append(u)
if x==applex and y==appley:
length=length+float(applePower)
applex,appley=newApple(appleC,bgC)
score=score+int(appleScore)
x=x+((u==3)-(u==0))*10
y=y+((u==2)-(u==1))*10
x,y=checkTeleport(x,y)
if length:
length=length-1
else:
snake.remove(snake[0])
endx=endx+((v==3)-(v==0))*10
endy=endy+((v==2)-(v==1))*10
endx,endy=checkTeleport(endx,endy)
v=snake[0]
fill_rect(endx-4,endy-4,10,10,bgC)
touched=get_pixel(x,y)
if x<0 or x>320 or y<0 or y>220:
touched=borderC
if touched!=appleC and touched!=bgC:
touched=borderC
fill_rect(x-4,y-4,10,10,snakeC)
back=lastPos(snake,x,y)
if u==3 or u==0:
fill_rect(x,y-4,2,4,(0,0,0))
fill_rect(x,y+2,2,4,(0,0,0))
fill_rect(back[0]-4,back[1]-4,10,10,snakeC)
elif u==2 or u==1:
fill_rect(x-4,y,4,2,(0,0,0))
fill_rect(x+2,y,4,2,(0,0,0))
fill_rect(back[0]-4,back[1]-4,10,10,snakeC)
sleep(float(speed))
# EPILEPSY WARNING !!!
# snakeC=(randint(0,255),randint(0,255),randint(0,255))
while snakeC==appleC or snakeC==bgC:
snakeC=(randint(0,255),randint(0,255),randint(0,255))
# beau()
if len(snake)==640:
if darkmode==1:
draw_string("You win !",120,100,'white','black')
draw_string("(You reached the max length)",20,120,'white','black')
else:
draw_string("You win !",120,100)
draw_string("(You reached the max length)",20,120)
touched=borderC
if darkmode==1:
draw_string("Score:"+str(score),10,10,'white','black')
draw_string("(OK=play again, DELETE=Menu)",10,30,'white','black')
else:
draw_string("Score:"+str(score),10,10)
draw_string("(OK=play again, DELETE=Menu)",10,30)
choice=0
while choice==0:
if keydown(KEY_OK):
choice=1
launch(darkmode,speed,applePower,appleScore)
elif keydown(KEY_BACKSPACE):
choice=2
menu()
print("Score:",score)
menu()

View File

@ -0,0 +1,27 @@
# This script draws a Mandelbrot fractal set
# N_iteration: degree of precision
import kandinsky
import ion
import time
N_iteration = 10
for x in range(320):
for y in range(222):
# Compute the mandelbrot sequence for the point c = (c_r, c_i) with start value z = (z_r, z_i)
z = complex(0,0)
# Rescale to fit the drawing screen 320x222
c = complex(3.5*x/319-2.5, -2.5*y/221+1.25)
i = 0
while (i < N_iteration) and abs(z) < 2:
i = i + 1
z = z*z+c
# Choose the color of the dot from the Mandelbrot sequence
rgb = int(255*i/N_iteration)
col = kandinsky.color(int(rgb),int(rgb*0.75),int(rgb*0.25))
# Draw a pixel colored in 'col' at position (x,y)
kandinsky.set_pixel(x,y,col)
while not ion.keydown(ion.KEY_EXE):
time.sleep(0.1)

View File

@ -0,0 +1,46 @@
from kandinsky import *
from gint import *
draw_string( "Hello Kandinsky", 10, 10, "white", "red" )
draw_string( "Hello Kandinsky", 10, 200, "k" )
fill_rect( 25, 25, 100, 100, 00000 )
fill_rect( 60, 25, 10, 100, 65000 )
fill_rect( 25, 60, 100, 10, 00031 )
fill_rect( 100, 100, 25, 25, "green" )
fill_rect( 200, 100, 25, 25, (255,255,0) )
fill_rect( 200, 50, 25, 25, (128,0,255) )
set_pixel( 150, 150, "red" )
set_pixel( 160, 160, (0,0,255) )
# The following functions are only valid on fxCG (this is an extension of Kandinsky to take benefit of wide screen
color = "black"
if CGEXT_Is_Wide_Screen_Enabled() :
color = "red"
fill_rect( -100, 150, 500, 10, color )
CGEXT_Enable_Wide_Screen()
if CGEXT_Is_Wide_Screen_Enabled() :
color = "green"
else :
color = "purple"
fill_rect( -100, 165, 500, 10, color )
CGEXT_Disable_Wide_Screen()
if CGEXT_Is_Wide_Screen_Enabled() :
color = "blue"
else :
color = "red"
fill_rect( -100, 180, 500, 10, color )
getkey()

View File

@ -0,0 +1,227 @@
# PacMan par Kevin FEDYNA
# https://nsi.xyz/numapps/pac-man-en-python-numworks/
# converti sur fxCG50 et PythonExtra par SlyVTT
from kandinsky import fill_rect, draw_string
from ion import keydown, KEY_LEFT, KEY_UP, KEY_DOWN, KEY_RIGHT
from math import sqrt
from random import randint
from time import monotonic
try:
from kandinsky import get_keys
color = (192, 53, 53)
except:
color = (255, 183, 52)
terrain = (262143,131841,187245,187245,131073,186285,135969,252783,249903,251823,1152,251823,249903,251823,131841,187245,147465,219051,135969,195453,131073,262143)
bits = 18
width = 320
height = 222
colors = ((0, 0, 0), (32, 48, 248), (248, 224, 8), tuple(color))
ghost_color = ((255, 184, 255), (255, 0,0), (255, 184, 82), (0, 255, 255))
pacgommes = [0,130302,9360,74898,131070,75858,126174,8208,8208,8208,8208,8208,8208,8208,130302,74898,49140,43092,126174,66690,131070,0]
superpacgommes = [0,0,65538,0,0,0,0,0,0,0,0,0,0,0,0,0,65538,0,0,0,0,0,0]
frightened = 0
lives = 2
won = 0
lvl = 0
score = 0
chained = 0
class Entity:
def __init__(self, x, y, clr, d=0):
self.x = x
self.y = y
self.d = d
self.nd = d
self.f = 0
self.out = 0
self.color = clr
fill_rect(int(self.x*10)+136,int(self.y*10)-3,8,8,self.color)
def espace(self,dx=-1,dy=-1):
if dx == dy:
dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[self.nd]
return not terrain[int(self.y + 5.5*dy)]>>(bits-1-int(self.x + 5.5*dx)) & 1 and ((dx != 0 and self.y%1 == 0.5) or (dy != 0 and self.x%1== 0.5))
def move(self):
global frightened, ghosts, score, chained, lives, total, won
dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[self.d]
if self.espace(dx,dy):
fill_rect(int(self.x*10)+136,int(self.y*10)-3,8,8,colors[0])
self.x = (round(self.x + dx, 1) - 0.5) % 16.5 + 0.5
self.y = round(self.y + dy, 1)
fill_rect(int(self.x*10)+136,int(self.y*10)-3,8,8,self.color)
if self.color == colors[2]:
if pacgommes[int(self.y)] >> (bits - 1 - int(self.x)) & 1:
pacgommes[int(self.y)] -= 1 << (bits - 1 - int(self.x))
score += 10
if superpacgommes[int(self.y)] >> (bits - 1 - int(self.x)) & 1:
superpacgommes[int(self.y)] -= 1 << (bits - 1 - int(self.x))
score += 50
chained = 0
frightened = monotonic()
for g in ghosts:
if g.out:
g.color = colors[1]
g.d = (3, 2, 1, 0)[g.d]
g.f = 1
for g in range(4):
if sqrt((self.x-ghosts[g].x)**2+(self.y-ghosts[g].y)**2) < 0.6:
if ghosts[g].f:
chained += 1
total += 1
score += (1 << chained)*100
ghosts[g].f = 0
ghosts[g].color = ghost_color[g]
ghosts[g].x = 9
ghosts[g].y = 8.5
if total == 16:
score += 12000
else:
for gp in range(4):
ghosts[gp].f = 0
ghosts[gp].color = ghost_color[gp]
ghosts[gp].x = 9
ghosts[gp].y = 10.5
ghosts[gp].out = 0
self.x = 9
self.y = 16.5
self.d, self.nd = 0, 0
lives -= 1
return render()
if not won and score > 10000:
lives += 1
won = 1
px, py = int(self.x - 5.5*dx), int(self.y - 5.5*dy)
if pacgommes[py]>>(bits-1-px) & 1:
fill_rect(px*10+144,py*10+5,2,2,(250, 207, 173))
if superpacgommes[py]>>(bits-1-px) & 1:
fill_rect(px*10+143,py*10+4,4,4,(250, 207, 173))
def ia(self,x,y):
if self.f:
while True:
d = randint(0,3)
dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[d]
if d != (3,2,1,0)[self.d] and self.espace(dx,dy):
self.d = d
break
else:
distances = [9999 for _ in range(4)]
for i in range(4):
if i != (3,2,1,0)[self.d]:
dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[i]
if self.espace(dx,dy):
distances[i] = sqrt((self.y + dy - y)**2 + (self.x + dx - x)**2)
self.d = distances.index(min(distances))
def prebuild():
fill_rect(0,0,width,height,colors[0])
fill_rect(138, 0, 2, height, colors[3])
draw_string("PAC-MAN", 35, 10, colors[3], colors[0])
draw_string("nsi.xyz/pacman", 0, 204,colors[0], colors[3])
draw_string("Score :", 35, 40, (255,)*3, colors[0])
draw_string("Niveau :", 30, 90, (255,)*3, colors[0])
def render():
global terrain, pacgommes, superpacgommes, lives, arrivee
if lives == -1:
return 42
draw_string(str(lvl),70-5*len(str(lvl)),110,(255,)*3,colors[0])
fill_rect(0,150,138,20,colors[0])
for i in range(lives):
fill_rect(60-(lives-1)*20+i*40,150,20,20,colors[2])
for l in range(len(terrain)):
for c in range(bits):
fill_rect(c*10+140,l*10+1,10,10,colors[0])
if pacgommes[l]>>(bits-1-c) & 1:
fill_rect(c*10+144,l*10+5,2,2,(250, 207, 173))
if superpacgommes[l]>>(bits-1-c) & 1:
fill_rect(c*10+143,l*10+4,4,4,(250, 207, 173))
if terrain[l]>>(bits-1-c) & 1:
for d in ((1,0),(0,1),(-1,0),(0,-1)):
if 0 <= l + d[0] <= len(terrain) - 1 and 0 <= c + d[1] <= bits - 1 and not terrain[l + d[0]]>>(bits-1-(c+d[1])) & 1:
fill_rect(c*10+140+9*(d[1]==1),l*10+1+9*(d[0]==1),1+9*(d[1]==0),1+9*(d[0]==0),colors[1])
arrivee = monotonic()
def engine():
global frightened, ghosts, pacgommes, superpacgommes, lvl, arrivee, total
while True:
pacgommes = [0,130302,9360,74898,131070,75858,126174,8208,8208,8208,8208,8208,8208,8208,130302,74898,49140,43092,126174,66690,131070,0]
superpacgommes = [0,0,65538,0,0,0,0,0,0,0,0,0,0,0,0,0,65538,0,0,0,0,0,0]
lvl += 1
total = 0
render()
pacman = Entity(9, 16.5, colors[2])
ghosts = [Entity(9, 10.5, ghost_color[i]) for i in range(4)]
while sum(pacgommes) + sum(superpacgommes):
depart = monotonic()
lk=[KEY_LEFT, KEY_UP, KEY_DOWN, KEY_RIGHT]
for i in range(4):
if keydown(lk[i]):
if i == (3,2,1,0)[pacman.d]:
pacman.d = i
pacman.nd = i
while monotonic() - depart < 0.01:
if pacman.espace():
pacman.d = pacman.nd
if pacman.move() == 42:
draw_string("GAME OVER",185,100,colors[3],colors[0])
return 69
draw_string(str(score),70-5*len(str(score)),60,(255,)*3,colors[0])
""" Fantomes """
if frightened:
if monotonic() - frightened > 6.5:
for g in ghosts:
if g.f:
g.color = (255,)*3
if monotonic() - frightened > 8.5:
frightened = 0
for g in range(4):
ghosts[g].color = ghost_color[g]
ghosts[g].f = 0
if arrivee:
if monotonic() - arrivee > 0 and not ghosts[1].out:
ghosts[1].out = 1
ghosts[1].y = 8.5
if monotonic() - arrivee > 2.5 and not ghosts[0].out:
ghosts[0].out = 1
ghosts[0].y = 8.5
if monotonic() - arrivee > 5 and not ghosts[3].out:
ghosts[3].out = 1
ghosts[3].y = 8.5
if monotonic() - arrivee > 7.5 and not ghosts[2].out:
ghosts[2].out = 1
ghosts[2].y = 8.5
fill_rect(220,101,20,10,colors[0])
arrivee = 0
pdx, pdy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[pacman.d]
# Pinky
ghosts[0].ia(pacman.x + 20 * pdx, pacman.y + 20 * pdy)
ghosts[0].move()
# Inky
ghosts[3].ia(max(min(ghosts[1].x + 2*(pacman.x + 20 * pdx - ghosts[1].x), 16.5), 1.5), max(min(ghosts[1].y +2*(pacman.y + 20 * pdy - ghosts[1].y), 21.5), 1.5))
ghosts[3].move()
# Blinky
ghosts[1].ia(pacman.x, pacman.y)
ghosts[1].move()
# Clyde
if sqrt((ghosts[2].x - pacman.x)**2 + (ghosts[2].y - pacman.y)**2) > 4:
ghosts[2].ia(pacman.x, pacman.y)
else:
ghosts[2].ia(1.5, 20.5)
ghosts[2].move()
fill_rect(0,0,319,219,"black")
prebuild()
engine()

View File

@ -0,0 +1,77 @@
from kandinsky import *
from math import *
import ion
import time
def cercle1(x0,y0,r,c,e):
for i in range(2*e):
xd=x0-int((r-i*0.5)/sqrt(2))
xf=x0+int((r-i*0.5)/sqrt(2))
for x in range(xd,xf+1):
x1=x
y1=y0+int(sqrt((r-i*0.5)**2-(x-x0)**2))
if sqrt((160-x1)**2+(111-y1)**2)<r:
set_pixel(x1,y1,c)
for j in range(3):
x2=x0+y1-y0
y2=y0+x0-x1
if sqrt((160-x2)**2+(111-y2)**2)<r:
set_pixel(x2,y2,c)
x1,y1=x2,y2
def cercle2(x0,y0,r,c,e):
for i in range(2*e):
xd=x0-int((r-i*0.5)/sqrt(2))
xf=x0+int((r-i*0.5)/sqrt(2))
for x in range(xd,xf+1):
x1=x
y1=y0+int(sqrt((r-i*0.5)**2-(x-x0)**2))
set_pixel(x,y1,c)
for j in range(3):
x2=x0+y1-y0
y2=y0+x0-x1
set_pixel(x2,y2,c)
x1,y1=x2,y2
def rosace1(n,r,c,e):
x,y=160+r,111
for i in range(n):
x1=int(160+r*cos(i*2*pi/n))
y1=int(111+r*sin(i*2*pi/n))
cercle1(x1,y1,r,c,e)
cercle1(160,111,r,c,e)
def rosace2(n,r,c,e):
x,y=160+r,111
for i in range(n):
x1=int(160+r*cos(i*2*pi/n))
y1=int(111+r*sin(i*2*pi/n))
cercle2(x1,y1,r,c,e)
def rosace3(n,r,c1,c2,c3,e):
for k in range(2):
rj=r
for j in range(n-2):
rj=int(rj-rj/(2*n))
if k==0:rj+=1
x,y=160+rj,111
for i in range(n):
x1=int(160+rj*cos(i*2*pi/n))
y1=int(111+rj*sin(i*2*pi/n))
if k==0:
col=c3
else:
if j==0 or j>n-4:col=c2
else:col=c1
cercle2(x1,y1,rj,col,e)
col1=color(5,50,120)
col2=color(255,45,45)
col3=color(245,225,25)
#rosace1(12,50,col1,2)
#rosace2(12,50,col1,1)
rosace3(10,55,col1,col2,col3,1)
while not ion.keydown(ion.KEY_EXE):
time.sleep(0.1)

View File

@ -0,0 +1,326 @@
# Snake from Golem64
# https://my.numworks.com/python/golem64/snake
#
# converted to PythonExtra on fx-CG50 by SlyVTT
#
# Version 1.7 STABLE
# Tip: You should try to press
# some keys in the menu...
from random import *
from kandinsky import *
from ion import *
from time import *
def oscolor():
try:
get_keys()
except:
return 'orange'
else:
return 'red'
def lastPos(i,x,y):
if i[-1]==3:
pos=[x-10,y]
elif i[-1]==2:
pos=[x,y-10]
elif i[-1]==0:
pos=[x+10,y]
elif i[-1]==1:
pos=[x,y+10]
pos[0],pos[1]=checkTeleport(pos[0],pos[1])
return pos
def newApple(appleC,bgC):
applex=randint(0,31)*10+4
appley=randint(0,21)*10+5
while get_pixel(applex,appley)!=bgC:
applex=randint(0,31)*10+4
appley=randint(0,21)*10+5
fill_rect(applex-4,appley-4,10,10,appleC)
return applex,appley
def checkTeleport(x,y):
if x<4:
x=314
if x>314:
x=4
if y<5:
y=215
if y>215:
y=5
return x,y
def getMove(u):
lk=[KEY_LEFT, KEY_UP, KEY_DOWN, KEY_RIGHT]
for k in range(4):
if keydown(lk[k])==True and u+k!=3: return k
return u
def clearDraw():
fill_rect(0,0,320,222,(255,255,255))
def clearHome():
print("\n \n \n \n \n \n \n \n \n \n \n \n \n ")
def redraw():
draw_string("(DELETE to exit)",0,0)
printLetter([1,1,1,1,0,0,1,1,1,0,0,1,1,1,1],70,80,10,(0,204,0))
fill_rect(95,80,2,4,(0,0,0))
fill_rect(95,86,2,4,(0,0,0))
fill_rect(100,84,4,2,(255,0,0))
fill_rect(104,82,2,2,(255,0,0))
fill_rect(104,86,2,2,(255,0,0))
printLetter([1,1,1,1,0,1,1,0,1,1,0,1,1,0,1],110,80,10,(0,0,0))
printLetter([1,1,1,1,0,1,1,1,1,1,0,1,1,0,1],150,80,10,(0,0,0))
printLetter([1,0,1,1,0,1,1,1,0,1,0,1,1,0,1],190,80,10,(0,0,0))
printLetter([1,1,1,1,0,0,1,1,1,1,0,0,1,1,1],230,80,10,(0,0,0))
def printLetter(letter,x,y,size,color):
for yi in range(5):
for xi in range(3):
if letter[yi*3+xi]==1:
fill_rect(x+(xi*size),y+(yi*size),size,size,color)
def menu():
clearDraw()
printLetter([1,1,1,1,0,1,1,0,1,1,0,1,1,0,1],110,80,10,(0,0,0))
printLetter([1,1,1,1,0,1,1,1,1,1,0,1,1,0,1],150,80,10,(0,0,0))
printLetter([1,0,1,1,0,1,1,1,0,1,0,1,1,0,1],190,80,10,(0,0,0))
printLetter([1,1,1,1,0,0,1,1,1,1,0,0,1,1,1],230,80,10,(0,0,0))
anim=[1,1,1,1,1,1,1,1,1,4,4,3,3,4,4,1,1]
ax=0
ay=120
aendx=-110
aendy=120
u=1
aback=0
for i in range(len(anim)):
ax=ax+((anim[i]==1)-(anim[i]==3))*10
ay=ay+((anim[i]==2)-(anim[i]==4))*10
if aendx<0:
aendx=aendx+10
else:
aendx=aendx+((anim[i-11]==1)-(anim[i-11]==3))*10
aendy=aendy+((anim[i-11]==2)-(anim[i-11]==4))*10
fill_rect(aendx,aendy,10,10,(255,255,255))
fill_rect(ax,ay,10,10,(0,204,0))
# aback=lastPos(anim,ax,ay)
# if u==26 or u==24:
# fill_rect(ax-1,ay-1,3,1,(0,0,0))
# fill_rect(ax-1,ay+1,3,1,(0,0,0))
# fill_rect(aback[0],aback[1],10,10,(0,204,0))
# elif u==34 or u==25:
# fill_rect(ax-1,ay-1,1,3,(0,0,0))
# fill_rect(ax+1,ay-1,1,3,(0,0,0))
# fill_rect(aback[0]-2,aback[1]-2,5,5,(0,204,0))
sleep(0.05)
fill_rect(ax+5,ay,2,4,(0,0,0))
fill_rect(ax+5,ay+6,2,4,(0,0,0))
fill_rect(ax+10,ay+4,4,2,(255,0,0))
fill_rect(ax+14,ay+2,2,2,(255,0,0))
fill_rect(ax+14,ay+6,2,2,(255,0,0))
draw_string("(DELETE to exit)",0,0)
draw_string("> Play <",125,140,oscolor())
draw_string(" Options ",110,165)
darkMode=0
Speed=0.05
power=5
score=1
exit=0
sel=1
while keydown(KEY_OK)!=True and exit==0:
if keydown(KEY_DOWN) and sel==1:
draw_string(" Play ",125,140)
draw_string("> Options <",110,165,oscolor())
sel=2
elif keydown(KEY_UP) and sel==2:
draw_string("> Play <",125,140,oscolor())
draw_string(" Options ",110,165)
sel=1
if keydown(KEY_LEFTPARENTHESIS) and keydown(KEY_RIGHTPARENTHESIS):
draw_string("Dark mode enabled !",80,195)
darkMode=1
if keydown(KEY_BACKSPACE):
exit=1
sleep(0.1)
if sel==2 and exit!=1:
fill_rect(0,130,300,60,(255,255,255))
Speed=0.05
power=5
score=1
draw_string("Speed:"+str(Speed),50,140,oscolor(),'white')
draw_string("Power:+"+str(power),200,140)
draw_string("Score:+"+str(score),50,170)
draw_string("Play",220,170)
sel=1
sleep(0.2)
while keydown(KEY_OK)!=True or sel!=4:
if keydown(KEY_RIGHT):
sel=sel+1
elif keydown(KEY_DOWN):
sel=sel+2
elif keydown(KEY_LEFT):
sel=sel-1
elif keydown(KEY_UP):
sel=sel-2
if sel<0:
sel=0
if sel>4:
sel=4
if sel==1:
draw_string("Speed:"+str(Speed),50,140,oscolor(),'white')
draw_string("Power:+"+str(power),200,140)
draw_string("Score:+"+str(score),50,170)
draw_string("Play",220,170)
if keydown(KEY_OK):
clearHome()
Speed=input("Speed:")
redraw()
elif sel==2:
draw_string("Speed:"+str(Speed),50,140)
draw_string("Power:+"+str(power),200,140,oscolor(),'white')
draw_string("Score:+"+str(score),50,170)
draw_string("Play",220,170)
if keydown(KEY_OK):
clearHome()
power=int(input("Power:+"))
redraw()
elif sel==3:
draw_string("Speed:"+str(Speed),50,140)
draw_string("Power:+"+str(power),200,140)
draw_string("Score:+"+str(score),50,170,oscolor(),'white')
draw_string("Play",220,170)
if keydown(KEY_OK):
clearHome()
score=int(input("Score:"))
redraw()
elif sel==4:
draw_string("Speed:"+str(Speed),50,140)
draw_string("Power:+"+str(power),200,140)
draw_string("Score:+"+str(score),50,170)
draw_string("Play",220,170,oscolor(),'white')
if (keydown(KEY_LEFTPARENTHESIS) and keydown(KEY_RIGHTPARENTHESIS)) or darkMode==1:
draw_string("Dark mode enabled !",80,195)
darkMode=1
if keydown(KEY_BACKSPACE):
exit=1
break
sleep(0.1)
if exit!=1:
if darkMode==1:
launch(1,Speed,power,score)
elif darkMode==0:
launch(0,Speed,power,score)
elif exit==1:
clearDraw()
return
def launch(darkmode=0,speed=0.05,applePower=5,appleScore=1):
bgC=(248,252,248)
borderC=(0,0,0)
snakeC=(0,204,0)
appleC=(248,0,0)
if darkmode==1:
bgC=(0,0,0)
borderC=(0,0,204)
fill_rect(0,0,320,222,bgC)
# fill_rect(315,0,5,222,borderC)
# fill_rect(0,0,5,222,borderC)
# fill_rect(0,0,320,1,(197,52,49))
fill_rect(0,221,320,1,(0,0,0))
try:
get_keys()
except:
fill_rect(0,0,320,1,(255,181,49))
else:
fill_rect(0,0,320,1,(197,52,49))
snake=[3,3,3,3,3]
x=154
y=115
endx=104
endy=115
u,v=3,3
length=5
applex,appley=newApple(appleC,bgC)
score,touched=0,0
while touched!=borderC and touched!=snakeC:
if keydown(KEY_LEFT) or keydown(KEY_UP) or keydown(KEY_DOWN) or keydown(KEY_RIGHT):
u=getMove(u)
if keydown(KEY_BACKSPACE):
while keydown(KEY_BACKSPACE):
sleep(0.1)
while keydown(KEY_BACKSPACE)!=True:
sleep(0.1)
while keydown(KEY_BACKSPACE):
sleep(0.1)
snake.append(u)
if x==applex and y==appley:
length=length+float(applePower)
applex,appley=newApple(appleC,bgC)
score=score+int(appleScore)
x=x+((u==3)-(u==0))*10
y=y+((u==2)-(u==1))*10
x,y=checkTeleport(x,y)
if length:
length=length-1
else:
snake.remove(snake[0])
endx=endx+((v==3)-(v==0))*10
endy=endy+((v==2)-(v==1))*10
endx,endy=checkTeleport(endx,endy)
v=snake[0]
fill_rect(endx-4,endy-4,10,10,bgC)
touched=get_pixel(x,y)
if x<0 or x>320 or y<0 or y>220:
touched=borderC
if touched!=appleC and touched!=bgC:
touched=borderC
fill_rect(x-4,y-4,10,10,snakeC)
back=lastPos(snake,x,y)
if u==3 or u==0:
fill_rect(x,y-4,2,4,(0,0,0))
fill_rect(x,y+2,2,4,(0,0,0))
fill_rect(back[0]-4,back[1]-4,10,10,snakeC)
elif u==2 or u==1:
fill_rect(x-4,y,4,2,(0,0,0))
fill_rect(x+2,y,4,2,(0,0,0))
fill_rect(back[0]-4,back[1]-4,10,10,snakeC)
sleep(float(speed))
# EPILEPSY WARNING !!!
# snakeC=(randint(0,255),randint(0,255),randint(0,255))
while snakeC==appleC or snakeC==bgC:
snakeC=(randint(0,255),randint(0,255),randint(0,255))
# beau()
if len(snake)==640:
if darkmode==1:
draw_string("You win !",120,100,'white','black')
draw_string("(You reached the max length)",20,120,'white','black')
else:
draw_string("You win !",120,100)
draw_string("(You reached the max length)",20,120)
touched=borderC
if darkmode==1:
draw_string("Score:"+str(score),10,10,'white','black')
draw_string("(OK=play again, DELETE=Menu)",10,30,'white','black')
else:
draw_string("Score:"+str(score),10,10)
draw_string("(OK=play again, DELETE=Menu)",10,30)
choice=0
while choice==0:
if keydown(KEY_OK):
choice=1
launch(darkmode,speed,applePower,appleScore)
elif keydown(KEY_BACKSPACE):
choice=2
menu()
print("Score:",score)
try:
CGEXT_Set_Margin_Color( "black" )
except:
print("fxCG Extension not supported")
menu()

View File

@ -0,0 +1,15 @@
from time import *
print(monotonic())
sleep(1)
print(monotonic())
sleep(2)
print(monotonic())
sleep(1)
print(monotonic())

View File

@ -18,6 +18,7 @@
#include <gint/keyboard.h>
#include <gint/kmalloc.h>
#include <gint/fs.h>
#include <gint/timer.h>
#include <justui/jscene.h>
#include <justui/jlabel.h>
@ -57,6 +58,14 @@ widget_shell *pe_shell;
struct pe_globals PE = { 0 };
// TODO : make this more clean by putting these globals into pe_globals and
// making this accessible to modules
bool is_dwindowed = false;
bool is_timered = false;
unsigned int timer_altered[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
bool is_refreshed_required = false;
//=== Hook for redirecting stdout/stderr to the shell ===//
static ssize_t stdouterr_write(void *data, void const *buf, size_t size)
@ -170,6 +179,15 @@ void pe_enter_graphics_mode(void)
PE.shell->widget.update = 0;
}
void pe_refresh_graphics(void)
{
/* refresh graphical output on request by setting
is_refresh_graphics to true */
dupdate();
pe_debug_run_videocapture();
is_refreshed_required = false;
}
void pe_draw(void)
{
dclear(C_WHITE);
@ -194,6 +212,31 @@ void pe_draw(void)
//=== Application control functions ===//
void pe_restore_window_and_timer(void)
{
if (is_dwindowed)
{
struct dwindow win;
win.left = 0;
win.top = 0;
win.right = DWIDTH;
win.bottom = DHEIGHT;
dwindow_set(win);
is_dwindowed = false; // we mark as not windowed
}
if (is_timered)
{
for (int u = 0; u < 9; u++)
if (timer_altered[u] == 1)
timer_stop(u);
is_timered = false;
}
}
static void pe_reset_micropython(void)
{
gc_sweep_all();
@ -290,6 +333,8 @@ static char *pe_handle_event(jevent e, bool shell_bound)
}
free(module);
pe_restore_window_and_timer();
pe_print_prompt(1);
}
}
@ -430,6 +475,13 @@ int main(int argc, char **argv)
- The OS' extra VRAM
- Memory past the 2 MB boundary on tested OSes */
// gc_add(start, end)...
/* TODO : test to check if we can definitely maintain this addition of RAM */
void *uram_area = kmalloc(300000, "_uram");
if(uram_area)
gc_add(uram_area, uram_area+300000);
#endif
mp_init();
@ -501,6 +553,8 @@ int main(int argc, char **argv)
//=== Deinitialization ===//
pe_debug_close();
gc_sweep_all();
mp_deinit();
console_destroy(PE.console);

View File

@ -107,8 +107,11 @@ void pe_after_python_exec(
/* Command executed regularly during execution */
extern void pe_draw(void);
extern widget_shell *pe_shell;
extern void pe_refresh_graphics(void);
extern bool is_refreshed_required;
#define MICROPY_VM_HOOK_LOOP \
{ if(pe_shell->widget.update) pe_draw(); }
{ if(pe_shell->widget.update) pe_draw(); \
if(is_refreshed_required) pe_refresh_graphics(); }
/* extra built in names to add to the global namespace
#define MICROPY_PORT_BUILTINS \
@ -123,3 +126,4 @@ typedef long mp_off_t;
#define MICROPY_HW_MCU_NAME "sh-4a"
#define MP_STATE_PORT MP_STATE_VM

204
ports/sh/numworks/ion.c Normal file
View File

@ -0,0 +1,204 @@
//---------------------------------------------------------------------------//
// ____ PythonExtra //
//.-'`_ o `;__, A community port of MicroPython for CASIO calculators. //
//.-'` `---` ' License: MIT (except some files; see LICENSE) //
//---------------------------------------------------------------------------//
// pe.ion: `gint` module
//
// This module aims to wrap commonly-used gint functions (not all APIs are
// considered relevant for high-level Python development).
//---
#include "console.h"
#include "py/objtuple.h"
#include "py/runtime.h"
#include <gint/keyboard.h>
#include <stdio.h>
#include <stdlib.h>
/* BEGINING OF KEY TRANSLATION */
// the following table aims at providing a keymap for NW on Casio
// line that are commented correspond to keys that are similar (with exact same
// name) between NW and Casio
#define KEY_LEFT 0
#define KEY_UP 1
#define KEY_DOWN 2
#define KEY_RIGHT 3
#define KEY_OK 4
#define KEY_BACK 5
#define KEY_HOME 6
#define KEY_ONOFF 7
/* -- */
#define KEY_SHIFT 12
#define KEY_ALPHA 13
#define KEY_XNT 14
#define KEY_VAR 15
#define KEY_TOOLBOX 16
#define KEY_BACKSPACE 17
#define KEY_EXP 18
#define KEY_LN 19
#define KEY_LOG 20
#define KEY_IMAGINARY 21
#define KEY_COMMA 22
#define KEY_POWER 23
#define KEY_SINE 24
#define KEY_COSINE 25
#define KEY_TANGENT 26
#define KEY_PI 27
#define KEY_SQRT 28
#define KEY_SQUARE 29
#define KEY_SEVEN 30
#define KEY_EIGHT 31
#define KEY_NINE 32
#define KEY_LEFTPARENTHESIS 33
#define KEY_RIGHTPARENTHESIS 34
/* -- */
#define KEY_FOUR 36
#define KEY_FIVE 37
#define KEY_SIX 38
#define KEY_MULTIPLICATION 39
#define KEY_DIVISION 40
/* -- */
#define KEY_ONE 42
#define KEY_TWO 43
#define KEY_THREE 44
#define KEY_PLUS 45
#define KEY_MINUS 46
/* -- */
#define KEY_ZERO 48
#define KEY_DOT 49
#define KEY_EE 50
#define KEY_ANS 51
#define KEY_EXE 52
int KeyTranslationMap[ 53 ] = { 0x85, 0x86, 0x75, 0x76, 0x91, // gint LEFT, UP, DOWN, RIGHT, F1
0x74, 0x84, 0x07, -1, -1, // gint EXIT, MENU, ACON, __, __
-1, -1, 0x81, 0x71, 0x61, // gint __, __, SHIFT, ALPHA, XOT
0x83, 0x82, 0x44, 0x13, 0x63, // gint VARS, OPTN, DEL, EXP, LN
0x62, 0x92, 0x55, 0x73, 0x64, // gint LOG, F2, COMMA, POWER, SIN
0x65, 0x66, 0x93, 0x94, 0x72, // gint COS, TAN, F3, F4, SQUARE
0x41, 0x42, 0x43, 0x53, 0x54, // gint 7, 8, 9, LEFP, RIGHTP
-1, 0x31, 0x32, 0x33, 0x34, // gint __, 4, 5, 6, MUL
0x35, -1, 0x21, 0x22, 0x23, // gint DIV, __, 1, 2, 3
0x24, 0x25, -1, 0x11, 0x12, // gint ADD, SUB, __, 0, DOT
0x95, 0x14, 0x15 }; // gint F5, NEG, EXE
/* END OF KEY TRANSLATION */
#define FUN_0(NAME) MP_DEFINE_CONST_FUN_OBJ_0(ion_##NAME##_obj, ion_##NAME)
#define FUN_1(NAME) MP_DEFINE_CONST_FUN_OBJ_1(ion_##NAME##_obj, ion_##NAME)
#define FUN_2(NAME) MP_DEFINE_CONST_FUN_OBJ_2(ion_##NAME##_obj, ion_##NAME)
#define FUN_3(NAME) MP_DEFINE_CONST_FUN_OBJ_3(ion_##NAME##_obj, ion_##NAME)
#define FUN_VAR(NAME, MIN) \
MP_DEFINE_CONST_FUN_OBJ_VAR(ion_##NAME##_obj, MIN, ion_##NAME)
#define FUN_BETWEEN(NAME, MIN, MAX) \
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ion_##NAME##_obj, MIN, MAX, ion_##NAME)
STATIC mp_obj_t ion___init__(void) { return mp_const_none; }
/* <gint/keyboard.h> */
STATIC mp_obj_t ion_keydown(mp_obj_t arg1) {
mp_int_t key = mp_obj_get_int(arg1);
if (key < KEY_LEFT || key > KEY_EXE )
return mp_obj_new_bool(false);
int translatedKey = KeyTranslationMap[ key ];
if (translatedKey==-1)
return mp_obj_new_bool(false);
clearevents();
bool down = keydown(translatedKey) != 0;
return mp_obj_new_bool(down);
}
FUN_1(keydown);
FUN_0(__init__);
/* Module definition */
// Helper: define object "ion_F_obj" as object "F" in the module
#define OBJ(F) \
{ MP_ROM_QSTR(MP_QSTR_##F), MP_ROM_PTR(&ion_##F##_obj) }
// Helper: define small integer constant "I" as "I" in the module
#define INT(I) \
{ MP_ROM_QSTR(MP_QSTR_##I), MP_OBJ_NEW_SMALL_INT(I) }
STATIC const mp_rom_map_elem_t ion_module_globals_table[] = {
{MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ion)},
OBJ(__init__),
/*Numworks keycodes */
/* BE CAREFUL THERE ARE MISSING SLOTS */
INT(KEY_LEFT), // value 0
INT(KEY_UP),
INT(KEY_DOWN),
INT(KEY_RIGHT),
INT(KEY_OK),
INT(KEY_BACK),
INT(KEY_HOME),
INT(KEY_ONOFF), // value 7
INT(KEY_SHIFT), // value 12
INT(KEY_ALPHA),
INT(KEY_XNT),
INT(KEY_VAR),
INT(KEY_TOOLBOX),
INT(KEY_BACKSPACE),
INT(KEY_EXP),
INT(KEY_LN),
INT(KEY_LOG),
INT(KEY_IMAGINARY),
INT(KEY_COMMA),
INT(KEY_POWER),
INT(KEY_SINE),
INT(KEY_COSINE),
INT(KEY_TANGENT),
INT(KEY_PI),
INT(KEY_SQRT),
INT(KEY_SQUARE),
INT(KEY_SEVEN),
INT(KEY_EIGHT),
INT(KEY_NINE),
INT(KEY_LEFTPARENTHESIS),
INT(KEY_RIGHTPARENTHESIS), // value 34
INT(KEY_FOUR), // value 36
INT(KEY_FIVE),
INT(KEY_SIX),
INT(KEY_MULTIPLICATION),
INT(KEY_DIVISION), // value 40
INT(KEY_ONE), // value 42
INT(KEY_TWO),
INT(KEY_THREE),
INT(KEY_PLUS),
INT(KEY_MINUS), // value 46
INT(KEY_ZERO), // value 48
INT(KEY_DOT),
INT(KEY_EE),
INT(KEY_ANS),
INT(KEY_EXE), // value 52
OBJ(keydown),
};
STATIC MP_DEFINE_CONST_DICT(ion_module_globals, ion_module_globals_table);
const mp_obj_module_t ion_module = {
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&ion_module_globals,
};
MP_REGISTER_MODULE(MP_QSTR_ion, ion_module);

View File

@ -0,0 +1,341 @@
//---------------------------------------------------------------------------//
// ____ PythonExtra //
//.-'`_ o `;__, A community port of MicroPython for CASIO calculators. //
//.-'` `---` ' License: MIT (except some files; see LICENSE) //
//---------------------------------------------------------------------------//
// pe.modkandinsky: Compatibility module for NumWorks Kandinsky library
#include "py/obj.h"
#include "py/runtime.h"
#include <gint/display.h>
#include <gint/drivers/r61524.h>
#include <gint/timer.h>
#include <stdlib.h>
#include <string.h>
extern font_t numworks;
extern bool is_dwindowed;
extern bool is_timered;
extern unsigned int timer_altered[9];
extern bool is_refreshed_required;
#define NW_MAX_X 320
#define NW_MAX_Y 222
/* Parameters used in windowed mode to center the screen of the NW in the fxCG screen*/
#define DELTAXNW ((DWIDTH - NW_MAX_X) / 2) // we center the NW screen on Casio's screen
#define DELTAYNW ((DHEIGHT - NW_MAX_Y) / 2)
/* refresh rate of the screen */
#define TARGET_FPS 20
/* Definition of color on Numworks */
// Data can be found here
// https://github.com/numworks/epsilon/blob/master/escher/include/escher/palette.h
// and here
// https://github.com/numworks/epsilon/blob/master/python/port/port.cpp#L221
#define NW_RGB(r, g, b) (((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3))
#define NW_BLUE NW_RGB(0x50, 0x75, 0xF2)
#define NW_RED NW_RGB(0xFF, 0x00, 0x0C)
#define NW_GREEN NW_RGB(0x50, 0xC1, 0x02)
#define NW_WHITE NW_RGB(0xFF, 0xFF, 0xFF)
#define NW_BLACK NW_RGB(0x00, 0x00, 0x00)
#define NW_YELLOW NW_RGB(0xFF, 0xCC, 0x7B)
#define NW_PURPLE NW_RGB(0x6E, 0x2D, 0x79)
#define NW_BROWN NW_RGB(0x8D, 0x73, 0x50)
#define NW_CYAN NW_RGB(0x00, 0xFF, 0xFF)
#define NW_ORANGE NW_RGB(0xFE, 0x87, 0x1F)
#define NW_PINK NW_RGB(0xFF, 0xAB, 0xB6)
#define NW_MAGENTA NW_RGB(0xFF, 0x05, 0x88)
#define NW_GRAY NW_RGB(0xA7, 0xA7, 0xA7)
// There are possibly some others to be listed correctly
static int callback(void) {
is_refreshed_required = true;
return TIMER_CONTINUE;
}
static mp_obj_t Kandinsky_make_color(color_t color) {
int r, g, b;
r = (color >> 8) & 0xf8;
g = (color >> 3) & 0xfc;
b = (color << 3) & 0xfc;
mp_obj_t items[3] = {
MP_OBJ_NEW_SMALL_INT(r),
MP_OBJ_NEW_SMALL_INT(g),
MP_OBJ_NEW_SMALL_INT(b),
};
return mp_obj_new_tuple(3, items);
}
static mp_obj_t Kandinsky_init(void) {
void pe_enter_graphics_mode(void);
pe_enter_graphics_mode();
dclear(NW_WHITE);
struct dwindow nw;
nw.left = DELTAXNW;
nw.top = DELTAYNW;
nw.right = 320 + DELTAXNW;
nw.bottom = 222 + DELTAYNW;
dwindow_set(nw);
is_dwindowed = true; // we mark as windowed
int t = timer_configure(TIMER_TMU, (1000000/TARGET_FPS), GINT_CALL(callback));
if (t >= 0) {
timer_start(t);
is_timered = true; // there is a timer altered from this module
timer_altered[t] = 1; // we put the corresponding timer at 1 to identify it
}
return mp_const_none;
}
static mp_obj_t Kandinsky_color(size_t n, mp_obj_t const *args) {
int r = mp_obj_get_int(args[0]);
int g = mp_obj_get_int(args[1]);
int b = mp_obj_get_int(args[2]);
int color = NW_RGB(r, g, b);
return mp_obj_new_int(color);
}
int Internal_Get_Color_From_String(const char *str) {
if (strcmp(str, "red") == 0 || strcmp(str, "r") == 0)
return NW_RED;
else if (strcmp(str, "green") == 0 || strcmp(str, "g") == 0)
return NW_GREEN;
else if (strcmp(str, "blue") == 0 || strcmp(str, "b") == 0)
return NW_BLUE;
else if (strcmp(str, "black") == 0 || strcmp(str, "k") == 0)
return NW_BLACK;
else if (strcmp(str, "white") == 0 || strcmp(str, "w") == 0)
return NW_WHITE;
else if (strcmp(str, "yellow") == 0 || strcmp(str, "y") == 0)
return NW_YELLOW;
else if (strcmp(str, "pink") == 0)
return NW_PINK;
else if (strcmp(str, "magenta") == 0)
return NW_MAGENTA;
else if (strcmp(str, "grey") == 0 || strcmp(str, "gray") == 0)
return NW_GRAY;
else if (strcmp(str, "purple") == 0)
return NW_PURPLE;
else if (strcmp(str, "orange") == 0)
return NW_ORANGE;
else if (strcmp(str, "cyan") == 0)
return NW_CYAN;
else if (strcmp(str, "brown") == 0)
return NW_BROWN;
else
return C_NONE;
}
int Internal_Treat_Color(mp_obj_t color) {
const mp_obj_type_t *type = mp_obj_get_type(color);
if (type == &mp_type_str) {
size_t text_len;
char const *text = mp_obj_str_get_data(color, &text_len);
return Internal_Get_Color_From_String(text);
}
else if (type == &mp_type_int)
return mp_obj_get_int(color);
else if (type == &mp_type_tuple) {
size_t tuple_len;
mp_obj_t *items;
mp_obj_tuple_get(color, &tuple_len, &items);
int r = mp_obj_get_int(items[0]);
int g = mp_obj_get_int(items[1]);
int b = mp_obj_get_int(items[2]);
return NW_RGB(r, g, b);
} else
return NW_BLACK;
}
static mp_obj_t Kandinsky_fill_rect(size_t n, mp_obj_t const *args) {
int x = mp_obj_get_int(args[0]) + DELTAXNW;
int y = mp_obj_get_int(args[1]) + DELTAYNW;
int w = mp_obj_get_int(args[2]);
int h = mp_obj_get_int(args[3]);
int color = Internal_Treat_Color(args[4]);
drect(x, y, x + w - 1, y + h - 1, color);
return mp_const_none;
}
static mp_obj_t Kandinsky_set_pixel(size_t n, mp_obj_t const *args) {
int x = mp_obj_get_int(args[0]) + DELTAXNW;
int y = mp_obj_get_int(args[1]) + DELTAYNW;
int color;
if (n == 3)
color = Internal_Treat_Color(args[2]);
else
color = NW_BLACK;
dpixel(x, y, color);
return mp_const_none;
}
static mp_obj_t Kandinsky_get_pixel(mp_obj_t _x, mp_obj_t _y) {
int x = mp_obj_get_int(_x) + DELTAXNW;
int y = mp_obj_get_int(_y) + DELTAYNW;
if ((!is_dwindowed && x >= 0 && x < DWIDTH && y >= 0 && y < DHEIGHT) || (is_dwindowed && x >= 0 && x < NW_MAX_X && y >= 0 && y < NW_MAX_Y)) {
color_t color = gint_vram[DWIDTH * y + x];
return Kandinsky_make_color(color);
}
return Kandinsky_make_color(0x0000);
}
static mp_obj_t Kandinsky_draw_string(size_t n, mp_obj_t const *args) {
int x = mp_obj_get_int(args[1]) + DELTAXNW + 1; // values used to adjust the visual result as per actual NW
int y = mp_obj_get_int(args[2]) + DELTAYNW + 2; // values used to adjust the visual result as per actual NW
size_t text_len;
char const *text = mp_obj_str_get_data(args[0], &text_len);
color_t colortext = NW_BLACK;
if (n >= 4) {
colortext = Internal_Treat_Color(args[3]);
}
color_t colorback = C_NONE;
if (n >= 5) {
colorback = Internal_Treat_Color(args[4]);
}
font_t const *old_font = dfont(&numworks);
int u = 0;
int v = 0;
for (int l = 0; l < (int)text_len; l++) {
if (text[l] == '\n') {
u = 0;
v += 16;
} else {
/* The following test is for support of unicode characters that are encoded on 1 char or more */
/* we need to pass multiple chars to dtext to take care of unicode encoding */
if(((unsigned char) text[l]) >= 0x00 && ((unsigned char) text[l]) <= 0x7F){
drect(x + u - 1, y + v - 1, x + u + 9, y + v + 15, colorback);
dtext_opt(x + u, y + v, colortext, C_NONE, DTEXT_LEFT, DTEXT_TOP, &text[l], 1);
u += 10;
}
else if(((unsigned char) text[l]) >= 0x80 && ((unsigned char) text[l]) <= 0xDF){
drect(x + u - 1, y + v - 1, x + u + 9, y + v + 15, colorback);
dtext_opt(x + u, y + v, colortext, C_NONE, DTEXT_LEFT, DTEXT_TOP, &text[l], 2);
u += 10;
l+=1;
}
else if(((unsigned char) text[l]) >= 0xE0 && ((unsigned char) text[l]) <= 0xEF){
drect(x + u - 1, y + v - 1, x + u + 9, y + v + 15, colorback);
dtext_opt(x + u, y + v, colortext, C_NONE, DTEXT_LEFT, DTEXT_TOP, &text[l], 3);
u += 10;
l+=2;
}
else if(((unsigned char) text[l]) >= 0xF0 && ((unsigned char) text[l]) <= 0xF7){
drect(x + u - 1, y + v - 1, x + u + 9, y + v + 15, colorback);
dtext_opt(x + u, y + v, colortext, C_NONE, DTEXT_LEFT, DTEXT_TOP, &text[l], 4);
u += 10;
l+=3;
}
}
}
dfont(old_font);
return mp_const_none;
}
static mp_obj_t Kandinsky_CGEXT_Enable_Wide_Screen( void ) {
struct dwindow nw;
nw.left = 0;
nw.top = 0;
nw.right = DWIDTH;
nw.bottom = DHEIGHT;
dwindow_set(nw);
is_dwindowed = false; // we mark as not windowed
return mp_const_none;
}
static mp_obj_t Kandinsky_CGEXT_Disable_Wide_Screen( void ) {
struct dwindow nw;
nw.left = DELTAXNW;
nw.top = DELTAYNW;
nw.right = 320 + DELTAXNW;
nw.bottom = 222 + DELTAYNW;
dwindow_set(nw);
is_dwindowed = true; // we mark as windowed
return mp_const_none;
}
static mp_obj_t Kandinsky_CGEXT_Is_Wide_Screen_Enabled( void ) {
return mp_obj_new_bool( is_dwindowed );
}
static mp_obj_t Kandinsky_CGEXT_Set_Margin_Color( mp_obj_t color ) {
color_t colorside = NW_BLACK;
colorside = Internal_Treat_Color(color);
Kandinsky_CGEXT_Enable_Wide_Screen();
dclear(colorside);
Kandinsky_CGEXT_Disable_Wide_Screen();
return mp_obj_new_bool( is_dwindowed );
}
/* Extension of Kandinsky for fxCG - all names starting with "CGEXT_" */
MP_DEFINE_CONST_FUN_OBJ_0(Kandinsky_CGEXT_Enable_Wide_Screen_obj, Kandinsky_CGEXT_Enable_Wide_Screen);
MP_DEFINE_CONST_FUN_OBJ_0(Kandinsky_CGEXT_Disable_Wide_Screen_obj, Kandinsky_CGEXT_Disable_Wide_Screen);
MP_DEFINE_CONST_FUN_OBJ_0(Kandinsky_CGEXT_Is_Wide_Screen_Enabled_obj, Kandinsky_CGEXT_Is_Wide_Screen_Enabled);
MP_DEFINE_CONST_FUN_OBJ_1(Kandinsky_CGEXT_Set_Margin_Color_obj, Kandinsky_CGEXT_Set_Margin_Color);
/* Standard Kandinsky function as per Numworks specification */
MP_DEFINE_CONST_FUN_OBJ_0(Kandinsky_init_obj, Kandinsky_init);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Kandinsky_set_pixel_obj, 3, 3, Kandinsky_set_pixel);
MP_DEFINE_CONST_FUN_OBJ_2(Kandinsky_get_pixel_obj, Kandinsky_get_pixel);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Kandinsky_draw_string_obj, 3, 5, Kandinsky_draw_string);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Kandinsky_fill_rect_obj, 5, 5, Kandinsky_fill_rect);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Kandinsky_color_obj, 3, 3, Kandinsky_color);
STATIC const mp_rom_map_elem_t kandinsky_module_globals_table[] = {
{MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_kandinsky)},
{MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&Kandinsky_init_obj)},
{MP_ROM_QSTR(MP_QSTR_fill_rect), MP_ROM_PTR(&Kandinsky_fill_rect_obj)},
{MP_ROM_QSTR(MP_QSTR_color), MP_ROM_PTR(&Kandinsky_color_obj)},
{MP_ROM_QSTR(MP_QSTR_set_pixel), MP_ROM_PTR(&Kandinsky_set_pixel_obj)},
{MP_ROM_QSTR(MP_QSTR_get_pixel), MP_ROM_PTR(&Kandinsky_get_pixel_obj)},
{MP_ROM_QSTR(MP_QSTR_draw_string), MP_ROM_PTR(&Kandinsky_draw_string_obj)},
{MP_ROM_QSTR(MP_QSTR_CGEXT_Enable_Wide_Screen), MP_ROM_PTR(&Kandinsky_CGEXT_Enable_Wide_Screen_obj)},
{MP_ROM_QSTR(MP_QSTR_CGEXT_Disable_Wide_Screen), MP_ROM_PTR(&Kandinsky_CGEXT_Disable_Wide_Screen_obj)},
{MP_ROM_QSTR(MP_QSTR_CGEXT_Is_Wide_Screen_Enabled), MP_ROM_PTR(&Kandinsky_CGEXT_Is_Wide_Screen_Enabled_obj)},
{MP_ROM_QSTR(MP_QSTR_CGEXT_Set_Margin_Color), MP_ROM_PTR(&Kandinsky_CGEXT_Set_Margin_Color_obj)},
};
STATIC MP_DEFINE_CONST_DICT(kandinsky_module_globals,
kandinsky_module_globals_table);
const mp_obj_module_t kandinsky_module = {
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&kandinsky_module_globals,
};
MP_REGISTER_MODULE(MP_QSTR_kandinsky, kandinsky_module);

111
ports/sh/numworks/time.c Normal file
View File

@ -0,0 +1,111 @@
//---------------------------------------------------------------------------//
// ____ PythonExtra //
//.-'`_ o `;__, A community port of MicroPython for CASIO calculators. //
//.-'` `---` ' License: MIT (except some files; see LICENSE) //
//---------------------------------------------------------------------------//
// pe.time: `gint` module
//
// This module aims to wrap commonly-used gint functtimes (not all APIs are
// considered relevant for high-level Python development).
//---
#include "console.h"
#include "py/objtuple.h"
#include "py/runtime.h"
#include <gint/clock.h>
#include <gint/timer.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define FUN_0(NAME) MP_DEFINE_CONST_FUN_OBJ_0(time_##NAME##_obj, time_##NAME)
#define FUN_1(NAME) MP_DEFINE_CONST_FUN_OBJ_1(time_##NAME##_obj, time_##NAME)
#define FUN_2(NAME) MP_DEFINE_CONST_FUN_OBJ_2(time_##NAME##_obj, time_##NAME)
#define FUN_3(NAME) MP_DEFINE_CONST_FUN_OBJ_3(time_##NAME##_obj, time_##NAME)
#define FUN_VAR(NAME, MIN) \
MP_DEFINE_CONST_FUN_OBJ_VAR(time_##NAME##_obj, MIN, time_##NAME)
#define FUN_BETWEEN(NAME, MIN, MAX) \
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_##NAME##_obj, MIN, MAX, time_##NAME)
extern bool is_timered;
extern unsigned int timer_altered[9];
static uint64_t tickmono = 0;
static int monotonic_callback(void) {
tickmono++;
return TIMER_CONTINUE;
}
STATIC mp_obj_t time___init__(void)
{
tickmono = 0;
int t = timer_configure(TIMER_TMU, 1000, GINT_CALL(monotonic_callback));
if (t >= 0)
{
timer_start(t);
is_timered = true; // there is a timer altered from this module
timer_altered[t] = 1; // we put the corresponding timer at 1 to identify it
}
return mp_const_none;
}
/* <gint/keyboard.h> */
STATIC mp_obj_t time_sleep(mp_obj_t arg1)
{
mp_float_t duration = mp_obj_get_float(arg1);
uint64_t length = (uint64_t)(duration * 1000000.0f); // duration is in seconds and length in µs
sleep_us(length);
return mp_const_none;
}
STATIC mp_obj_t time_monotonic(void)
{
float value = (float) ((uint64_t) (tickmono * 1000 +0.5 )) / 1000000.0f;
return mp_obj_new_float( value );
}
FUN_1(sleep);
FUN_0(monotonic);
FUN_0(__init__);
/* Module definittime */
// Helper: define object "time_F_obj" as object "F" in the module
#define OBJ(F) \
{ MP_ROM_QSTR(MP_QSTR_##F), MP_ROM_PTR(&time_##F##_obj) }
// Helper: define small integer constant "I" as "I" in the module
#define INT(I) \
{ MP_ROM_QSTR(MP_QSTR_##I), MP_OBJ_NEW_SMALL_INT(I) }
STATIC const mp_rom_map_elem_t time_module_globals_table[] = {
{MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_time)},
OBJ(__init__),
OBJ(sleep),
OBJ(monotonic),
};
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
const mp_obj_module_t time_module = {
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&time_module_globals,
};
MP_REGISTER_MODULE(MP_QSTR_time, time_module);