Skip to content

Commit

Permalink
Improve exception handling. Clean up code.
Browse files Browse the repository at this point in the history
  • Loading branch information
wojciech-graj committed Apr 26, 2024
1 parent c9ec825 commit 7f2dfd2
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 165 deletions.
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def set_window_title(t: str) -> None:
def get_ticks_ms() -> int:
cdg.init(resx,
resy,n
resy,
draw_frame,
get_key,
init=init,
Expand All @@ -39,7 +39,9 @@ cdg.init(resx,
cdg.main() # Optional parameter argv=[...]
```

`get_key` should return `None` if all input has been processed, or a tuple `(pressed as 0 or 1, key)`. All possible keys are either members of the `Keys` enum, or the ascii value of the lowercase character `ord(c.lower())`.
`get_key` should return `None` if all input has been processed, or a tuple `(pressed as 0 or 1, key)`. All possible keys are either members of the `Keys` enum, or the ascii value of the lowercase character `ord(c.lower())`.

If any function that was passed to `cdg.init` raises an exception during the execution of `cdg.main`, `sys.exit(1)` is called.

Some additional documentation can be found in `cydoomgeneric/cydoomgeneric.pyx`.

Expand Down Expand Up @@ -131,6 +133,18 @@ $ cd cydoomgeneric
$ python democalc.py
```

## TODO
## License

```
Copyright (c) 2023-2024 Wojciech Graj
- Fix segfault when closing game
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
```
16 changes: 8 additions & 8 deletions cydoomgeneric/cydoomgeneric.pxd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Copyright(C) 2023 Wojciech Graj
Copyright(C) 2023-2024 Wojciech Graj
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Expand All @@ -23,13 +23,13 @@ cdef extern from "doomgeneric.h":

void dg_Create(uint32_t resx,
uint32_t resy,
void (*pDG_Init)(),
void (*pDG_DrawFrame)(),
void (*pDG_SleepMs)(uint32_t),
uint32_t (*pDG_GetTicksMs)(),
int (*pDG_GetKey)(int*, unsigned char*),
void (*pDG_SetWindowTitle)(const char*))
int dg_main(int argc, char **argv)
void (*pDG_Init)() except *,
void (*pDG_DrawFrame)() noexcept,
void (*pDG_SleepMs)(uint32_t) noexcept,
uint32_t (*pDG_GetTicksMs)() noexcept,
int (*pDG_GetKey)(int*, unsigned char*) noexcept,
void (*pDG_SetWindowTitle)(const char*) noexcept) except *
int dg_main(int argc, char **argv) noexcept


cdef extern from "doomkeys.h":
Expand Down
42 changes: 29 additions & 13 deletions cydoomgeneric/cydoomgeneric.pyx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Copyright(C) 2023 Wojciech Graj
Copyright(C) 2023-2024 Wojciech Graj
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Expand All @@ -15,7 +15,8 @@

from enum import IntEnum
import time
from typing import Callable, Optional, Tuple, Sequence, NoReturn
import sys
from typing import Callable, Optional, Tuple, Sequence


from cpython.mem cimport PyMem_Malloc, PyMem_Free
Expand All @@ -33,40 +34,55 @@ __set_window_title_f: Optional[Callable[[str], None]]
__start_time: int


cdef void __init():
cdef void __init() except *:
if __init_f:
__init_f()


cdef void __draw_frame():
__draw_frame_f(np.asarray(<uint8_t[:cdg.DOOMGENERIC_RESY, :cdg.DOOMGENERIC_RESX, :4]><uint8_t*>&cdg.DG_ScreenBuffer[0]))
cdef void __draw_frame() noexcept:
try:
__draw_frame_f(np.asarray(<uint8_t[:cdg.DOOMGENERIC_RESY, :cdg.DOOMGENERIC_RESX, :4]><uint8_t*>&cdg.DG_ScreenBuffer[0]))
except:
sys.exit(1)


cdef void __sleep_ms(uint32_t ms):
cdef void __sleep_ms(uint32_t ms) noexcept:
if __sleep_ms_f:
__sleep_ms_f(ms)
try:
__sleep_ms_f(ms)
except:
sys.exit(1)
else:
time.sleep(ms / 1000)


cdef uint32_t __get_ticks_ms():
cdef uint32_t __get_ticks_ms() noexcept:
if __get_ticks_ms_f:
return __get_ticks_ms_f()
try:
return __get_ticks_ms_f()
except:
sys.exit(1)
else:
return (time.time() - __start_time) * 1000


cdef int __get_key(int *pressed, unsigned char *key):
r = __get_key_f()
cdef int __get_key(int *pressed, unsigned char *key) noexcept:
try:
r = __get_key_f()
except:
sys.exit(1)
if r is None:
return 0
(pressed[0], key[0]) = r
return 1


cdef void __set_window_title(const char *title):
cdef void __set_window_title(const char *title) noexcept:
if __set_window_title_f:
__set_window_title_f(title.decode("utf-8"))
try:
__set_window_title_f(title.decode("utf-8"))
except:
sys.exit(1)


def init(resx: int,
Expand Down
86 changes: 41 additions & 45 deletions cydoomgeneric/democalc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Copyright(C) 2023 Wojciech Graj
Copyright(C) 2023-2024 Wojciech Graj
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Expand All @@ -12,25 +12,24 @@
GNU General Public License for more details.
"""


import itertools
import sys

from typing import Optional, Tuple, List

import cydoomgeneric as cdg
import numpy as np
import uno

import cydoomgeneric as cdg


# Change this variable to adjust screen resolution. Allowed values in range [0,5]
scale = 1
SCALE = 1


keymap = {
KEYMAP = {
'a': cdg.Keys.LEFTARROW,
'd': cdg.Keys.RIGHTARROW,
'w': cdg.Keys.UPARROW,
'd': cdg.Keys.DOWNARROW,
's': cdg.Keys.DOWNARROW,
',': cdg.Keys.STRAFE_L,
'.': cdg.Keys.STRAFE_R,
'e': cdg.Keys.FIRE,
Expand All @@ -41,50 +40,50 @@
}


grad = " .'`^\",:;Il!i><~+_-?][}{1)(|\\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$"
GRAD = " .'`^\",:;Il!i><~+_-?][}{1)(|\\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$"


class CalcDoom:
def __init__(self, sheet, scale) -> None:
self.scale = scale
self.resx = 320 // (2 ** scale)
self.resy = 200 // (2 ** scale)
self.image_cell = sheet.getCellByPosition(1, 0)
self.input_cell = sheet.getCellByPosition(0, 0)
self.input = None
self.pressed = []
self.pressed_prev = []
self._scale = scale
self._resx = 320 // (2 ** scale)
self._resy = 200 // (2 ** scale)
self._image_cell = sheet.getCellByPosition(1, 0)
self._input_cell = sheet.getCellByPosition(0, 0)
self._input: Optional[List[str]] = None
self._pressed: List[int] = []
self._pressed_prev: List[int] = []


def init(self) -> None:
for y in range(1, self.resy + 1):
print(f"Initializing row {y}/{self.resy}")
for x in range(1, self.resx + 1):
for y in range(1, self._resy + 1):
print(f"Initializing row {y}/{self._resy}")
for x in range(1, self._resx + 1):
cell = sheet.getCellByPosition(x, y)
cell.setFormula(f"=MID(B1;{x + (y - 1) * self.resx};1)")
cell.setFormula(f"=MID(B1;{x + (y - 1) * self._resx};1)")


def draw_frame(self, pix):
def draw_frame(self, pix) -> None:
pix = np.average(pix, axis=-1)
self.image_cell.setString(''.join(
[grad[int(pix[y, x] * 0.35)] for y, x in
itertools.product(range(0, 200, 2 ** self.scale), range(0, 320, 2 ** self.scale))]))


def get_key(self):
if len(self.pressed) > 0:
return (0, self.pressed.pop())
if self.input == None:
self.input = list(self.input_cell.getString().lower())
self.input_cell.setString("")
if len(self.input) == 0:
self.input = None
self.pressed = self.pressed_prev
self.pressed_prev = []
self._image_cell.setString(''.join(
[GRAD[int(pix[y, x] * 0.35)] for y, x in
itertools.product(range(0, 200, 2 ** self._scale), range(0, 320, 2 ** self._scale))]))


def get_key(self) -> Optional[Tuple[int, int]]:
if len(self._pressed) > 0:
return (0, self._pressed.pop())
if self._input is None:
self._input = list(self._input_cell.getString().lower())
self._input_cell.setString("")
if len(self._input) == 0:
self._input = None
self._pressed = self._pressed_prev
self._pressed_prev = []
return None
c = self.input.pop()
key = keymap[c] if c in keymap else ord(c)
self.pressed_prev.append(key)
c = self._input.pop()
key = KEYMAP[c] if c in KEYMAP else ord(c)
self._pressed_prev.append(key)
return (1, key)


Expand All @@ -101,13 +100,10 @@ def get_key(self):
document = desktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, (PropertyValue(),))
sheet = document.getSheets()[0]

g = CalcDoom(sheet, scale)
g = CalcDoom(sheet, SCALE)
cdg.init(320,
200,
g.draw_frame,
g.get_key,
init=g.init)
try:
cdg.main()
except KeyboardInterrupt:
sys.exit()
cdg.main()
Loading

0 comments on commit 7f2dfd2

Please sign in to comment.