好活!
readme update 看起来更像 Dear ImGui 一些(looks more like Dear ImGui and some intersting feature to the button remove debug 确认一下action 404 修改 writing theme looks good better? a ? alpha=255 not 256 looks better try new pyglet first 看起来好一些 sync pyglet 水一手 这波必须得水一手了,要不然commit太少了(确信 丢点正经东西上去 顺手继承一下Options 补充docs 坏了,忘记水commit了( 至少我能早睡了( 这里还能水一点来着( 试试再说 reee 保证能跑( 同步lib not dr 的修改 忘记带上 None了 还是加上一个额外的判断参数吧 刷点commit也不错 先更新一下依赖版本 水commit啦 理论可行,实践开始! 构建参数喜加一 reeeee 更新一下 pyproject 的依赖 fix typing looks better 水一个( 测试? sync pyglet to master A | Try use rust-cache looks good? what? C | sync pyglet A | 添加了一个 Button Draw Theme A | Magic Number (确信) A | 尽量不继承Options sync pyglet A | Add theme A | Add more Theme information Enhance | Theme sync pyglet Add | add unifont Enhance | use os.walk in font loading Enhance | Use i18n in font loading Enhance | doc sync pyglet Add | add 3.12 build option to build_rs Fix | Button position have a z sync pyglet A | Logger.py 启动! sync pyglet Changed | Bump pyo3 to 0.20.0 add logger.py update logger! Add | more logger! Add | lib-not-dr some lib-not-dr
This commit is contained in:
parent
0a4de29d5a
commit
f9eeafe322
7
.github/workflows/dr_rs.yml
vendored
7
.github/workflows/dr_rs.yml
vendored
@ -34,6 +34,13 @@ jobs:
|
||||
- name: Check out
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# 缓存 Rust 构建
|
||||
- name: Cache rust
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspace: mods/dr_game/Difficult_Rocket_rs
|
||||
key: dr_rs-v1
|
||||
|
||||
# 获取短 sha
|
||||
- name: Get short commit sha
|
||||
id: get_short_sha
|
||||
|
1
.github/workflows/dsm.py
vendored
1
.github/workflows/dsm.py
vendored
@ -108,6 +108,7 @@ def main():
|
||||
return 0
|
||||
dsm.clear_dsm()
|
||||
dsm.upload_docs('docs/md5.txt')
|
||||
|
||||
dsm.fl.logout()
|
||||
|
||||
|
||||
|
5
.github/workflows/get_info.py
vendored
5
.github/workflows/get_info.py
vendored
@ -10,7 +10,10 @@ import rtoml
|
||||
|
||||
sys.path.append(os.path.abspath(os.curdir))
|
||||
|
||||
from Difficult_Rocket import DR_status
|
||||
try:
|
||||
from Difficult_Rocket import DR_status
|
||||
except ImportError:
|
||||
raise
|
||||
|
||||
args = ['-env', '-github-dev']
|
||||
|
||||
|
2
DR.py
2
DR.py
@ -43,7 +43,7 @@ def start(start_time_ns: int) -> None:
|
||||
main_game.start()
|
||||
if DR_status.crash_report_test:
|
||||
raise TestError('debug crash test')
|
||||
except:
|
||||
except: # noqa: E722
|
||||
trace = traceback.format_exc()
|
||||
crash.create_crash_report(trace)
|
||||
print(trace)
|
||||
|
@ -11,7 +11,7 @@ from pathlib import Path
|
||||
from Difficult_Rocket.api.types import Options, Version
|
||||
|
||||
sdk_version = Version("0.8.7.0") # SDK 版本
|
||||
build_version = Version("2.1.3.0") # 编译文件版本(与游戏本体无关)
|
||||
build_version = Version("2.2.0.0") # 编译文件版本(与游戏本体无关)
|
||||
Api_version = Version("0.1.1.0") # API 版本
|
||||
__version__ = sdk_version
|
||||
|
||||
|
@ -11,6 +11,7 @@ from os import PathLike
|
||||
from pyglet.event import EventDispatcher
|
||||
|
||||
# Difficult Rocket function
|
||||
from Difficult_Rocket.api.types import Options
|
||||
from Difficult_Rocket.command.api import CommandText
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -19,11 +20,13 @@ else:
|
||||
ClientWindow = TypeVar("ClientWindow")
|
||||
|
||||
|
||||
class BaseScreen(EventDispatcher):
|
||||
class BaseScreen(EventDispatcher, Options):
|
||||
"""
|
||||
DR 的 页面API
|
||||
"""
|
||||
|
||||
name: str = 'BaseScreen'
|
||||
|
||||
def __init__(self, main_window: ClientWindow):
|
||||
super().__init__()
|
||||
self.focus = False
|
||||
|
@ -119,26 +119,28 @@ def pyglet_load_fonts_folder(folder) -> None:
|
||||
if not font_path.exists():
|
||||
font_path.mkdir(parents=True)
|
||||
return None
|
||||
file_folder_list = os.listdir(folder)
|
||||
for obj in file_folder_list:
|
||||
if os.path.isfile(os.path.join(folder, obj)):
|
||||
if obj[-4:] == '.ttf' or obj[-4:] == '.otf':
|
||||
logger.debug(f'loading font {os.path.join(folder, obj)}')
|
||||
logger.info(tr().client.load.font.start().format(font_path))
|
||||
start_time = time.time_ns()
|
||||
for dir_path, dir_names, file_names in os.walk(font_path):
|
||||
dir_path = Path(dir_path)
|
||||
for file_name in file_names:
|
||||
file_name = Path(file_name)
|
||||
if file_name.suffix in ('.ttf', '.otf'):
|
||||
logger.debug(tr().client.load.font.file().format(str(dir_path / file_name)))
|
||||
try:
|
||||
pyglet.font.add_file(os.path.join(folder, obj))
|
||||
pyglet.font.add_file(str(dir_path / file_name))
|
||||
except Exception:
|
||||
logger.error(traceback.format_exc())
|
||||
logger.error(f'loading font {os.path.join(folder, obj)} failed')
|
||||
else:
|
||||
logger.info(f'loading font folder {os.path.join(folder, obj)}')
|
||||
pyglet_load_fonts_folder(os.path.join(folder, obj))
|
||||
logger.error(tr().client.load.font.error().format(str(dir_path / file_name), traceback.format_exc()))
|
||||
end_time = time.time_ns()
|
||||
use_time = end_time - start_time
|
||||
logger.info(tr().client.load.font.use_time().format(use_time / 1000000000))
|
||||
|
||||
|
||||
def _call_back(call_back: Callable) -> Callable:
|
||||
"""
|
||||
>>> def call_back():
|
||||
>>> def call_back_example():
|
||||
>>> pass
|
||||
>>> @_call_back(call_back)
|
||||
>>> @_call_back(call_back_example)
|
||||
>>> def on_draw(self):
|
||||
>>> pass
|
||||
用于在调用窗口函数后调用指定函数 的装饰器
|
||||
@ -149,7 +151,7 @@ def _call_back(call_back: Callable) -> Callable:
|
||||
@functools.wraps(func)
|
||||
def warp(self: "ClientWindow", *args, **kwargs):
|
||||
result = func(self, *args, **kwargs)
|
||||
call_back(self)
|
||||
# call_back(self)
|
||||
return result
|
||||
return warp
|
||||
return wrapper
|
||||
@ -256,7 +258,7 @@ class ClientWindow(Window):
|
||||
end_time = time.time_ns()
|
||||
self.use_time = end_time - start_time
|
||||
DR_runtime.client_setup_cause_ns = self.use_time
|
||||
self.logger.info(tr().window.setup.use_time().format(Decimal(self.use_time) / 1000000000))
|
||||
self.logger.info(tr().window.setup.use_time().format(self.use_time / 1000000000))
|
||||
self.logger.debug(tr().window.setup.use_time_ns().format(self.use_time))
|
||||
self.count = 0
|
||||
|
||||
@ -321,7 +323,7 @@ class ClientWindow(Window):
|
||||
def on_draw(self):
|
||||
while (command := self.game.console.get_command()) is not None:
|
||||
self.on_command(line.CommandText(command))
|
||||
pyglet.gl.glClearColor(0.1, 0, 0, 0.0)
|
||||
pyglet.gl.glClearColor(21/255, 22/255, 23/255, 0.0)
|
||||
self.clear()
|
||||
# self.draw_update(dt) # TODO: wait for pyglet 2.1
|
||||
self.draw_update(float(self.SPF))
|
||||
@ -376,10 +378,10 @@ class ClientWindow(Window):
|
||||
self.logger.debug(self.fps_log.fps_list)
|
||||
elif command.find('max'):
|
||||
self.logger.info(self.fps_log.max_fps)
|
||||
self.command.push_line(self.fps_log.max_fps, block_line=True)
|
||||
# self.command.push_line(self.fps_log.max_fps, block_line=True)
|
||||
elif command.find('min'):
|
||||
self.logger.info(self.fps_log.min_fps)
|
||||
self.command.push_line(self.fps_log.min_fps, block_line=True)
|
||||
# self.command.push_line(self.fps_log.min_fps, block_line=True)
|
||||
elif command.find('default'):
|
||||
self.set_size(int(self.main_config['window_default']['width']),
|
||||
int(self.main_config['window_default']['height']))
|
||||
|
@ -4,14 +4,7 @@
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
"""
|
||||
writen by shenjackyuanjie
|
||||
mail: 3695888@qq.com
|
||||
github: @shenjackyuanjie
|
||||
gitee: @shenjackyuanjie
|
||||
"""
|
||||
|
||||
from typing import Optional, Union, Tuple
|
||||
from typing import Optional, Tuple
|
||||
|
||||
# from libs import pyglet
|
||||
import pyglet
|
||||
@ -23,7 +16,7 @@ from pyglet.shapes import Rectangle
|
||||
# from pyglet.image import AbstractImage
|
||||
from pyglet.graphics import Batch, Group
|
||||
|
||||
from Difficult_Rocket.api.types import Fonts
|
||||
from Difficult_Rocket.api.types import Options, FontData
|
||||
|
||||
# from Difficult_Rocket import DR_status
|
||||
|
||||
@ -31,19 +24,67 @@ from Difficult_Rocket.api.types import Fonts
|
||||
RGBA = Tuple[int, int, int, int]
|
||||
|
||||
|
||||
class BaseTheme:
|
||||
class ButtonDrawTheme:
|
||||
"""
|
||||
用于定义主题的类
|
||||
直接绘制按钮的风格
|
||||
"""
|
||||
name = 'ButtonDrawTheme'
|
||||
|
||||
def __init__(self,
|
||||
main_color: RGBA = (39, 73, 114, 256),
|
||||
secondary_color: RGBA = (66, 150, 250, 256),
|
||||
main_font: str = Fonts.鸿蒙简体,
|
||||
):
|
||||
self.main_color = main_color
|
||||
self.secondary_color = secondary_color
|
||||
self.main_font = main_font
|
||||
batch: Batch,
|
||||
group: Group):
|
||||
self.batch = batch
|
||||
self.group = group
|
||||
a = (72, 73, 74)
|
||||
b = (109, 109, 110)
|
||||
c = (88, 91, 92)
|
||||
d = (124, 124, 125)
|
||||
e = (49, 50, 51)
|
||||
touch_a = (49, 50, 51)
|
||||
touch_b = (90, 91, 92)
|
||||
touch_c = (71, 72, 72)
|
||||
touch_d = (106, 107, 108)
|
||||
|
||||
def on_touch(self, x, y) -> None:
|
||||
"""
|
||||
当鼠标在按钮上的时候
|
||||
:param x: 鼠标绝对位置
|
||||
:param y: 鼠标绝对位置
|
||||
:return:
|
||||
"""
|
||||
|
||||
def on_move_away(self) -> None:
|
||||
"""
|
||||
当鼠标移出按钮的时候
|
||||
:return:
|
||||
"""
|
||||
|
||||
def on_hit(self, x: int, y: int) -> None:
|
||||
"""
|
||||
当鼠标点击按钮的时候
|
||||
:param x: 鼠标绝对位置
|
||||
:param y: 鼠标绝对位置
|
||||
:return:
|
||||
"""
|
||||
|
||||
def on_release(self) -> None:
|
||||
"""
|
||||
当鼠标松开按钮的时候
|
||||
:return:
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class ButtonThemeOptions(Options):
|
||||
""" 基于 Options 写的 ButtonTheme """
|
||||
name = 'ButtonTheme'
|
||||
untouched_color: RGBA = (39, 73, 114, 255)
|
||||
touched_color: RGBA = (66, 150, 250, 255)
|
||||
hit_color: RGBA = (15, 135, 250, 255)
|
||||
font_theme: FontData = FontData()
|
||||
|
||||
def __str__(self):
|
||||
return self.as_markdown()
|
||||
|
||||
|
||||
class PressTextButton(widgets.WidgetBase):
|
||||
@ -57,38 +98,39 @@ class PressTextButton(widgets.WidgetBase):
|
||||
width: int,
|
||||
height: int,
|
||||
text: str,
|
||||
font_name: str = Fonts.鸿蒙简体,
|
||||
font_size: int = 15,
|
||||
batch: Optional[Batch] = None,
|
||||
group: Optional[Group] = None,
|
||||
theme: Optional[ButtonThemeOptions] = None,
|
||||
):
|
||||
super().__init__(x, y, width, height)
|
||||
self.back_ground_batch = batch or Batch()
|
||||
self.front_batch = batch or Batch()
|
||||
if group:
|
||||
self.front_group = Group(order=10, parent=group)
|
||||
self.back_ground_group = Group(order=5, parent=group)
|
||||
else:
|
||||
self.front_group = Group(order=5)
|
||||
self.back_ground_group = Group(order=10)
|
||||
self.main_batch = batch or Batch()
|
||||
self.user_batch = batch is not None
|
||||
self.front_group = Group(order=10, parent=group)
|
||||
self.back_ground_group = Group(order=5, parent=group)
|
||||
self.pressed = False
|
||||
|
||||
self.untouched_color = (39, 73, 114, 255)
|
||||
self.touched_color = (66, 150, 250, 255)
|
||||
self.hit_color = (15, 135, 250, 255)
|
||||
self.theme = theme or ButtonThemeOptions()
|
||||
|
||||
self.untouched_color = self.theme.untouched_color
|
||||
self.touched_color = self.theme.touched_color
|
||||
self.hit_color = self.theme.hit_color
|
||||
# from ImGui
|
||||
|
||||
self.text = text
|
||||
self.text_label = Label(font_name=font_name, font_size=font_size,
|
||||
batch=self.front_batch, group=self.front_group,
|
||||
self.text_label = Label(font_name=self.theme.font_theme.font_name, font_size=self.theme.font_theme.font_size,
|
||||
batch=self.main_batch, group=self.front_group,
|
||||
x=self._x, y=self._y, width=self._width,
|
||||
height=self._height,)
|
||||
self.font = pyglet.font.load(font_name, font_size)
|
||||
self.font = pyglet.font.load(self.theme.font_theme.font_name,
|
||||
self.theme.font_theme.font_size,
|
||||
bold=self.theme.font_theme.bold,
|
||||
italic=self.theme.font_theme.italic,
|
||||
stretch=self.theme.font_theme.stretch)
|
||||
self.font_height = self.font.ascent - self.font.descent
|
||||
self.back_rec = Rectangle(x=self._x, y=self._y,
|
||||
width=self._width, height=self._height,
|
||||
color=self.untouched_color, # ImGui color
|
||||
batch=self.back_ground_batch, group=self.back_ground_group)
|
||||
batch=self.main_batch, group=self.back_ground_group)
|
||||
|
||||
self.value = text # 重新分配一下高度和宽度的位置
|
||||
|
||||
@ -103,12 +145,14 @@ class PressTextButton(widgets.WidgetBase):
|
||||
text_width = self.text_label.content_width
|
||||
self.text_label.x = self._x + (self.width - text_width) // 2
|
||||
self.text_label.y = self._y + (self.height - self.font_height) // 2 + (self.font_height * 0.2) # 修正一下位置
|
||||
print(self.text_label.x, self.text_label.y)
|
||||
print(self.height, self.font_height)
|
||||
|
||||
def __contains__(self, item):
|
||||
return item in self.back_rec
|
||||
|
||||
def on_draw(self):
|
||||
if not self.user_batch:
|
||||
self.main_batch.draw()
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
if (x, y) in self.back_rec:
|
||||
self.back_rec.color = self.touched_color
|
||||
@ -130,14 +174,10 @@ class PressTextButton(widgets.WidgetBase):
|
||||
self.pressed = False
|
||||
|
||||
def _update_position(self):
|
||||
self.text_label.position = self._x, self._y
|
||||
self.text_label.position = self._x, self._y, 0
|
||||
self.back_rec.position = self._x, self._y
|
||||
self.back_rec.width = self._width
|
||||
self.back_rec.height = self._height
|
||||
...
|
||||
|
||||
def on_press(self, x, y):
|
||||
self.value += "1"
|
||||
|
||||
|
||||
PressTextButton.register_event_type('on_press')
|
||||
|
50
Difficult_Rocket/gui/widget/theme/__init__.py
Normal file
50
Difficult_Rocket/gui/widget/theme/__init__.py
Normal file
@ -0,0 +1,50 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
from typing import Optional, Tuple, TYPE_CHECKING
|
||||
|
||||
from pyglet.graphics import Batch, Group
|
||||
|
||||
|
||||
class BaseTheme(dict):
|
||||
"""
|
||||
Base class of themes
|
||||
"""
|
||||
theme_name = 'BaseTheme'
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
for k, v in kwargs.items():
|
||||
if hasattr(self, k):
|
||||
setattr(self, k, v)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
def init(self,
|
||||
batch: Batch,
|
||||
group: Group,
|
||||
**kwargs) -> None:
|
||||
"""
|
||||
Init theme
|
||||
:param batch: batch
|
||||
:param group: group
|
||||
:param kwargs: options
|
||||
:return: None
|
||||
"""
|
||||
|
||||
|
||||
class FontTheme(BaseTheme):
|
||||
"""
|
||||
Base class of font themes
|
||||
"""
|
||||
theme_name = 'FontTheme'
|
||||
font_name: Optional[str] = 'Times New Roman'
|
||||
font_size: Optional[int] = 12
|
||||
bold: Optional[bool] = False
|
||||
italic: Optional[bool] = False
|
||||
stretch: Optional[bool] = False
|
||||
color: Optional[Tuple[int, int, int, int]] = (255, 255, 255, 255)
|
||||
align: Optional[str] = 'center'
|
||||
|
49
Difficult_Rocket/gui/widget/theme/button.py
Normal file
49
Difficult_Rocket/gui/widget/theme/button.py
Normal file
@ -0,0 +1,49 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from pyglet.shapes import Rectangle
|
||||
from pyglet.graphics import Batch, Group
|
||||
|
||||
from Difficult_Rocket.gui.widget.theme import BaseTheme, FontTheme
|
||||
|
||||
_RGBA = Tuple[int, int, int, int]
|
||||
|
||||
|
||||
class ButtonBaseTheme(BaseTheme):
|
||||
"""
|
||||
Base theme of button
|
||||
inherit from BaseTheme and dict
|
||||
按钮的基础主题
|
||||
继承了 BaseTheme 和 dict
|
||||
"""
|
||||
theme_name = 'Button Base Theme'
|
||||
|
||||
def init(self, batch: Batch, group: Group, **kwargs) -> None:
|
||||
"""
|
||||
Init theme
|
||||
:param batch: batch
|
||||
:param group: group
|
||||
:param kwargs: options
|
||||
:return: None
|
||||
"""
|
||||
self.batch = batch
|
||||
self.group = group
|
||||
self.font_theme = FontTheme(**kwargs)
|
||||
|
||||
|
||||
class BlockTheme(ButtonBaseTheme):
|
||||
"""
|
||||
button theme: Block like button
|
||||
"""
|
||||
theme_name = 'Block Theme(button)'
|
||||
main_color: _RGBA = (39, 73, 114, 255)
|
||||
touch_color: _RGBA = (66, 150, 250, 255)
|
||||
hit_color: _RGBA = (15, 135, 250, 255)
|
||||
|
||||
font_theme: FontTheme = FontTheme()
|
||||
|
@ -11,23 +11,23 @@ github: @shenjackyuanjie
|
||||
gitee: @shenjackyuanjie
|
||||
"""
|
||||
|
||||
import time
|
||||
# import time
|
||||
import logging
|
||||
import traceback
|
||||
# import traceback
|
||||
import logging.config
|
||||
import multiprocessing
|
||||
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
# from io import StringIO
|
||||
# from pathlib import Path
|
||||
from typing import List, Optional, Dict
|
||||
|
||||
from Difficult_Rocket.utils import tools
|
||||
# from Difficult_Rocket.utils import tools
|
||||
from Difficult_Rocket.api.types import Options
|
||||
from Difficult_Rocket.utils.translate import tr
|
||||
from Difficult_Rocket.runtime import DR_runtime
|
||||
# from Difficult_Rocket.utils.translate import tr
|
||||
# from Difficult_Rocket.runtime import DR_runtime
|
||||
from Difficult_Rocket.mod.loader import ModManager
|
||||
from Difficult_Rocket.utils.thread import new_thread
|
||||
from Difficult_Rocket.crash import write_info_to_cache
|
||||
# from Difficult_Rocket.crash import write_info_to_cache
|
||||
from Difficult_Rocket import client, server, DR_status
|
||||
|
||||
|
||||
|
@ -61,9 +61,11 @@ class ModInfo(Options):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
if not self.DR_version[0] <= DR_status.DR_version <= self.DR_version[1]:
|
||||
warnings.warn(f"mod {self.mod_id} version {self.version} is not support by DR {DR_status.DR_version}\nDR {self.DR_version} is required")
|
||||
warnings.warn(f"mod {self.mod_id} version {self.version} is not support by DR {DR_status.DR_version}\n"
|
||||
f"DR {self.DR_version} is required")
|
||||
if not self.DR_Api_version[0] <= DR_status.API_version <= self.DR_Api_version[1]:
|
||||
warnings.warn(f"mod {self.mod_id} version {self.version} is not support by DR {DR_status.API_version}\nDR {self.DR_Api_version} is required")
|
||||
warnings.warn(f"mod {self.mod_id} version {self.version} is not support by DR {DR_status.API_version}\n"
|
||||
f"DR {self.DR_Api_version} is required")
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def on_load(self, game: Game, old_self: Optional["ModInfo"] = None) -> bool:
|
||||
|
@ -14,7 +14,7 @@ from typing import List, Dict, Optional, TypeVar
|
||||
|
||||
from Difficult_Rocket.mod.api import ModInfo
|
||||
from Difficult_Rocket.utils.translate import tr
|
||||
from Difficult_Rocket.api.types import Options, Version
|
||||
from Difficult_Rocket.api.types import Options
|
||||
|
||||
Game = TypeVar('Game')
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
from typing import Tuple, Optional
|
||||
|
||||
from pyglet.gl import gl_compat, gl
|
||||
from pyglet.gl import gl
|
||||
from pyglet.math import Mat4, Vec3
|
||||
from pyglet.graphics import Group
|
||||
|
||||
|
@ -58,7 +58,6 @@ key_type = Union[str, int, Hashable]
|
||||
|
||||
|
||||
class Translates:
|
||||
name = 'Translate'
|
||||
|
||||
def __init__(self, value: Union[Dict[str, Any], list, tuple, str],
|
||||
config: Optional[TranslateConfig] = None,
|
||||
|
16
README.md
16
README.md
@ -24,7 +24,7 @@
|
||||
[关于版本号的说明](./docs/src/version.md)
|
||||
|
||||
[](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||
[](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||
[](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||
[](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||
|
||||
[](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)
|
||||
@ -51,20 +51,20 @@
|
||||
|
||||
- `开发平台 1 - Windows 10 x64 22H2`
|
||||
- Python `3.8.10` / `3.10.11`
|
||||
- pillow `9.5.0`
|
||||
- pillow `10.0.0`
|
||||
- psutil `5.9.5`
|
||||
- rtoml `0.9.0`
|
||||
- tomlkit `0.11.8`
|
||||
- tomlkit `0.12.1`
|
||||
- defusedxml `0.7.1`
|
||||
- objprint `0.2.2`
|
||||
- viztracer `0.15.6`
|
||||
- vizplugins `0.1.3`
|
||||
- nuitka `1.6.6`
|
||||
- nuitka `1.7.10`
|
||||
- ordered-set `4.1.0`
|
||||
- imageio `2.31.0`
|
||||
- wheel `0.40.0`
|
||||
- setuptools `67.8.0`
|
||||
- setuptools-rust `1.6.0`
|
||||
- imageio `2.31.2`
|
||||
- wheel `0.41.2`
|
||||
- setuptools `68.1.2`
|
||||
- setuptools-rust `1.7.0`
|
||||
- `AMD R5 5600X`
|
||||
- `AMD RX 550 4G`
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<PartTypes xmlns="https://raw.githubusercontent.com/wengh/SRxsd/master/SR/partlist.xsd">
|
||||
<PartTypes xmlns="http://shenjack.top:81/files/DR/xsd/partlist.xsd">
|
||||
<PartType id="pod-1" name="Command Pod Mk1" description="This is your ship's brain. Be careful with it." sprite="Pod.png" type="pod" mass="1.0" width="4" height="3" hidden="true">
|
||||
<Damage disconnect="1500" explode="1500" explosionPower="5" explosionSize="10" />
|
||||
<Shape>
|
||||
|
5
assets/fonts/readme.md
Normal file
5
assets/fonts/readme.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Fonts information
|
||||
|
||||
## Unifont
|
||||
|
||||
- current version: 15.1.02
|
BIN
assets/fonts/unifont.otf
(Stored with Git LFS)
Normal file
BIN
assets/fonts/unifont.otf
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -47,6 +47,10 @@ setup.use_time = "Client loading has used: {} second"
|
||||
setup.use_time_ns = "Client loading has used: {} nano second"
|
||||
config.save.start = "Saving config……"
|
||||
config.save.done = "Config saved"
|
||||
load.font.start = "Font loading~ from folder {}"
|
||||
load.font.file = "Loading font file: {}"
|
||||
load.font.error = "Font {} Load failed\ntraceback: {}"
|
||||
load.font.use_time = "Font loading has used: {} second"
|
||||
|
||||
[window]
|
||||
setup.start = "Window start loading"
|
||||
|
@ -47,6 +47,10 @@ setup.use_time = "客户端载入花费: {} 秒"
|
||||
setup.use_time_ns = "客户端载入花费: {} 纳秒"
|
||||
config.save.start = "正在保存配置文件"
|
||||
config.save.done = "配置文件保存完成"
|
||||
load.font.start = "正在加载文件夹 {} 下的字体文件"
|
||||
load.font.file = "正在加载字体文件: {}"
|
||||
load.font.error = "字体加载失败: {}\n错误信息: {}"
|
||||
load.font.use_time = "字体加载消耗时间: {} 秒"
|
||||
|
||||
[window]
|
||||
setup.start = "游戏窗口加载开始"
|
||||
|
@ -4,7 +4,7 @@ Write-Output $args[0]
|
||||
|
||||
$do = 0
|
||||
|
||||
if ("38" -notin $args -and "39" -notin $args -and "310" -notin $args -and "311" -notin $args) {
|
||||
if ("38" -notin $args -and "39" -notin $args -and "310" -notin $args -and "311" -notin $args -and "312" -notin $args) {
|
||||
$do = 1
|
||||
}
|
||||
|
||||
@ -22,6 +22,9 @@ if ($do -or "310" -in $args) {
|
||||
if ($do -or "311" -in $args) {
|
||||
python3.11 setup.py build
|
||||
}
|
||||
if ($do -or "312" -in $args) {
|
||||
python3.12 setup.py build
|
||||
}
|
||||
|
||||
python3.8 post_build.py
|
||||
|
||||
|
@ -22,8 +22,8 @@
|
||||
[About Versions](src/version.md)
|
||||
|
||||
[](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||
[](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||
[](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||
[](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||
[](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||
|
||||
[](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)
|
||||
|
||||
@ -49,20 +49,20 @@
|
||||
|
||||
- `Develop platform 1 - Windows 10 x64 22H2`
|
||||
- Python `3.8.10` / `3.10.11`
|
||||
- pillow `9.5.0`
|
||||
- pillow `10.0.0`
|
||||
- psutil `5.9.5`
|
||||
- rtoml `0.9.0`
|
||||
- tomlkit `0.11.8`
|
||||
- tomlkit `0.12.1`
|
||||
- defusedxml `0.7.1`
|
||||
- objprint `0.2.2`
|
||||
- viztracer `0.15.6`
|
||||
- vizplugins `0.1.3`
|
||||
- nuitka `1.6.6`
|
||||
- nuitka `1.7.10`
|
||||
- ordered-set `4.1.0`
|
||||
- imageio `2.31.0`
|
||||
- wheel `0.40.0`
|
||||
- setuptools `67.8.0`
|
||||
- setuptools-rust `1.6.0`
|
||||
- imageio `2.31.2`
|
||||
- wheel `0.41.2`
|
||||
- setuptools `68.1.2`
|
||||
- setuptools-rust `1.7.0`
|
||||
- `AMD R5 5600X`
|
||||
- `AMD RX 550 4G`
|
||||
|
||||
|
@ -3,3 +3,5 @@
|
||||
- 很明显,这里没有你想要的东西
|
||||
|
||||
- 404啦!
|
||||
|
||||
aaaaaaa
|
||||
|
@ -2,7 +2,23 @@
|
||||
# DR 构建 更新日志
|
||||
|
||||
- 最新构建版本号
|
||||
- build_version: 2.1.3.0
|
||||
- build_version: 2.2.0.0
|
||||
|
||||
## 20230917 build 2.2.0.0
|
||||
|
||||
### 修改
|
||||
|
||||
- 删掉了蹩脚的 `_add_cmd`
|
||||
- 可读性更好的写法
|
||||
- 反正建议自己去看源码修改
|
||||
- 现在应该可以直接运行输出的脚本了
|
||||
- 不需要手动给带空格的参数添加引号了
|
||||
- 给 `--disable-plugin` 添加了
|
||||
- `pyqt5`
|
||||
- `tk-inter`
|
||||
- 防止因为 `pyperclicp` 把他俩打包进来
|
||||
- 添加了几行 `# noqa`
|
||||
- 向 linker 低头
|
||||
|
||||
## 20230715 build 2.1.3.0
|
||||
|
||||
|
@ -5,6 +5,47 @@
|
||||
- DR sdk: 0.8.7.0
|
||||
- DR api: 0.1.1.0
|
||||
|
||||
## Draft DR sdk 0.8.7.2
|
||||
|
||||
### Add
|
||||
|
||||
- `assets/fonts`
|
||||
- `unifont.otf`
|
||||
- `unifont v 15.1.02`
|
||||
|
||||
### Translate key
|
||||
|
||||
- Add
|
||||
- `client`
|
||||
- `load.font`
|
||||
- `start`
|
||||
- `file`
|
||||
- `error`
|
||||
- `use_time`
|
||||
|
||||
### Enhance
|
||||
|
||||
- `client.pyglet_load_fonts_folder`
|
||||
- 现在使用 `os.walk` 遍历文件夹
|
||||
- 使用 `tr` 进行日志记录
|
||||
|
||||
## DR sdk 0.8.7.1
|
||||
|
||||
### Add
|
||||
|
||||
- `BaseScreen`
|
||||
- 现在继承了 `Options`
|
||||
- 添加了 `name` 选项来识别名称
|
||||
- Now inherits `Options`
|
||||
- Added `name` option to identify name
|
||||
- `gui.widget.PressTextButton`
|
||||
- 作为 gui 的一部分
|
||||
- 依然在测试阶段
|
||||
- 有人发现 bug 请务必发 issue, 十分感谢
|
||||
- As part of gui
|
||||
- Still in the testing phase
|
||||
- If you find a bug, please be sure to issue it, thank you very much
|
||||
|
||||
## DR sdk 0.8.7.0
|
||||
|
||||
### Add
|
||||
|
7
libs/lib_not_dr/__init__.py
Normal file
7
libs/lib_not_dr/__init__.py
Normal file
@ -0,0 +1,7 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
__version__ = '0.1.7'
|
0
libs/lib_not_dr/command/__init__.py
Normal file
0
libs/lib_not_dr/command/__init__.py
Normal file
40
libs/lib_not_dr/command/data.py
Normal file
40
libs/lib_not_dr/command/data.py
Normal file
@ -0,0 +1,40 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Set, List
|
||||
|
||||
|
||||
class Parsed:
|
||||
...
|
||||
|
||||
|
||||
@dataclass
|
||||
class Option:
|
||||
name: str
|
||||
shortcuts: List[str]
|
||||
optional: bool
|
||||
types: Set[type] = field(default_factory=lambda: {str})
|
||||
|
||||
|
||||
@dataclass
|
||||
class OptionGroup:
|
||||
options: List[Option]
|
||||
optional: bool = True
|
||||
exclusive: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class Argument:
|
||||
name: str
|
||||
types: Set[type] = field(default_factory=lambda: {str})
|
||||
|
||||
|
||||
@dataclass
|
||||
class Flag:
|
||||
name: str
|
||||
shortcuts: List[str]
|
||||
|
||||
|
||||
@dataclass
|
||||
class FlagGroup:
|
||||
flags: List[Flag]
|
||||
exclusive: bool = False
|
||||
|
14
libs/lib_not_dr/command/descriptor.py
Normal file
14
libs/lib_not_dr/command/descriptor.py
Normal file
@ -0,0 +1,14 @@
|
||||
class CallBackDescriptor:
|
||||
def __init__(self, name):
|
||||
self.callback_name = name
|
||||
|
||||
def __set__(self, instance, value):
|
||||
assert getattr(instance, self.callback_name) is None, f"Attribute '{self.callback_name}' has been set."
|
||||
instance.__dict__[self.callback_name] = value
|
||||
|
||||
def __get__(self, instance, owner):
|
||||
return (
|
||||
self
|
||||
if instance is None
|
||||
else instance.__dict__.get(self.callback_name)
|
||||
)
|
2
libs/lib_not_dr/command/exception.py
Normal file
2
libs/lib_not_dr/command/exception.py
Normal file
@ -0,0 +1,2 @@
|
||||
class IllegalName(Exception):
|
||||
"""名称或快捷名不合法"""
|
130
libs/lib_not_dr/command/nodes.py
Normal file
130
libs/lib_not_dr/command/nodes.py
Normal file
@ -0,0 +1,130 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
import re
|
||||
from typing import Callable, List, Optional, Union, Set
|
||||
|
||||
from .data import Option, Argument, Flag, Parsed
|
||||
from .descriptor import CallBackDescriptor
|
||||
|
||||
try:
|
||||
from typing import Self
|
||||
except ImportError:
|
||||
from typing import TypeVar
|
||||
Self = TypeVar("Self") # NOQA
|
||||
|
||||
from .exception import IllegalName
|
||||
|
||||
CallBack = Union[Callable[[str], None], str] # Equals to `Callable[[str], None] | str`
|
||||
# 可调用对象或字符串作为回调
|
||||
# A callable or str as callback
|
||||
|
||||
ParseArgFunc = Callable[[str], Optional[type]]
|
||||
# 解析参数的函数,返回值为 None 时表示解析失败
|
||||
# function to parse argument, return None when failed
|
||||
|
||||
EMPTY_WORDS = re.compile(r"\s", re.I)
|
||||
|
||||
|
||||
def check_name(name: Union[str, List[str]]) -> None:
|
||||
"""
|
||||
Check the name or shortcuts of argument(s) or flag(s).
|
||||
The name must not be empty str, and must not contains \\t or \\n or \\f or \\r.
|
||||
If that not satisfy the requirements, it will raise exception `IllegalArgumentName`.
|
||||
检查 参数或标记 的 名称或快捷方式 是否符合要求。
|
||||
名称必须是非空的字符串,且不能包含 \\t 或 \\n 或 \\f 或 \\r。
|
||||
如果不符合要求,将会抛出 `IllegalArgumentName` 异常。
|
||||
:param name: arguments
|
||||
:return: None
|
||||
"""
|
||||
if isinstance(name, str) and EMPTY_WORDS.search(name):
|
||||
raise IllegalName("The name of argument must not contains empty words.")
|
||||
elif isinstance(name, list) and all((not isinstance(i, str)) and EMPTY_WORDS.search(i) for i in name):
|
||||
raise IllegalName("The name of shortcut must be 'str', and must not contains empty words.")
|
||||
else:
|
||||
raise TypeError("The type of name must be 'str' or 'list[str]'.")
|
||||
|
||||
|
||||
class Literal:
|
||||
_tip = CallBackDescriptor("_tip")
|
||||
_func = CallBackDescriptor("_func")
|
||||
_err_callback = CallBackDescriptor("_err_callback")
|
||||
|
||||
def __init__(self, name: str):
|
||||
self.name: str = name
|
||||
self.sub: List[Self] = []
|
||||
self._tip: Optional[CallBack] = None
|
||||
self._func: Optional[CallBack] = None
|
||||
self._err_callback: Optional[CallBack] = None
|
||||
|
||||
self._opts: List[Option] = []
|
||||
self._args: List[Argument] = []
|
||||
self._flags: List[Flag] = []
|
||||
|
||||
def __call__(self, *nodes) -> Self:
|
||||
self.sub += nodes
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
attrs = (k for k in self.__dict__ if not (k.startswith("__") and k.endswith("__")))
|
||||
return f"{self.__class__.__name__}({', '.join(f'{k}={v!r}' for k in attrs if (v := self.__dict__[k]))})"
|
||||
|
||||
def arg(self, name: str, types: Optional[Set[type]] = None) -> Self:
|
||||
Argument(name=name, types=types)
|
||||
return self
|
||||
|
||||
def opt(
|
||||
self,
|
||||
name: str,
|
||||
shortcuts: Optional[List[str]] = None,
|
||||
optional: bool = True,
|
||||
types: Optional[Set[type]] = None
|
||||
) -> Self:
|
||||
check_name(name)
|
||||
if shortcuts is not None and len(shortcuts) != 0:
|
||||
check_name(shortcuts)
|
||||
self._opts.append(
|
||||
Option(name=name, shortcuts=shortcuts, optional=optional, types=types)
|
||||
)
|
||||
return self
|
||||
|
||||
def opt_group(self, opts: List[Option], exclusive: bool = False):
|
||||
...
|
||||
|
||||
def flag(self, name: str, shortcuts: Optional[List[str]] = None) -> Self:
|
||||
check_name(name)
|
||||
if shortcuts is not None and len(shortcuts) != 0:
|
||||
check_name(shortcuts)
|
||||
Flag(name=name, shortcuts=shortcuts)
|
||||
...
|
||||
return self
|
||||
|
||||
def flag_group(self, flags: List[Flag], exclusive: bool = False) -> Self:
|
||||
|
||||
...
|
||||
return self
|
||||
|
||||
def error(self, callback: CallBack) -> Self:
|
||||
self._err_callback = callback
|
||||
return self
|
||||
|
||||
def run(self, func: CallBack) -> Self:
|
||||
self._func = func
|
||||
return self
|
||||
|
||||
def tip(self, tip: CallBack) -> Self:
|
||||
self._tip = tip
|
||||
return self
|
||||
|
||||
def parse(self, cmd: Union[str, List[str]]) -> Parsed:
|
||||
...
|
||||
|
||||
def to_doc(self) -> str:
|
||||
...
|
||||
|
||||
|
||||
def builder(node: Literal) -> Literal:
|
||||
...
|
0
libs/lib_not_dr/nuitka/__init__.py
Normal file
0
libs/lib_not_dr/nuitka/__init__.py
Normal file
472
libs/lib_not_dr/nuitka/compile.py
Normal file
472
libs/lib_not_dr/nuitka/compile.py
Normal file
@ -0,0 +1,472 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
import platform
|
||||
import warnings
|
||||
from pathlib import Path
|
||||
from typing import List, Tuple, Optional, Union, Any
|
||||
from enum import Enum
|
||||
|
||||
from lib_not_dr.types import Options, Version, VersionRequirement
|
||||
|
||||
|
||||
def ensure_cmd_readable(cmd: str) -> str:
|
||||
"""
|
||||
保证 参数中 不含空格
|
||||
:param cmd: 要格式化的命令行参数
|
||||
:return: 格式化后的命令行参数
|
||||
"""
|
||||
if ' ' in str(cmd):
|
||||
return f'"{cmd}"'
|
||||
return cmd
|
||||
|
||||
|
||||
def format_cmd(arg_name: Optional[str] = None,
|
||||
arg_value: Optional[Union[str, List[str]]] = None,
|
||||
write: Optional[Any] = True) -> List[str]:
|
||||
"""
|
||||
用来格式化输出命令行参数
|
||||
:param arg_name: 类似 --show-memory 之类的主项
|
||||
:param arg_value: 类似 xxx 类的内容
|
||||
:param write: 是否写入
|
||||
:return: 直接拼接好的命令行参数 不带 =
|
||||
"""
|
||||
if not write:
|
||||
return []
|
||||
if arg_name is None:
|
||||
return []
|
||||
if arg_value is None:
|
||||
return [arg_name]
|
||||
if isinstance(arg_value, list):
|
||||
arg_value = ','.join([ensure_cmd_readable(value) for value in arg_value])
|
||||
return [f'{arg_name}{arg_value}']
|
||||
arg_value = ensure_cmd_readable(arg_value)
|
||||
return [f'{arg_name}{arg_value}']
|
||||
|
||||
|
||||
class NuitkaSubConfig(Options):
|
||||
"""
|
||||
Nuitka 配置的子项
|
||||
Nuitka configuration sub-items
|
||||
"""
|
||||
name = 'Nuitka Sub Configuration'
|
||||
|
||||
def gen_cmd(self) -> List[str]:
|
||||
"""
|
||||
生成命令行参数
|
||||
:return:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class NuitkaPluginConfig(NuitkaSubConfig):
|
||||
"""
|
||||
控制 nuitka 的 plugin 相关参数的部分
|
||||
Control part of nuitka's plugin related parameters
|
||||
"""
|
||||
name = 'Nuitka Plugin Configuration'
|
||||
|
||||
# --enable-plugin=PLUGIN_NAME
|
||||
enable_plugin: List[str] = []
|
||||
# --disable-plugin=PLUGIN_NAME
|
||||
disable_plugin: List[str] = []
|
||||
# --plugin-no-detection
|
||||
plugin_no_detection: bool = False
|
||||
# --user-plugin=PATH
|
||||
user_plugin: List[Path] = []
|
||||
# --show-source-changes
|
||||
show_source_changes: bool = False
|
||||
|
||||
# --include-plugin-directory=MODULE/PACKAGE
|
||||
include_plugin_dir: List[str] = []
|
||||
# --include-plugin-files=PATTERN
|
||||
include_plugin_files: List[str] = []
|
||||
|
||||
def gen_cmd(self) -> List[str]:
|
||||
lst = []
|
||||
lst += format_cmd('--enable-plugin=', self.enable_plugin, self.enable_plugin)
|
||||
lst += format_cmd('--disable-plugin=', self.disable_plugin, self.disable_plugin)
|
||||
lst += format_cmd('--plugin-no-detection' if self.plugin_no_detection else None)
|
||||
lst += format_cmd('--user-plugin=', [str(plugin.absolute()) for plugin in self.user_plugin], self.user_plugin)
|
||||
lst += format_cmd('--show-source-changes' if self.show_source_changes else None)
|
||||
lst += format_cmd('--include-plugin-directory=', self.include_plugin_dir, self.include_plugin_dir)
|
||||
lst += format_cmd('--include-plugin-files=', self.include_plugin_files, self.include_plugin_files)
|
||||
return lst
|
||||
|
||||
|
||||
class NuitkaIncludeConfig(NuitkaSubConfig):
|
||||
"""
|
||||
控制 nuitka 的 include 和 数据 相关参数的部分
|
||||
Control part of nuitka's include related parameters
|
||||
"""
|
||||
name = 'Nuitka Include Configuration'
|
||||
|
||||
# --include-package=PACKAGE
|
||||
include_packages: List[str] = []
|
||||
# --include-module=MODULE
|
||||
include_modules: List[str] = []
|
||||
|
||||
# --prefer-source-code
|
||||
# --no-prefer-source-code for --module
|
||||
prefer_source_code: bool = False
|
||||
# --follow-stdlib
|
||||
follow_stdlib: bool = False
|
||||
|
||||
def gen_cmd(self) -> List[str]:
|
||||
lst = []
|
||||
lst += format_cmd('--include-package=', self.include_packages, self.include_packages)
|
||||
lst += format_cmd('--include-module=', self.include_modules, self.include_modules)
|
||||
lst += format_cmd('--prefer-source-code' if self.prefer_source_code else None)
|
||||
lst += format_cmd('--no-prefer-source-code' if not self.prefer_source_code else None)
|
||||
lst += format_cmd('--follow-stdlib' if self.follow_stdlib else None)
|
||||
return lst
|
||||
|
||||
|
||||
class NuitkaDataConfig(NuitkaSubConfig):
|
||||
"""
|
||||
控制 nuitka 的 数据 相关参数的部分
|
||||
Control part of nuitka's data related parameters
|
||||
"""
|
||||
name = 'Nuitka Data Configuration'
|
||||
|
||||
# --include-package-data=PACKAGE=PACKAGE_PATH
|
||||
include_package_data: List[Tuple[Path, Path]] = []
|
||||
# --include-data-files=PATH=PATH
|
||||
include_data_files: List[Tuple[Path, Path]] = []
|
||||
# --include-data-dir=DIRECTORY=PATH
|
||||
include_data_dir: List[Tuple[Path, Path]] = []
|
||||
|
||||
# --noinclude-data-files=PATH
|
||||
no_include_data_files: List[Path] = []
|
||||
|
||||
# --list-package-data=LIST_PACKAGE_DATA
|
||||
list_package_data: List[str] = []
|
||||
# --list-package-dlls=LIST_PACKAGE_DLLS
|
||||
list_package_dlls: List[str] = []
|
||||
|
||||
# --include-distribution-metadata=DISTRIBUTION
|
||||
include_distribution_metadata: List[str] = []
|
||||
|
||||
|
||||
class NuitkaBinaryInfo(Options):
|
||||
"""
|
||||
nuitka 构建的二进制文件的信息
|
||||
nuitka build binary file information
|
||||
"""
|
||||
name = 'Nuitka Binary Info'
|
||||
|
||||
# --company-name=COMPANY_NAME
|
||||
company_name: Optional[str] = None
|
||||
# --product-name=PRODUCT_NAME
|
||||
product_name: Optional[str] = None
|
||||
|
||||
# --file-version=FILE_VERSION
|
||||
# --macos-app-version=MACOS_APP_VERSION
|
||||
file_version: Optional[Union[str, Version]] = None
|
||||
# --product-version=PRODUCT_VERSION
|
||||
product_version: Optional[Union[str, Version]] = None
|
||||
|
||||
# --file-description=FILE_DESCRIPTION
|
||||
file_description: Optional[str] = None
|
||||
# --copyright=COPYRIGHT_TEXT
|
||||
copyright: Optional[str] = None
|
||||
# --trademarks=TRADEMARK_TEXT
|
||||
trademarks: Optional[str] = None
|
||||
|
||||
# Icon
|
||||
# --linux-icon=ICON_PATH
|
||||
# --macos-app-icon=ICON_PATH
|
||||
# --windows-icon-from-ico=ICON_PATH
|
||||
# --windows-icon-from-exe=ICON_EXE_PATH
|
||||
# 注意: 只有 Windows 下 才可以提供多个 ICO 文件
|
||||
# 其他平台 和 EXE 下只会使用第一个路径
|
||||
icon: Optional[List[Path]] = None
|
||||
|
||||
# Console
|
||||
# --enable-console
|
||||
# --disable-console
|
||||
console: bool = True
|
||||
|
||||
# Windows UAC
|
||||
# --windows-uac-admin
|
||||
windows_uac_admin: bool = False
|
||||
# --windows-uac-uiaccess
|
||||
windows_uac_ui_access: bool = False
|
||||
|
||||
|
||||
class NuitkaOutputConfig(Options):
|
||||
"""
|
||||
nuitka 构建的选项
|
||||
nuitka build output information
|
||||
"""
|
||||
name = 'Nuitka Output Config'
|
||||
|
||||
# --output-dir=DIRECTORY
|
||||
output_dir: Optional[Path] = None
|
||||
# --output-filename=FILENAME
|
||||
output_filename: Optional[str] = None
|
||||
|
||||
# --quiet
|
||||
quiet: bool = False
|
||||
# --no-progressbar
|
||||
no_progressbar: bool = False
|
||||
# --verbose
|
||||
verbose: bool = False
|
||||
# --verbose-output=PATH
|
||||
verbose_output: Optional[Path] = None
|
||||
|
||||
# --show-progress
|
||||
show_progress: bool = False
|
||||
# --show-memory
|
||||
show_memory: bool = False
|
||||
# --show-scons
|
||||
show_scons: bool = False
|
||||
# --show-modules
|
||||
show_modules: bool = False
|
||||
# --show-modules-output=PATH
|
||||
show_modules_output: Optional[Path] = None
|
||||
|
||||
# --xml=XML_FILENAME
|
||||
xml: Optional[Path] = None
|
||||
# --report=REPORT_FILENAME
|
||||
report: Optional[Path] = None
|
||||
# --report-diffable
|
||||
report_diffable: bool = False
|
||||
|
||||
# --remove-output
|
||||
remove_output: bool = False
|
||||
# --no-pyo-file
|
||||
no_pyo_file: bool = False
|
||||
|
||||
|
||||
class NuitkaDebugConfig(Options):
|
||||
"""
|
||||
nuitka 构建的调试选项
|
||||
nuikta build debug information
|
||||
"""
|
||||
name = 'Nuitka Debug Config'
|
||||
|
||||
# --debug
|
||||
debug: bool = False
|
||||
# --unstripped
|
||||
strip: bool = True
|
||||
# --profile
|
||||
profile: bool = False
|
||||
# --internal-graph
|
||||
internal_graph: bool = False
|
||||
# --trace-execution
|
||||
trace_execution: bool = False
|
||||
# --recompile-c-only
|
||||
recompile_c_only: bool = False
|
||||
# --generate-c-only
|
||||
generate_c_only: bool = False
|
||||
# --deployment
|
||||
deployment: bool = False
|
||||
# --no-deployment-flag=FLAG
|
||||
deployment_flag: Optional[str] = None
|
||||
# --experimental=FLAG
|
||||
experimental: Optional[str] = None
|
||||
|
||||
|
||||
class NuitkaTarget(Enum):
|
||||
"""
|
||||
用于指定 nuitka 构建的目标
|
||||
Use to specify the target of nuitka build
|
||||
exe: 不带任何参数
|
||||
module: --module
|
||||
standalone: --standalone
|
||||
one_file: --onefile
|
||||
"""
|
||||
exe = ''
|
||||
module = 'module'
|
||||
standalone = 'standalone'
|
||||
one_file = 'package'
|
||||
|
||||
|
||||
class NuitkaScriptGenerator(Options):
|
||||
"""
|
||||
用于帮助生成 nuitka 构建脚本的类
|
||||
Use to help generate nuitka build script
|
||||
|
||||
:arg main 需要编译的文件
|
||||
"""
|
||||
name = 'Nuitka Script Generator'
|
||||
|
||||
# --main=PATH
|
||||
# 可以有多个 输入时需要包在列表里
|
||||
main: List[Path]
|
||||
|
||||
# --run
|
||||
run_after_build: bool = False
|
||||
# --debugger
|
||||
debugger: bool = False
|
||||
# --execute-with-pythonpath
|
||||
execute_with_python_path: bool = False
|
||||
|
||||
# --assume-yes-for-downloads
|
||||
download_confirm: bool = True
|
||||
|
||||
# standalone/one_file/module/exe
|
||||
target: NuitkaTarget = NuitkaTarget.exe
|
||||
|
||||
# --python-debug
|
||||
python_debug: bool = False
|
||||
# --python-flag=FLAG
|
||||
python_flag: List[str] = []
|
||||
# --python-for-scons=PATH
|
||||
python_for_scons: Optional[Path] = None
|
||||
|
||||
|
||||
class CompilerHelper(Options):
|
||||
"""
|
||||
用于帮助生成 nuitka 构建脚本的类
|
||||
Use to help generate nuitka build script
|
||||
|
||||
"""
|
||||
name = 'Nuitka Compiler Helper'
|
||||
|
||||
output_path: Path = Path('./build')
|
||||
src_file: Path
|
||||
|
||||
python_cmd: str = 'python'
|
||||
compat_nuitka_version: VersionRequirement = VersionRequirement("~1.8.0") # STATIC VERSION
|
||||
|
||||
# 以下为 nuitka 的参数
|
||||
# nuitka options below
|
||||
use_lto: bool = False # --lto=yes (no is faster)
|
||||
use_clang: bool = True # --clang
|
||||
use_msvc: bool = True # --msvc=latest
|
||||
use_mingw: bool = False # --mingw64
|
||||
|
||||
onefile: bool = False # --onefile
|
||||
onefile_tempdir: Optional[str] = '' # --onefile-tempdir-spec=
|
||||
standalone: bool = True # --standalone
|
||||
use_ccache: bool = True # not --disable-ccache
|
||||
enable_console: bool = True # --enable-console / --disable-console
|
||||
|
||||
show_progress: bool = True # --show-progress
|
||||
show_memory: bool = False # --show-memory
|
||||
remove_output: bool = True # --remove-output
|
||||
save_xml: bool = False # --xml
|
||||
xml_path: Path = Path('build/compile_data.xml')
|
||||
save_report: bool = False # --report
|
||||
report_path: Path = Path('build/compile_report.xml')
|
||||
|
||||
download_confirm: bool = True # --assume-yes-for-download
|
||||
run_after_build: bool = False # --run
|
||||
|
||||
company_name: Optional[str] = ''
|
||||
product_name: Optional[str] = ''
|
||||
file_version: Optional[Version] = None
|
||||
product_version: Optional[Version] = None
|
||||
file_description: Optional[str] = '' # --file-description
|
||||
|
||||
copy_right: Optional[str] = '' # --copyright
|
||||
|
||||
icon_path: Optional[Path] = None
|
||||
|
||||
follow_import: List[str] = []
|
||||
no_follow_import: List[str] = []
|
||||
|
||||
include_data_dir: List[Tuple[str, str]] = []
|
||||
include_packages: List[str] = []
|
||||
|
||||
enable_plugin: List[str] = [] # --enable-plugin=xxx,xxx
|
||||
disable_plugin: List[str] = [] # --disable-plugin=xxx,xxx
|
||||
|
||||
def init(self, **kwargs) -> None:
|
||||
if (compat_version := kwargs.get('compat_nuitka_version')) is not None:
|
||||
if not self.compat_nuitka_version.accept(compat_version):
|
||||
warnings.warn(
|
||||
f"Nuitka version may not compat with {compat_version}\n"
|
||||
"requirement: {self.compat_nuitka_version}"
|
||||
)
|
||||
# 非 windows 平台不使用 msvc
|
||||
if platform.system() != 'Windows':
|
||||
self.use_msvc = False
|
||||
self.use_mingw = False
|
||||
else:
|
||||
self.use_mingw = self.use_mingw and not self.use_msvc
|
||||
# Windows 平台下使用 msvc 时不使用 mingw
|
||||
|
||||
def __str__(self):
|
||||
return self.as_markdown()
|
||||
|
||||
def as_markdown(self, longest: Optional[int] = None) -> str:
|
||||
"""
|
||||
输出编译器帮助信息
|
||||
Output compiler help information
|
||||
|
||||
Args:
|
||||
longest (Optional[int], optional):
|
||||
输出信息的最大长度限制 The maximum length of output information.
|
||||
Defaults to None.
|
||||
|
||||
Returns:
|
||||
str: 以 markdown 格式输出的编译器帮助信息
|
||||
Compile helper information in markdown format
|
||||
"""
|
||||
front = super().as_markdown(longest)
|
||||
gen_cmd = self.gen_subprocess_cmd()
|
||||
return f"{front}\n\n```bash\n{' '.join(gen_cmd)}\n```"
|
||||
|
||||
def gen_subprocess_cmd(self) -> List[str]:
|
||||
"""生成 nuitka 构建脚本
|
||||
Generate nuitka build script
|
||||
|
||||
Returns:
|
||||
List[str]:
|
||||
生成的 nuitka 构建脚本
|
||||
Generated nuitka build script
|
||||
"""
|
||||
cmd_list = [self.python_cmd, '-m', 'nuitka']
|
||||
# macos 和 非 macos icon 参数不同
|
||||
if platform.system() == 'Darwin':
|
||||
cmd_list += format_cmd('--macos-app-version=', self.product_version, self.product_version)
|
||||
cmd_list += format_cmd('--macos-app-icon=', self.icon_path.absolute(), self.icon_path)
|
||||
elif platform.system() == 'Windows':
|
||||
cmd_list += format_cmd('--windows-icon-from-ico=', self.icon_path.absolute(), self.icon_path)
|
||||
elif platform.system() == 'Linux':
|
||||
cmd_list += format_cmd('--linux-icon=', self.icon_path.absolute(), self.icon_path)
|
||||
|
||||
cmd_list += format_cmd('--lto=', 'yes' if self.use_lto else 'no')
|
||||
cmd_list += format_cmd('--clang' if self.use_clang else None)
|
||||
cmd_list += format_cmd('--msvc=latest' if self.use_msvc else None)
|
||||
cmd_list += format_cmd('--mingw64' if self.use_mingw else None)
|
||||
cmd_list += format_cmd('--standalone' if self.standalone else None)
|
||||
cmd_list += format_cmd('--onefile' if self.onefile else None)
|
||||
cmd_list += format_cmd('--onefile-tempdir-spec=', self.onefile_tempdir, self.onefile_tempdir)
|
||||
|
||||
cmd_list += format_cmd('--disable-ccache' if not self.use_ccache else None)
|
||||
cmd_list += format_cmd('--show-progress' if self.show_progress else None)
|
||||
cmd_list += format_cmd('--show-memory' if self.show_memory else None)
|
||||
cmd_list += format_cmd('--remove-output' if self.remove_output else None)
|
||||
cmd_list += format_cmd('--assume-yes-for-download' if self.download_confirm else None)
|
||||
cmd_list += format_cmd('--run' if self.run_after_build else None)
|
||||
cmd_list += format_cmd('--enable-console' if self.enable_console else '--disable-console')
|
||||
|
||||
cmd_list += format_cmd('--xml=', str(self.xml_path.absolute()), self.save_xml)
|
||||
cmd_list += format_cmd('--report=', str(self.report_path.absolute()), self.save_report)
|
||||
cmd_list += format_cmd('--output-dir=', str(self.output_path.absolute()), self.output_path)
|
||||
cmd_list += format_cmd('--company-name=', self.company_name, self.company_name)
|
||||
cmd_list += format_cmd('--product-name=', self.product_name, self.product_name)
|
||||
cmd_list += format_cmd('--file-version=', str(self.file_version), self.file_version)
|
||||
cmd_list += format_cmd('--product-version=', str(self.product_version), self.product_version)
|
||||
cmd_list += format_cmd('--file-description=', self.file_description, self.file_description)
|
||||
cmd_list += format_cmd('--copyright=', self.copy_right, self.copy_right)
|
||||
|
||||
cmd_list += format_cmd('--follow-import-to=', self.follow_import, self.follow_import)
|
||||
cmd_list += format_cmd('--nofollow-import-to=', self.no_follow_import, self.no_follow_import)
|
||||
cmd_list += format_cmd('--enable-plugin=', self.enable_plugin, self.enable_plugin)
|
||||
cmd_list += format_cmd('--disable-plugin=', self.disable_plugin, self.disable_plugin)
|
||||
|
||||
if self.include_data_dir:
|
||||
cmd_list += [f"--include-data-dir={src}={dst}" for src, dst in self.include_data_dir]
|
||||
if self.include_packages:
|
||||
cmd_list += [f"--include-package={package}" for package in self.include_packages]
|
||||
|
||||
cmd_list.append(f"--main={self.src_file}")
|
||||
return cmd_list
|
31
libs/lib_not_dr/types/__init__.py
Normal file
31
libs/lib_not_dr/types/__init__.py
Normal file
@ -0,0 +1,31 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
from .options import (Options,
|
||||
OptionsError,
|
||||
OptionNotFound,
|
||||
OptionNameNotDefined,
|
||||
get_type_hints_)
|
||||
|
||||
from .version import (Version,
|
||||
VersionRequirement,
|
||||
VersionParsingError,
|
||||
ExtraElement)
|
||||
|
||||
__all__ = [
|
||||
# options
|
||||
'get_type_hints_',
|
||||
'Options',
|
||||
'OptionsError',
|
||||
'OptionNotFound',
|
||||
'OptionNameNotDefined',
|
||||
|
||||
# version
|
||||
'Version',
|
||||
'VersionRequirement',
|
||||
'VersionParsingError',
|
||||
'ExtraElement'
|
||||
]
|
271
libs/lib_not_dr/types/options.py
Normal file
271
libs/lib_not_dr/types/options.py
Normal file
@ -0,0 +1,271 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
import shutil
|
||||
import traceback
|
||||
from io import StringIO
|
||||
from typing import get_type_hints, Type, List, Union, Dict, Any, Callable, Tuple, Optional, TYPE_CHECKING, Iterable
|
||||
|
||||
__all__ = [
|
||||
'get_type_hints_',
|
||||
'Options',
|
||||
'OptionsError',
|
||||
'OptionNotFound',
|
||||
'OptionNameNotDefined'
|
||||
]
|
||||
|
||||
|
||||
def get_type_hints_(cls: Type):
|
||||
try:
|
||||
return get_type_hints(cls)
|
||||
except ValueError:
|
||||
return get_type_hints(cls, globalns={})
|
||||
|
||||
|
||||
def to_str_value_(value: Any) -> Any:
|
||||
"""递归的将输入值的每一个非 builtin type 转换成 str"""
|
||||
if isinstance(value, (str, bytes, bytearray, int, float, bool, type(None))):
|
||||
return value
|
||||
elif isinstance(value, dict):
|
||||
return {k: to_str_value_(v) for k, v in value.items()}
|
||||
elif isinstance(value, (list, Iterable)):
|
||||
return [to_str_value_(v) for v in value]
|
||||
else:
|
||||
return str(value)
|
||||
|
||||
|
||||
class OptionsError(Exception):
|
||||
""" option 的错误基类"""
|
||||
|
||||
|
||||
class OptionNameNotDefined(OptionsError):
|
||||
""" 向初始化的 option 里添加了一个不存在于选项里的选项 """
|
||||
|
||||
|
||||
class OptionNotFound(OptionsError):
|
||||
""" 某个选项没有找到 """
|
||||
|
||||
|
||||
class Options:
|
||||
"""
|
||||
一个用于存储选项 / 提供 API 定义 的类
|
||||
用法:
|
||||
存储配置: 继承 Options 类
|
||||
在类里定义 option: typing
|
||||
(可选 定义 name: str = 'Option Base' 用于在打印的时候显示名字)
|
||||
提供 API 接口: 继承 Options 类
|
||||
在类里定义 option: typing
|
||||
定义 一些需要的方法
|
||||
子类: 继承 新的 Options 类
|
||||
实现定义的方法
|
||||
"""
|
||||
name = 'Option Base'
|
||||
cached_options: Dict[str, Union[str, Any]] = {}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""
|
||||
创建一个新的 Options 的时候的配置
|
||||
如果存在 init 方法 会在设置完 kwargs 之后运行子类的 init 方法
|
||||
:param kwargs: 需要设置的选项
|
||||
"""
|
||||
if TYPE_CHECKING:
|
||||
self._options: Dict[str, Union[Callable, object]] = {}
|
||||
self.flush_option()
|
||||
for option, value in kwargs.items():
|
||||
if option not in self.cached_options:
|
||||
raise OptionNameNotDefined(f"option: {option} with value: {value} is not defined")
|
||||
setattr(self, option, value)
|
||||
run_load_file = True
|
||||
if hasattr(self, 'init'):
|
||||
run_load_file = self.init(**kwargs) # 默认 False/None
|
||||
run_load_file = not run_load_file
|
||||
if hasattr(self, 'load_file') and run_load_file:
|
||||
try:
|
||||
self.load_file()
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
self.flush_option()
|
||||
|
||||
def __str__(self):
|
||||
return f"<{self.__class__.__name__} {self.name}>" if self.name else f"<{self.__class__.__name__}>"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
if TYPE_CHECKING:
|
||||
_options: Dict[str, Union[Callable, object]] = {}
|
||||
|
||||
def init(self, **kwargs) -> bool:
|
||||
""" 如果子类定义了这个函数,则会在 __init__ 之后调用这个函数
|
||||
返回值为 True 则不会调用 load_file 函数
|
||||
"""
|
||||
|
||||
def load_file(self) -> bool:
|
||||
"""如果子类定义了这个函数,则会在 __init__ 和 init 之后再调用这个函数
|
||||
|
||||
请注意,这个函数请尽量使用 try 包裹住可能出现错误的部分
|
||||
否则会在控制台输出你的报错"""
|
||||
return True
|
||||
|
||||
def option(self) -> Dict[str, Any]:
|
||||
"""
|
||||
获取配置类的所有配置
|
||||
:return: 自己的所有配置
|
||||
"""
|
||||
values = {}
|
||||
for ann in self.__annotations__: # 获取类型注释
|
||||
values[ann] = getattr(self, ann, None)
|
||||
if values[ann] is None:
|
||||
values[ann] = self.__annotations__[ann]
|
||||
|
||||
if not hasattr(self, '_options'):
|
||||
self._options: Dict[str, Union[Callable, object]] = {}
|
||||
for option, a_fun in self._options.items(): # 获取额外内容
|
||||
values[option] = a_fun
|
||||
|
||||
for option, a_fun in values.items(): # 检查是否为 property
|
||||
if a_fun is bool and getattr(self, option, None) is not None:
|
||||
values[option] = False
|
||||
if isinstance(a_fun, property):
|
||||
try:
|
||||
values[option] = getattr(self, option)
|
||||
except AttributeError:
|
||||
raise OptionNotFound(f'Option {option} is not found in {self.name}') from None
|
||||
return values
|
||||
|
||||
def str_option(self, shrink_to_long: Optional[int] = None) -> Dict[str, Union[str, Any]]:
|
||||
"""
|
||||
获取配置类的所有配置 并将所有非 BuiltIn 类型的值转换为 str
|
||||
:return:
|
||||
"""
|
||||
raw_option = self.option()
|
||||
str_option = to_str_value_(raw_option)
|
||||
if shrink_to_long is None:
|
||||
return str_option
|
||||
if not isinstance(shrink_to_long, int) or shrink_to_long <= 0:
|
||||
return str_option
|
||||
for option, value in str_option.items():
|
||||
if value is not None:
|
||||
if len(str(value)) > shrink_to_long:
|
||||
str_option[option] = str(value)[:shrink_to_long] + '...'
|
||||
return str_option
|
||||
|
||||
def format(self, text: str) -> str:
|
||||
"""
|
||||
使用自己的选项给输入的字符串替换内容
|
||||
:param text: 想替换的内容
|
||||
:return: 替换之后的内容
|
||||
"""
|
||||
cache_option = self.flush_option()
|
||||
for option, value in cache_option.items():
|
||||
text = text.replace(f'{{{option}}}', str(value))
|
||||
return text
|
||||
|
||||
def flush_option(self) -> Dict[str, Any]:
|
||||
"""
|
||||
刷新缓存 options 的内容
|
||||
:return: 刷新过的 options
|
||||
"""
|
||||
self.cached_options = self.option()
|
||||
return self.cached_options
|
||||
|
||||
def option_with_len(self) -> Tuple[List[Tuple[str, Any, Type]], int, int, int]:
|
||||
"""
|
||||
返回一个可以用于打印的 option 列表
|
||||
:return:
|
||||
"""
|
||||
options = self.flush_option()
|
||||
max_len_key = 1
|
||||
max_len_value = 1
|
||||
max_len_value_t = 1
|
||||
option_list = []
|
||||
for key, value in options.items():
|
||||
value_t = type(value) if isinstance(value, type(value)) else type(value) # 判定这个类型 是不是 基本类型
|
||||
max_len_key = max(max_len_key, len(key))
|
||||
max_len_value = max(max_len_value, len(str(value)))
|
||||
max_len_value_t = max(max_len_value_t, len(str(value_t)))
|
||||
option_list.append([key, value, value_t])
|
||||
return [option_list, max_len_key, max_len_value, max_len_value_t] # noqa
|
||||
|
||||
def as_markdown(self, longest: Optional[int] = None) -> str:
|
||||
"""
|
||||
返回一个 markdown 格式的 option 字符串
|
||||
:param longest: 最长的输出长度
|
||||
:return: markdown 格式的 option 字符串
|
||||
"""
|
||||
value = self.option_with_len()
|
||||
cache = StringIO()
|
||||
option_len = max(value[1], len('Option'))
|
||||
value_len = max(value[2], len('Value'))
|
||||
value_type_len = max(value[3], len('Value Type'))
|
||||
|
||||
# | Option | Value | Value Type |
|
||||
shortest = len('Option | Value | Value Type')
|
||||
|
||||
if longest is not None:
|
||||
console_width = max(longest, shortest)
|
||||
else:
|
||||
console_width = shutil.get_terminal_size(fallback=(100, 80)).columns
|
||||
console_width = max(console_width, shortest)
|
||||
|
||||
# 为每一栏 预分配 1/3 或者 需要的宽度 (如果不需要 1/3)
|
||||
option_len = min(option_len, console_width // 3)
|
||||
value_len = min(value_len, console_width // 3)
|
||||
value_type_len = min(value_type_len, console_width // 3)
|
||||
|
||||
# 先指定每一个列的输出最窄宽度, 然后去尝试增加宽度
|
||||
# 循环分配新空间之前 首先检查是否已经不需要多分配 (and 后面)
|
||||
while option_len + value_len + value_type_len + 16 < console_width\
|
||||
and (option_len < value[1]
|
||||
or value_len < value[2]
|
||||
or value_type_len < value[3]):
|
||||
# 每一个部分的逻辑都是
|
||||
# 如果现在的输出长度小于原始长度
|
||||
# 并且长度 + 1 之后的总长度依然在允许范围内
|
||||
# 那么就 + 1
|
||||
if option_len < value[1] and option_len + value_len + value_type_len + 16 < console_width:
|
||||
option_len += 1
|
||||
if value_len < value[2] and option_len + value_len + value_type_len + 16 < console_width:
|
||||
value_len += 1
|
||||
if value_type_len < value[3] and option_len + value_len + value_type_len + 16 < console_width:
|
||||
value_type_len += 1
|
||||
# 实际上 对于列表(可变对象) for 出来的这个值是一个引用
|
||||
# 所以可以直接修改 string
|
||||
for v in value[0]:
|
||||
if len(str(v[0])) > option_len:
|
||||
v[0] = f'{str(v[0])[:value_len - 3]}...'
|
||||
if len(str(v[1])) > value_len:
|
||||
v[1] = f'{str(v[1])[:value_len - 3]}...'
|
||||
if len(str(v[2])) > value_type_len:
|
||||
v[2] = f'{str(v[2])[:value_len - 3]}..'
|
||||
|
||||
cache.write(
|
||||
f"| Option{' ' * (option_len - 3)}| Value{' ' * (value_len - 2)}| Value Type{' ' * (value_type_len - 7)}|\n")
|
||||
cache.write(f'|:{"-" * (option_len + 3)}|:{"-" * (value_len + 3)}|:{"-" * (value_type_len + 3)}|\n')
|
||||
for option, value, value_t in value[0]:
|
||||
cache.write(f"| `{option}`{' ' * (option_len - len(option))} "
|
||||
f"| `{value}`{' ' * (value_len - len(str(value)))} "
|
||||
f"| `{value_t}`{' ' * (value_type_len - len(str(value_t)))} |\n")
|
||||
result = cache.getvalue()
|
||||
cache.close()
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def add_option(cls, name: str, value: Union[Callable, object]) -> Dict:
|
||||
"""
|
||||
向配置类中添加一个额外的配置
|
||||
:param name: 配置的名字
|
||||
:param value: 用于获取配置的函数或者类
|
||||
:return: 配置类的所有配置
|
||||
"""
|
||||
if not hasattr(cls, '_options'):
|
||||
cls._options: Dict[str, Union[Callable, object]] = {}
|
||||
cls._options[name] = value
|
||||
return cls._options
|
||||
|
||||
@staticmethod
|
||||
def init_option(options_class: Type['Options'], init_value: Optional[dict] = None) -> 'Options':
|
||||
return options_class(**init_value if init_value is not None else {})
|
220
libs/lib_not_dr/types/version.py
Normal file
220
libs/lib_not_dr/types/version.py
Normal file
@ -0,0 +1,220 @@
|
||||
# 本文件以 GNU Lesser General Public License v3.0(GNU LGPL v3) 开源协议进行授权 (谢谢狐狸写出这么好的MCDR)
|
||||
# 顺便说一句,我把所有的tab都改成了空格,因为我觉得空格比tab更好看(草,后半句是github copilot自动填充的)
|
||||
|
||||
"""
|
||||
This part of code come from MCDReforged(https://github.com/Fallen-Breath/MCDReforged)
|
||||
Thanks a lot to Fallen_Breath and MCDR contributors
|
||||
GNU Lesser General Public License v3.0 (GNU LGPL v3)
|
||||
"""
|
||||
|
||||
import re
|
||||
from typing import List, Callable, Tuple, Optional, Union
|
||||
"""
|
||||
Plugin Version
|
||||
"""
|
||||
|
||||
|
||||
# beta.3 -> (beta, 3), random -> (random, None)
|
||||
class ExtraElement:
|
||||
DIVIDER = '.'
|
||||
body: str
|
||||
num: Optional[int]
|
||||
|
||||
def __init__(self, segment_str: str):
|
||||
segments = segment_str.rsplit(self.DIVIDER, 1)
|
||||
try:
|
||||
self.body, self.num = segments[0], int(segments[1])
|
||||
except (IndexError, ValueError):
|
||||
self.body, self.num = segment_str, None
|
||||
|
||||
def __str__(self):
|
||||
if self.num is None:
|
||||
return self.body
|
||||
return '{}{}{}'.format(self.body, self.DIVIDER, self.num)
|
||||
|
||||
def __lt__(self, other):
|
||||
if not isinstance(other, type(self)):
|
||||
raise TypeError()
|
||||
if self.num is None or other.num is None:
|
||||
return str(self) < str(other)
|
||||
else:
|
||||
return (self.body, self.num) < (other.body, other.num)
|
||||
|
||||
|
||||
class Version:
|
||||
"""
|
||||
A version container that stores semver like version string
|
||||
|
||||
Example:
|
||||
|
||||
* ``"1.2.3"``
|
||||
* ``"1.0.*"``
|
||||
* ``"1.2.3-pre4+build.5"``
|
||||
"""
|
||||
EXTRA_ID_PATTERN = re.compile(r'|[-+0-9A-Za-z]+(\.[-+0-9A-Za-z]+)*')
|
||||
WILDCARDS = ('*', 'x', 'X')
|
||||
WILDCARD = -1
|
||||
|
||||
component: List[int]
|
||||
has_wildcard: bool
|
||||
pre: Optional[ExtraElement]
|
||||
build: Optional[ExtraElement]
|
||||
|
||||
def __init__(self, version_str: str, *, allow_wildcard: bool = True):
|
||||
"""
|
||||
:param version_str: The version string to be parsed
|
||||
:keyword allow_wildcard: If wildcard (``"*"``, ``"x"``, ``"X"``) is allowed. Default: ``True``
|
||||
"""
|
||||
if not isinstance(version_str, str):
|
||||
raise VersionParsingError('Invalid input version string')
|
||||
|
||||
def separate_extra(text, char) -> Tuple[str, Optional[ExtraElement]]:
|
||||
if char in text:
|
||||
text, extra_str = text.split(char, 1)
|
||||
if not self.EXTRA_ID_PATTERN.fullmatch(extra_str):
|
||||
raise VersionParsingError('Invalid build string: ' + extra_str)
|
||||
extra = ExtraElement(extra_str)
|
||||
else:
|
||||
extra = None
|
||||
return text, extra
|
||||
|
||||
self.component = []
|
||||
self.has_wildcard = False
|
||||
version_str, self.build = separate_extra(version_str, '+')
|
||||
version_str, self.pre = separate_extra(version_str, '-')
|
||||
if len(version_str) == 0:
|
||||
raise VersionParsingError('Version string is empty')
|
||||
for comp in version_str.split('.'):
|
||||
if comp in self.WILDCARDS:
|
||||
self.component.append(self.WILDCARD)
|
||||
self.has_wildcard = True
|
||||
if not allow_wildcard:
|
||||
raise VersionParsingError('Wildcard {} is not allowed'.format(comp))
|
||||
else:
|
||||
try:
|
||||
num = int(comp)
|
||||
except ValueError:
|
||||
num = None
|
||||
if num is None:
|
||||
raise VersionParsingError('Invalid version number component: {}'.format(comp))
|
||||
if num < 0:
|
||||
raise VersionParsingError('Unsupported negatived number component: {}'.format(num))
|
||||
self.component.append(num)
|
||||
if len(self.component) == 0:
|
||||
raise VersionParsingError('Empty version string')
|
||||
|
||||
def __str__(self):
|
||||
version_str = '.'.join(map(lambda c: str(c) if c != self.WILDCARD else self.WILDCARDS[0], self.component))
|
||||
if self.pre is not None:
|
||||
version_str += '-' + str(self.pre)
|
||||
if self.build is not None:
|
||||
version_str += '+' + str(self.build)
|
||||
return version_str
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __getitem__(self, index: int) -> int:
|
||||
if index < len(self.component):
|
||||
return self.component[index]
|
||||
else:
|
||||
return self.WILDCARD if self.component[len(self.component) - 1] == self.WILDCARD else 0
|
||||
|
||||
def __lt__(self, other):
|
||||
if not isinstance(other, Version):
|
||||
raise TypeError('Cannot compare between instances of {} and {}'.format(Version.__name__, type(other).__name__))
|
||||
for i in range(max(len(self.component), len(other.component))):
|
||||
if self[i] == self.WILDCARD or other[i] == self.WILDCARD:
|
||||
continue
|
||||
if self[i] != other[i]:
|
||||
return self[i] < other[i]
|
||||
if self.pre is not None and other.pre is not None:
|
||||
return self.pre < other.pre
|
||||
elif self.pre is not None:
|
||||
return not other.has_wildcard
|
||||
elif other.pre is not None:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def __eq__(self, other):
|
||||
return not self < other and not other < self
|
||||
|
||||
def __le__(self, other):
|
||||
return self == other or self < other
|
||||
|
||||
def compare_to(self, other):
|
||||
if self < other:
|
||||
return -1
|
||||
elif self > other:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
DEFAULT_CRITERION_OPERATOR = '='
|
||||
|
||||
|
||||
class Criterion:
|
||||
def __init__(self, opt: str, base_version: Version, criterion: Callable[[Version, Version], bool]):
|
||||
self.opt = opt
|
||||
self.base_version = base_version
|
||||
self.criterion = criterion
|
||||
|
||||
def test(self, target: Union[Version, str]):
|
||||
return self.criterion(self.base_version, target)
|
||||
|
||||
def __str__(self):
|
||||
return '{}{}'.format(self.opt if self.opt != DEFAULT_CRITERION_OPERATOR else '', self.base_version)
|
||||
|
||||
|
||||
class VersionRequirement:
|
||||
"""
|
||||
A version requirement tester
|
||||
|
||||
It can test if a given :class:`Version` object matches its requirement
|
||||
"""
|
||||
CRITERIONS = {
|
||||
'<=': lambda base, ver: ver <= base,
|
||||
'>=': lambda base, ver: ver >= base,
|
||||
'<': lambda base, ver: ver < base,
|
||||
'>': lambda base, ver: ver > base,
|
||||
'=': lambda base, ver: ver == base,
|
||||
'^': lambda base, ver: ver >= base and ver[0] == base[0],
|
||||
'~': lambda base, ver: ver >= base and ver[0] == base[0] and ver[1] == base[1],
|
||||
}
|
||||
|
||||
def __init__(self, requirements: str):
|
||||
"""
|
||||
:param requirements: The requirement string, which contains several version predicates connected by space character.
|
||||
e.g. ``">=1.0.x"``, ``"^2.9"``, ``">=1.2.0 <1.4.3"``
|
||||
"""
|
||||
if not isinstance(requirements, str):
|
||||
raise VersionParsingError('Requirements should be a str, not {}'.format(type(requirements).__name__))
|
||||
self.criterions = [] # type: List[Criterion]
|
||||
for requirement in requirements.split(' '):
|
||||
if len(requirement) > 0:
|
||||
for prefix, func in self.CRITERIONS.items():
|
||||
if requirement.startswith(prefix):
|
||||
opt = prefix
|
||||
base_version = requirement[len(prefix):]
|
||||
break
|
||||
else:
|
||||
opt = DEFAULT_CRITERION_OPERATOR
|
||||
base_version = requirement
|
||||
self.criterions.append(Criterion(opt, Version(base_version), self.CRITERIONS[opt]))
|
||||
|
||||
def accept(self, version: Union[Version, str]):
|
||||
if isinstance(version, str):
|
||||
version = Version(version)
|
||||
for criterion in self.criterions:
|
||||
if not criterion.test(version):
|
||||
return False
|
||||
return True
|
||||
|
||||
def __str__(self):
|
||||
return ' '.join(map(str, self.criterions))
|
||||
|
||||
|
||||
class VersionParsingError(ValueError):
|
||||
pass
|
@ -9,7 +9,7 @@ import sys
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
#: The release version
|
||||
version = '2.0.9'
|
||||
version = '2.0.10'
|
||||
__version__ = version
|
||||
|
||||
MIN_PYTHON_VERSION = 3, 8
|
||||
@ -31,8 +31,10 @@ _enable_optimisations = not __debug__
|
||||
if getattr(sys, 'frozen', None):
|
||||
_enable_optimisations = True
|
||||
|
||||
#: Global dict of pyglet options. To change an option from its default, you
|
||||
#: must import ``pyglet`` before any sub-packages. For example::
|
||||
#: Global dict of pyglet options.
|
||||
#:
|
||||
#: To change an option from its default, you must import
|
||||
#: ``pyglet`` before any sub-packages. For example::
|
||||
#:
|
||||
#: import pyglet
|
||||
#: pyglet.options['debug_gl'] = False
|
||||
@ -48,14 +50,21 @@ if getattr(sys, 'frozen', None):
|
||||
#: The non-development options are:
|
||||
#:
|
||||
#: audio
|
||||
#: A sequence of the names of audio modules to attempt to load, in
|
||||
#: order of preference. Valid driver names are:
|
||||
#: A :py:class:`~typing.Sequence` of valid audio modules names. They will
|
||||
#: be tried from first to last until either a driver loads or no entries
|
||||
#: remain. See :ref:`guide-audio-driver-order` for more information.
|
||||
#:
|
||||
#: Valid driver names are:
|
||||
#:
|
||||
#: * ``'xaudio2'``, the Windows Xaudio2 audio module (Windows only)
|
||||
#: * ``'directsound'``, the Windows DirectSound audio module (Windows only)
|
||||
#: * ``'pulse'``, the :ref:`guide-audio-driver-pulseaudio` module
|
||||
#: (Linux only, otherwise nearly ubiquitous. Limited features; use
|
||||
#: ``'openal'`` for more.)
|
||||
#: * ``'openal'``, the :ref:`guide-audio-driver-openal` audio module
|
||||
#: (A library may need to be installed on Windows and Linux)
|
||||
#: * ``'silent'``, no audio
|
||||
#:
|
||||
#: * xaudio2, the Windows Xaudio2 audio module (Windows only)
|
||||
#: * directsound, the Windows DirectSound audio module (Windows only)
|
||||
#: * pulse, the PulseAudio module (Linux only)
|
||||
#: * openal, the OpenAL audio module
|
||||
#: * silent, no audio
|
||||
#: debug_lib
|
||||
#: If True, prints the path of each dynamic library loaded.
|
||||
#: debug_gl
|
||||
|
@ -1,4 +1,9 @@
|
||||
import weakref
|
||||
|
||||
from enum import Enum
|
||||
from typing import Tuple
|
||||
|
||||
import pyglet
|
||||
|
||||
from pyglet import gl
|
||||
from pyglet.gl import gl_info
|
||||
@ -162,7 +167,7 @@ class Config:
|
||||
|
||||
|
||||
class CanvasConfig(Config):
|
||||
"""OpenGL configuration for a particular canvas.
|
||||
"""An OpenGL configuration for a particular canvas.
|
||||
|
||||
Use `Config.match` to obtain an instance of this class.
|
||||
|
||||
@ -212,7 +217,7 @@ class ObjectSpace:
|
||||
|
||||
|
||||
class Context:
|
||||
"""OpenGL context for drawing.
|
||||
"""An OpenGL context for drawing.
|
||||
|
||||
Use `CanvasConfig.create_context` to create a context.
|
||||
|
||||
@ -237,9 +242,17 @@ class Context:
|
||||
else:
|
||||
self.object_space = ObjectSpace()
|
||||
|
||||
self._cached_programs = weakref.WeakValueDictionary()
|
||||
|
||||
def __repr__(self):
|
||||
return f"{self.__class__.__name__}(id={id(self)}, share={self.context_share})"
|
||||
|
||||
def __enter__(self):
|
||||
self.set_current()
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
return
|
||||
|
||||
def attach(self, canvas):
|
||||
if self.canvas is not None:
|
||||
self.detach()
|
||||
@ -266,7 +279,7 @@ class Context:
|
||||
|
||||
# Release Textures, Buffers, and VAOs on this context scheduled for
|
||||
# deletion. Note that the garbage collector may introduce a race
|
||||
# condition, so operate on a copy, and clear the list afterwards.
|
||||
# condition, so operate on a copy, and clear the list afterward.
|
||||
if self.object_space.doomed_textures:
|
||||
textures = self.object_space.doomed_textures[:]
|
||||
textures = (gl.GLuint * len(textures))(*textures)
|
||||
@ -305,6 +318,34 @@ class Context:
|
||||
if gl._shadow_window is not None:
|
||||
gl._shadow_window.switch_to()
|
||||
|
||||
def create_program(self, *sources: Tuple[str, str], program_class=None):
|
||||
"""Create a ShaderProgram from OpenGL GLSL source.
|
||||
|
||||
This is a convenience method that takes one or more tuples of
|
||||
(source_string, shader_type), and returns a
|
||||
:py:class:`~pyglet.graphics.shader.ShaderProgram` instance.
|
||||
|
||||
`source_string` is OpenGL GLSL source code as a str, and `shader_type`
|
||||
is the OpenGL shader type, such as "vertex" or "fragment". See
|
||||
:py:class:`~pyglet.graphics.shader.Shader` for more information.
|
||||
|
||||
.. note:: This method is cached. Given the same shader sources, the
|
||||
same ShaderProgram instance will be returned. For more
|
||||
control over the ShaderProgram lifecycle, it is recommended
|
||||
to manually create Shaders and link ShaderPrograms.
|
||||
|
||||
.. versionadded:: 2.0.10
|
||||
"""
|
||||
if program := self._cached_programs.get(str(sources)):
|
||||
return program
|
||||
|
||||
program_class = program_class or pyglet.graphics.shader.ShaderProgram
|
||||
shaders = (pyglet.graphics.shader.Shader(src, srctype) for (src, srctype) in sources)
|
||||
program = program_class(*shaders)
|
||||
self._cached_programs[str(sources)] = program
|
||||
|
||||
return program
|
||||
|
||||
def delete_texture(self, texture_id):
|
||||
"""Safely delete a Texture belonging to this context.
|
||||
|
||||
|
@ -63,10 +63,12 @@ class GLInfo:
|
||||
|
||||
This method is called automatically for the default context.
|
||||
"""
|
||||
from pyglet.gl.gl import glGetString, glGetStringi, GL_NUM_EXTENSIONS
|
||||
|
||||
self._have_context = True
|
||||
|
||||
if not self._have_info:
|
||||
|
||||
from pyglet.gl.gl import glGetString, glGetStringi, GL_NUM_EXTENSIONS
|
||||
|
||||
self.vendor = asstr(cast(glGetString(GL_VENDOR), c_char_p).value)
|
||||
self.renderer = asstr(cast(glGetString(GL_RENDERER), c_char_p).value)
|
||||
self.version = asstr(cast(glGetString(GL_VERSION), c_char_p).value)
|
||||
|
@ -188,24 +188,9 @@ def get_default_batch():
|
||||
return pyglet.gl.current_context.pyglet_graphics_default_batch
|
||||
|
||||
|
||||
def get_default_group():
|
||||
try:
|
||||
return pyglet.gl.current_context.pyglet_graphics_default_group
|
||||
except AttributeError:
|
||||
pyglet.gl.current_context.pyglet_graphics_default_group = ShaderGroup(get_default_shader())
|
||||
return pyglet.gl.current_context.pyglet_graphics_default_group
|
||||
|
||||
|
||||
def get_default_shader():
|
||||
try:
|
||||
return pyglet.gl.current_context.pyglet_graphics_default_shader
|
||||
except AttributeError:
|
||||
_default_vert_shader = pyglet.graphics.shader.Shader(_vertex_source, 'vertex')
|
||||
_default_frag_shader = pyglet.graphics.shader.Shader(_fragment_source, 'fragment')
|
||||
default_shader_program = pyglet.graphics.shader.ShaderProgram(_default_vert_shader, _default_frag_shader)
|
||||
pyglet.gl.current_context.pyglet_graphics_default_shader = default_shader_program
|
||||
return pyglet.gl.current_context.pyglet_graphics_default_shader
|
||||
|
||||
return pyglet.gl.current_context.create_program((_vertex_source, 'vertex'),
|
||||
(_fragment_source, 'fragment'))
|
||||
|
||||
class Batch:
|
||||
"""Manage a collection of drawables for batched rendering.
|
||||
|
@ -729,8 +729,8 @@ class Shader:
|
||||
result_str = create_string_buffer(log_length.value)
|
||||
glGetShaderInfoLog(shader_id, log_length, None, result_str)
|
||||
if result_str.value:
|
||||
return ("OpenGL returned the following message when compiling the '{0}' shader: "
|
||||
"\n{1}".format(self.type, result_str.value.decode('utf8')))
|
||||
return (f"OpenGL returned the following message when compiling the "
|
||||
f"'{self.type}' shader: \n{result_str.value.decode('utf8')}")
|
||||
else:
|
||||
return f"{self.type.capitalize()} Shader '{shader_id}' compiled successfully."
|
||||
|
||||
@ -936,8 +936,6 @@ class ShaderProgram:
|
||||
class ComputeShaderProgram:
|
||||
"""OpenGL Compute Shader Program"""
|
||||
|
||||
__slots__ = '_shader', '_id', '_context', '_uniforms', '_uniform_blocks', '__weakref__', 'limits'
|
||||
|
||||
def __init__(self, source: str):
|
||||
"""Create an OpenGL ComputeShaderProgram from source."""
|
||||
if not (gl_info.have_version(4, 3) or gl_info.have_extension("GL_ARB_compute_shader")):
|
||||
@ -954,12 +952,10 @@ class ComputeShaderProgram:
|
||||
self._uniforms = _introspect_uniforms(self._id, True)
|
||||
self._uniform_blocks = _introspect_uniform_blocks(self)
|
||||
|
||||
self.limits = {
|
||||
'work_group_count': self._get_tuple(GL_MAX_COMPUTE_WORK_GROUP_COUNT),
|
||||
'work_group_size': self._get_tuple(GL_MAX_COMPUTE_WORK_GROUP_SIZE),
|
||||
'work_group_invocations': self._get_value(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS),
|
||||
'shared_memory_size': self._get_value(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE),
|
||||
}
|
||||
self.max_work_group_size = self._get_tuple(GL_MAX_COMPUTE_WORK_GROUP_SIZE)
|
||||
self.max_work_group_count = self._get_tuple(GL_MAX_COMPUTE_WORK_GROUP_COUNT)
|
||||
self.max_shared_memory_size = self._get_value(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE)
|
||||
self.max_work_group_invocations = self._get_value(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS)
|
||||
|
||||
@staticmethod
|
||||
def _get_tuple(parameter: int):
|
||||
|
@ -79,7 +79,6 @@ class VertexDomain:
|
||||
self.program = program
|
||||
self.attribute_meta = attribute_meta
|
||||
self.allocator = allocation.Allocator(self._initial_count)
|
||||
self.vao = vertexarray.VertexArray()
|
||||
|
||||
self.attributes = []
|
||||
self.buffer_attributes = [] # list of (buffer, attributes)
|
||||
@ -99,6 +98,15 @@ class VertexDomain:
|
||||
attribute.buffer.attributes = (attribute,)
|
||||
self.buffer_attributes.append((attribute.buffer, (attribute,)))
|
||||
|
||||
self.vao = vertexarray.VertexArray()
|
||||
self.vao.bind()
|
||||
for buffer, attributes in self.buffer_attributes:
|
||||
buffer.bind()
|
||||
for attribute in attributes:
|
||||
attribute.enable()
|
||||
attribute.set_pointer(buffer.ptr)
|
||||
self.vao.unbind()
|
||||
|
||||
# Create named attributes for each attribute
|
||||
self.attribute_names = {}
|
||||
for attribute in self.attributes:
|
||||
@ -163,12 +171,8 @@ class VertexDomain:
|
||||
|
||||
"""
|
||||
self.vao.bind()
|
||||
|
||||
for buffer, attributes in self.buffer_attributes:
|
||||
for buffer, _ in self.buffer_attributes:
|
||||
buffer.bind()
|
||||
for attribute in attributes:
|
||||
attribute.enable()
|
||||
attribute.set_pointer(attribute.buffer.ptr)
|
||||
|
||||
starts, sizes = self.allocator.get_allocated_regions()
|
||||
primcount = len(starts)
|
||||
@ -182,9 +186,6 @@ class VertexDomain:
|
||||
sizes = (GLsizei * primcount)(*sizes)
|
||||
glMultiDrawArrays(mode, starts, sizes, primcount)
|
||||
|
||||
for buffer, _ in self.buffer_attributes:
|
||||
buffer.unbind()
|
||||
|
||||
def draw_subset(self, mode, vertex_list):
|
||||
"""Draw a specific VertexList in the domain.
|
||||
|
||||
@ -199,18 +200,11 @@ class VertexDomain:
|
||||
|
||||
"""
|
||||
self.vao.bind()
|
||||
|
||||
for buffer, attributes in self.buffer_attributes:
|
||||
for buffer, _ in self.buffer_attributes:
|
||||
buffer.bind()
|
||||
for attribute in attributes:
|
||||
attribute.enable()
|
||||
attribute.set_pointer(attribute.buffer.ptr)
|
||||
|
||||
glDrawArrays(mode, vertex_list.start, vertex_list.count)
|
||||
|
||||
for buffer, _ in self.buffer_attributes:
|
||||
buffer.unbind()
|
||||
|
||||
@property
|
||||
def is_empty(self):
|
||||
return not self.allocator.starts
|
||||
@ -339,6 +333,10 @@ class IndexedVertexDomain(VertexDomain):
|
||||
self.index_element_size = ctypes.sizeof(self.index_c_type)
|
||||
self.index_buffer = BufferObject(self.index_allocator.capacity * self.index_element_size)
|
||||
|
||||
self.vao.bind()
|
||||
self.index_buffer.bind_to_index_buffer()
|
||||
self.vao.unbind()
|
||||
|
||||
def safe_index_alloc(self, count):
|
||||
"""Allocate indices, resizing the buffers if necessary."""
|
||||
try:
|
||||
@ -414,13 +412,8 @@ class IndexedVertexDomain(VertexDomain):
|
||||
|
||||
"""
|
||||
self.vao.bind()
|
||||
|
||||
for buffer, attributes in self.buffer_attributes:
|
||||
for buffer, _ in self.buffer_attributes:
|
||||
buffer.bind()
|
||||
for attribute in attributes:
|
||||
attribute.enable()
|
||||
attribute.set_pointer(attribute.buffer.ptr)
|
||||
self.index_buffer.bind_to_index_buffer()
|
||||
|
||||
starts, sizes = self.index_allocator.get_allocated_regions()
|
||||
primcount = len(starts)
|
||||
@ -436,10 +429,6 @@ class IndexedVertexDomain(VertexDomain):
|
||||
sizes = (GLsizei * primcount)(*sizes)
|
||||
glMultiDrawElements(mode, sizes, self.index_gl_type, starts, primcount)
|
||||
|
||||
self.index_buffer.unbind()
|
||||
for buffer, _ in self.buffer_attributes:
|
||||
buffer.unbind()
|
||||
|
||||
def draw_subset(self, mode, vertex_list):
|
||||
"""Draw a specific IndexedVertexList in the domain.
|
||||
|
||||
@ -454,22 +443,13 @@ class IndexedVertexDomain(VertexDomain):
|
||||
|
||||
"""
|
||||
self.vao.bind()
|
||||
|
||||
for buffer, attributes in self.buffer_attributes:
|
||||
for buffer, _ in self.buffer_attributes:
|
||||
buffer.bind()
|
||||
for attribute in attributes:
|
||||
attribute.enable()
|
||||
attribute.set_pointer(attribute.buffer.ptr)
|
||||
self.index_buffer.bind_to_index_buffer()
|
||||
|
||||
glDrawElements(mode, vertex_list.index_count, self.index_gl_type,
|
||||
self.index_buffer.ptr +
|
||||
vertex_list.index_start * self.index_element_size)
|
||||
|
||||
self.index_buffer.unbind()
|
||||
for buffer, _ in self.buffer_attributes:
|
||||
buffer.unbind()
|
||||
|
||||
|
||||
class IndexedVertexList(VertexList):
|
||||
"""A list of vertices within an :py:class:`IndexedVertexDomain` that are
|
||||
|
@ -2,11 +2,10 @@ from pyglet import compat_platform
|
||||
|
||||
|
||||
# This file is automatically generated by 'pyglet/tools/gen_controller_db.py'
|
||||
# Generated on: Wed Jan 18 14:06:46 2023
|
||||
# Generated on: Wed Aug 30 15:53:55 2023
|
||||
|
||||
if compat_platform.startswith("linux"):
|
||||
mapping_list = [
|
||||
"xinput,*,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
@ -27,6 +26,8 @@ if compat_platform.startswith("linux"):
|
||||
"05000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"03000000c82d00000020000000000000,8BitDo Pro 2 Wired Controller for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"06000000c82d00000020000006010000,8BitDo Pro 2 Wired Controller for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"03000000c82d00000660000011010000,8BitDo Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"03000000c82d00000660000011010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"05000000c82d00000660000000010000,8BitDo Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
@ -87,10 +88,9 @@ if compat_platform.startswith("linux"):
|
||||
"03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
|
||||
"03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,",
|
||||
"03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,",
|
||||
"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,",
|
||||
"050000004c050000f20d000000010000,DualSense Edge Wireless Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
|
||||
"03000000790000001100000010010000,Elecom Gamepad,crc:e86c,a:b2,b:b3,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b0,y:b1,",
|
||||
"0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"0500000047532067616d657061640000,GS Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
|
||||
"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,",
|
||||
@ -104,6 +104,7 @@ if compat_platform.startswith("linux"):
|
||||
"030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"03000000d11800000094000011010000,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
|
||||
"05000000d11800000094000000010000,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
|
||||
"03000000280400000140000000010000,Gravis Gamepad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
"030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,",
|
||||
"030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,",
|
||||
@ -137,6 +138,7 @@ if compat_platform.startswith("linux"):
|
||||
"03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,",
|
||||
"03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
|
||||
"030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"030000006d040000d1ca000011010000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
@ -268,7 +270,8 @@ if compat_platform.startswith("linux"):
|
||||
"050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
|
||||
"0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,",
|
||||
"03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,",
|
||||
"03000000790000001100000010010000,Retrolink SNES Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b0,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"030000006b140000130d000011010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
@ -299,6 +302,7 @@ if compat_platform.startswith("linux"):
|
||||
"05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
|
||||
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
|
||||
"05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
|
||||
"03000000de2800000512000011010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,misc1:b2,paddle1:b21,paddle2:b20,paddle3:b23,paddle4:b22,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,",
|
||||
"03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b18,leftshoulder:b6,leftstick:b13,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:+a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
@ -317,7 +321,6 @@ if compat_platform.startswith("linux"):
|
||||
"03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,",
|
||||
"03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
|
||||
"03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
|
||||
"03000000790000000600000007010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,",
|
||||
"03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,",
|
||||
"05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,",
|
||||
"030000006f0e00000302000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
@ -332,17 +335,10 @@ if compat_platform.startswith("linux"):
|
||||
"0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,",
|
||||
"030000005e040000a102000014010000,Xbox 360 Wireless Receiver (XBOX),a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
|
||||
"050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"050000005e040000050b000003090000,Xbox One Elite Series 2,a:b0,b:b1,back:b121,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"030000005e040000ea02000000000000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"030000005e040000ea02000001030000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"050000005e040000130b000007050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"050000005e040000130b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
|
||||
"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,",
|
||||
"03000000c0160000e105000010010000,Xin-Mo Dual Arcade,crc:82d5,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,",
|
||||
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",
|
||||
@ -408,9 +404,6 @@ elif compat_platform.startswith("darwin"):
|
||||
"03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,",
|
||||
"030000000d0f00008400000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"030000000d0f00008500000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
|
||||
"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,",
|
||||
"03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
|
||||
"03000000ac0500001a06000002020000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
|
||||
"03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
@ -470,7 +463,8 @@ elif compat_platform.startswith("darwin"):
|
||||
"03000000321500000009000000020000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
|
||||
"0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
|
||||
"03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,",
|
||||
"03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,",
|
||||
"03000000790000001100000006010000,Retrolink SNES Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b0,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"030000006b140000130d000000010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
|
||||
@ -508,6 +502,7 @@ elif compat_platform.startswith("darwin"):
|
||||
"030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
|
||||
"030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
|
||||
"03000000c0160000e105000000040000,Xin-Mo Dual Arcade,crc:82d5,a:b2,b:b4,back:b18,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,rightshoulder:b8,righttrigger:b10,start:b16,x:b0,y:b6,",
|
||||
"03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000120c0000101e000000010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000830500006020000000010000,iBuffalo SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
@ -607,9 +602,7 @@ elif compat_platform.startswith("win"):
|
||||
"03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,",
|
||||
"03000000852100000201000000000000,FF-GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
"03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,",
|
||||
"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,",
|
||||
"03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
|
||||
"03000000790000000600000000000000,G-Shark GS-GP702,crc:8e4f,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
|
||||
"030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"03000000300f00000b01000000000000,GGE909 Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
|
||||
"03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
|
||||
@ -649,6 +642,7 @@ elif compat_platform.startswith("win"):
|
||||
"030000000d0f00000900000000000000,Hori Pad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"030000000d0f00005400000000000000,Hori Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"030000000d0f00004d00000000000000,Hori Pad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"030000000d0f00009200000000000000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
"030000000d0f0000c100000000000000,Horipad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,",
|
||||
"030000006f0e00002401000000000000,INJUSTICE FightStick PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
@ -767,7 +761,8 @@ elif compat_platform.startswith("win"):
|
||||
"030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,",
|
||||
"0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,",
|
||||
"03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,",
|
||||
"03000000790000001100000000000000,Retrolink SNES Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b0,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"030000006b140000130d000000000000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"030000006f0e00001e01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
@ -824,6 +819,7 @@ elif compat_platform.startswith("win"):
|
||||
"03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
|
||||
"03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
|
||||
"03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
|
||||
"03000000c0160000e105000000000000,Xin-Mo Dual Arcade,crc:2246,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,",
|
||||
"03000000790000004f18000000000000,ZD-T Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
|
||||
"03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
|
||||
|
@ -398,8 +398,6 @@ class WMFSource(Source):
|
||||
|
||||
def __init__(self, filename, file=None):
|
||||
assert any([self.decode_audio, self.decode_video]), "Source must decode audio, video, or both, not none."
|
||||
self._current_audio_sample = None
|
||||
self._current_audio_buffer = None
|
||||
self._current_video_sample = None
|
||||
self._current_video_buffer = None
|
||||
self._timestamp = 0
|
||||
@ -615,20 +613,13 @@ class WMFSource(Source):
|
||||
def get_audio_data(self, num_bytes, compensation_time=0.0):
|
||||
flags = DWORD()
|
||||
timestamp = ctypes.c_longlong()
|
||||
audio_data_length = DWORD()
|
||||
|
||||
# If we have an audio sample already in use and we call this again, release the memory of buffer and sample.
|
||||
# Can only release after the data is played or else glitches and pops can be heard.
|
||||
if self._current_audio_sample:
|
||||
self._current_audio_buffer.Release()
|
||||
self._current_audio_sample.Release()
|
||||
|
||||
self._current_audio_sample = IMFSample()
|
||||
self._current_audio_buffer = IMFMediaBuffer()
|
||||
imf_sample = IMFSample()
|
||||
imf_buffer = IMFMediaBuffer()
|
||||
|
||||
while True:
|
||||
self._source_reader.ReadSample(self._audio_stream_index, 0, None, ctypes.byref(flags),
|
||||
ctypes.byref(timestamp), ctypes.byref(self._current_audio_sample))
|
||||
ctypes.byref(timestamp), ctypes.byref(imf_sample))
|
||||
|
||||
if flags.value & MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED:
|
||||
assert _debug('WMFAudioDecoder: Data is no longer valid.')
|
||||
@ -638,20 +629,23 @@ class WMFSource(Source):
|
||||
assert _debug('WMFAudioDecoder: End of data from stream source.')
|
||||
break
|
||||
|
||||
if not self._current_audio_sample:
|
||||
if not imf_sample:
|
||||
assert _debug('WMFAudioDecoder: No sample.')
|
||||
continue
|
||||
|
||||
# Convert to single buffer as a sample could potentially(rarely) have multiple buffers.
|
||||
self._current_audio_sample.ConvertToContiguousBuffer(ctypes.byref(self._current_audio_buffer))
|
||||
imf_sample.ConvertToContiguousBuffer(ctypes.byref(imf_buffer))
|
||||
|
||||
audio_data_ptr = POINTER(BYTE)()
|
||||
audio_data_length = DWORD()
|
||||
|
||||
self._current_audio_buffer.Lock(ctypes.byref(audio_data_ptr), None, ctypes.byref(audio_data_length))
|
||||
self._current_audio_buffer.Unlock()
|
||||
imf_buffer.Lock(ctypes.byref(audio_data_ptr), None, ctypes.byref(audio_data_length))
|
||||
|
||||
audio_data = create_string_buffer(audio_data_length.value)
|
||||
memmove(audio_data, audio_data_ptr, audio_data_length.value)
|
||||
audio_data = ctypes.string_at(audio_data_ptr, audio_data_length.value)
|
||||
|
||||
imf_buffer.Unlock()
|
||||
imf_buffer.Release()
|
||||
imf_sample.Release()
|
||||
|
||||
return AudioData(audio_data,
|
||||
audio_data_length.value,
|
||||
@ -688,6 +682,7 @@ class WMFSource(Source):
|
||||
# changes if the stride is added/changed before playback?
|
||||
stride = ctypes.c_uint32()
|
||||
new.GetUINT32(MF_MT_DEFAULT_STRIDE, ctypes.byref(stride))
|
||||
new.Release()
|
||||
|
||||
self._stride = stride.value
|
||||
|
||||
@ -773,16 +768,15 @@ class WMFSource(Source):
|
||||
assert _debug('WMFVideoDecoder: Setting configuration attributes.')
|
||||
|
||||
def __del__(self):
|
||||
if self._source_reader:
|
||||
self._source_reader.Release()
|
||||
|
||||
if self._stream_obj:
|
||||
self._stream_obj.Release()
|
||||
|
||||
if self._imf_bytestream:
|
||||
self._imf_bytestream.Release()
|
||||
|
||||
if self._current_audio_sample:
|
||||
self._current_audio_buffer.Release()
|
||||
self._current_audio_sample.Release()
|
||||
|
||||
if self._current_video_sample:
|
||||
self._current_video_buffer.Release()
|
||||
self._current_video_sample.Release()
|
||||
|
@ -109,7 +109,9 @@ class Player(pyglet.event.EventDispatcher):
|
||||
self._playlists = deque()
|
||||
self._audio_player = None
|
||||
|
||||
self._context = pyglet.gl.current_context
|
||||
self._texture = None
|
||||
|
||||
# Desired play state (not an indication of actual state).
|
||||
self._playing = False
|
||||
|
||||
@ -455,9 +457,12 @@ class Player(pyglet.event.EventDispatcher):
|
||||
|
||||
image = source.get_next_video_frame()
|
||||
if image is not None:
|
||||
if self._texture is None:
|
||||
self._create_texture()
|
||||
self._texture.blit_into(image, 0, 0, 0)
|
||||
|
||||
with self._context:
|
||||
if self._texture is None:
|
||||
self._create_texture()
|
||||
self._texture.blit_into(image, 0, 0, 0)
|
||||
|
||||
elif bl.logger is not None:
|
||||
bl.logger.log("p.P.ut.1.8")
|
||||
|
||||
|
@ -87,25 +87,12 @@ def load(filename, file=None, decoder=None, batch=None, group=None):
|
||||
|
||||
|
||||
def get_default_shader():
|
||||
try:
|
||||
return pyglet.gl.current_context.model_default_plain_shader
|
||||
except AttributeError:
|
||||
vert_shader = shader.Shader(MaterialGroup.default_vert_src, 'vertex')
|
||||
frag_shader = shader.Shader(MaterialGroup.default_frag_src, 'fragment')
|
||||
default_shader_program = shader.ShaderProgram(vert_shader, frag_shader)
|
||||
pyglet.gl.current_context.model_default_plain_shader = default_shader_program
|
||||
return pyglet.gl.current_context.model_default_plain_shader
|
||||
|
||||
return pyglet.gl.current_context.create_program((MaterialGroup.default_vert_src, 'vertex'),
|
||||
(MaterialGroup.default_frag_src, 'fragment'))
|
||||
|
||||
def get_default_textured_shader():
|
||||
try:
|
||||
return pyglet.gl.current_context.model_default_textured_shader
|
||||
except AttributeError:
|
||||
vert_shader = shader.Shader(TexturedMaterialGroup.default_vert_src, 'vertex')
|
||||
frag_shader = shader.Shader(TexturedMaterialGroup.default_frag_src, 'fragment')
|
||||
default_shader_program = shader.ShaderProgram(vert_shader, frag_shader)
|
||||
pyglet.gl.current_context.model_default_textured_shader = default_shader_program
|
||||
return current_context.model_default_textured_shader
|
||||
return pyglet.gl.current_context.create_program((TexturedMaterialGroup.default_vert_src, 'vertex'),
|
||||
(TexturedMaterialGroup.default_frag_src, 'fragment'))
|
||||
|
||||
|
||||
class Model:
|
||||
|
@ -102,21 +102,15 @@ fragment_source = """#version 150 core
|
||||
|
||||
|
||||
def get_default_shader():
|
||||
try:
|
||||
return pyglet.gl.current_context.pyglet_shapes_default_shader
|
||||
except AttributeError:
|
||||
_default_vert_shader = pyglet.graphics.shader.Shader(vertex_source, 'vertex')
|
||||
_default_frag_shader = pyglet.graphics.shader.Shader(fragment_source, 'fragment')
|
||||
default_shader_program = pyglet.graphics.shader.ShaderProgram(_default_vert_shader, _default_frag_shader)
|
||||
pyglet.gl.current_context.pyglet_shapes_default_shader = default_shader_program
|
||||
return default_shader_program
|
||||
return pyglet.gl.current_context.create_program((vertex_source, 'vertex'),
|
||||
(fragment_source, 'fragment'))
|
||||
|
||||
|
||||
def _rotate_point(center, point, angle):
|
||||
prev_angle = math.atan2(point[1] - center[1], point[0] - center[0])
|
||||
now_angle = prev_angle + angle
|
||||
r = math.dist(point, center)
|
||||
return (center[0] + r * math.cos(now_angle), center[1] + r * math.sin(now_angle))
|
||||
return center[0] + r * math.cos(now_angle), center[1] + r * math.sin(now_angle)
|
||||
|
||||
|
||||
def _sat(vertices, point):
|
||||
@ -198,6 +192,7 @@ class ShapeBase(ABC):
|
||||
"""
|
||||
|
||||
_rgba = (255, 255, 255, 255)
|
||||
_rotation = 0
|
||||
_visible = True
|
||||
_x = 0
|
||||
_y = 0
|
||||
@ -258,6 +253,29 @@ class ShapeBase(ABC):
|
||||
"""
|
||||
raise NotImplementedError("_update_vertices must be defined"
|
||||
"for every ShapeBase subclass")
|
||||
@property
|
||||
def rotation(self) -> float:
|
||||
"""Clockwise rotation of the shape in degrees.
|
||||
|
||||
It will be rotated about its (anchor_x, anchor_y) position,
|
||||
which defaults to the first vertex point of the shape.
|
||||
|
||||
For most shapes, this is the lower left corner. The shapes
|
||||
below default to the points their ``radius`` values are
|
||||
measured from:
|
||||
|
||||
* :py:class:`.Circle`
|
||||
* :py:class:`.Ellipse`
|
||||
* :py:class:`.Arc`
|
||||
* :py:class:`.Sector`
|
||||
* :py:class:`.Star`
|
||||
"""
|
||||
return self._rotation
|
||||
|
||||
@rotation.setter
|
||||
def rotation(self, rotation: float) -> None:
|
||||
self._rotation = rotation
|
||||
self._vertex_list.rotation[:] = (rotation,) * self._num_verts
|
||||
|
||||
def draw(self):
|
||||
"""Draw the shape at its current position.
|
||||
@ -551,22 +569,6 @@ class Arc(ShapeBase):
|
||||
|
||||
self._vertex_list.position[:] = vertices
|
||||
|
||||
@property
|
||||
def rotation(self):
|
||||
"""Clockwise rotation of the arc, in degrees.
|
||||
|
||||
The arc will be rotated about its (anchor_x, anchor_y)
|
||||
position.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._rotation
|
||||
|
||||
@rotation.setter
|
||||
def rotation(self, rotation):
|
||||
self._rotation = rotation
|
||||
self._vertex_list.rotation[:] = (rotation,) * self._num_verts
|
||||
|
||||
@property
|
||||
def angle(self):
|
||||
"""The angle of the arc.
|
||||
@ -629,6 +631,7 @@ class BezierCurve(ShapeBase):
|
||||
Optional parent group of the curve.
|
||||
"""
|
||||
self._points = list(points)
|
||||
self._x, self._y = self._points[0]
|
||||
self._t = t
|
||||
self._segments = segments
|
||||
self._num_verts = self._segments * 2
|
||||
@ -655,7 +658,7 @@ class BezierCurve(ShapeBase):
|
||||
self._vertex_list = self._group.program.vertex_list(
|
||||
self._num_verts, self._draw_mode, self._batch, self._group,
|
||||
colors=('Bn', self._rgba * self._num_verts),
|
||||
translation=('f', (self._points[0]) * self._num_verts))
|
||||
translation=('f', (self._x, self._y) * self._num_verts))
|
||||
|
||||
def _update_vertices(self):
|
||||
if not self._visible:
|
||||
@ -902,22 +905,6 @@ class Ellipse(ShapeBase):
|
||||
self._b = value
|
||||
self._update_vertices()
|
||||
|
||||
@property
|
||||
def rotation(self):
|
||||
"""Clockwise rotation of the arc, in degrees.
|
||||
|
||||
The arc will be rotated about its (anchor_x, anchor_y)
|
||||
position.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._rotation
|
||||
|
||||
@rotation.setter
|
||||
def rotation(self, rotation):
|
||||
self._rotation = rotation
|
||||
self._vertex_list.rotation[:] = (rotation,) * self._num_verts
|
||||
|
||||
|
||||
class Sector(ShapeBase):
|
||||
def __init__(self, x, y, radius, segments=None, angle=math.tau, start_angle=0,
|
||||
@ -1048,22 +1035,6 @@ class Sector(ShapeBase):
|
||||
self._radius = value
|
||||
self._update_vertices()
|
||||
|
||||
@property
|
||||
def rotation(self):
|
||||
"""Clockwise rotation of the sector, in degrees.
|
||||
|
||||
The sector will be rotated about its (anchor_x, anchor_y)
|
||||
position.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._rotation
|
||||
|
||||
@rotation.setter
|
||||
def rotation(self, rotation):
|
||||
self._rotation = rotation
|
||||
self._vertex_list.rotation[:] = (rotation,) * self._num_verts
|
||||
|
||||
|
||||
class Line(ShapeBase):
|
||||
def __init__(self, x, y, x2, y2, width=1, color=(255, 255, 255, 255),
|
||||
@ -1286,22 +1257,6 @@ class Rectangle(ShapeBase):
|
||||
self._height = value
|
||||
self._update_vertices()
|
||||
|
||||
@property
|
||||
def rotation(self):
|
||||
"""Clockwise rotation of the rectangle, in degrees.
|
||||
|
||||
The Rectangle will be rotated about its (anchor_x, anchor_y)
|
||||
position.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._rotation
|
||||
|
||||
@rotation.setter
|
||||
def rotation(self, rotation):
|
||||
self._rotation = rotation
|
||||
self._vertex_list.rotation[:] = (rotation,) * self._num_verts
|
||||
|
||||
|
||||
class BorderedRectangle(ShapeBase):
|
||||
def __init__(self, x, y, width, height, border=1, color=(255, 255, 255),
|
||||
@ -1449,22 +1404,6 @@ class BorderedRectangle(ShapeBase):
|
||||
self._height = value
|
||||
self._update_vertices()
|
||||
|
||||
@property
|
||||
def rotation(self):
|
||||
"""Clockwise rotation of the rectangle, in degrees.
|
||||
|
||||
The Rectangle will be rotated about its (anchor_x, anchor_y)
|
||||
position.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._rotation
|
||||
|
||||
@rotation.setter
|
||||
def rotation(self, rotation):
|
||||
self._rotation = rotation
|
||||
self._vertex_list.rotation[:] = (rotation,) * self._num_verts
|
||||
|
||||
@property
|
||||
def border_color(self):
|
||||
"""The rectangle's border color.
|
||||
@ -1771,17 +1710,6 @@ class Star(ShapeBase):
|
||||
self._num_spikes = value
|
||||
self._update_vertices()
|
||||
|
||||
@property
|
||||
def rotation(self):
|
||||
"""Rotation of the star, in degrees.
|
||||
"""
|
||||
return self._rotation
|
||||
|
||||
@rotation.setter
|
||||
def rotation(self, rotation):
|
||||
self._rotation = rotation
|
||||
self._vertex_list.rotation[:] = (rotation,) * self._num_verts
|
||||
|
||||
|
||||
class Polygon(ShapeBase):
|
||||
def __init__(self, *coordinates, color=(255, 255, 255, 255), batch=None, group=None):
|
||||
@ -1805,6 +1733,7 @@ class Polygon(ShapeBase):
|
||||
# len(self._coordinates) = the number of vertices and sides in the shape.
|
||||
self._rotation = 0
|
||||
self._coordinates = list(coordinates)
|
||||
self._x, self._y = self._coordinates[0]
|
||||
self._num_verts = (len(self._coordinates) - 2) * 3
|
||||
|
||||
r, g, b, *a = color
|
||||
@ -1826,7 +1755,7 @@ class Polygon(ShapeBase):
|
||||
self._vertex_list = self._group.program.vertex_list(
|
||||
self._num_verts, self._draw_mode, self._batch, self._group,
|
||||
colors=('Bn', self._rgba * self._num_verts),
|
||||
translation=('f', (self._coordinates[0]) * self._num_verts))
|
||||
translation=('f', (self._x, self._y) * self._num_verts))
|
||||
|
||||
def _update_vertices(self):
|
||||
if not self._visible:
|
||||
@ -1846,21 +1775,5 @@ class Polygon(ShapeBase):
|
||||
# Flattening the list before setting vertices to it.
|
||||
self._vertex_list.position[:] = tuple(value for coordinate in triangles for value in coordinate)
|
||||
|
||||
@property
|
||||
def rotation(self):
|
||||
"""Clockwise rotation of the polygon, in degrees.
|
||||
|
||||
The Polygon will be rotated about its (anchor_x, anchor_y)
|
||||
position.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._rotation
|
||||
|
||||
@rotation.setter
|
||||
def rotation(self, rotation):
|
||||
self._rotation = rotation
|
||||
self._vertex_list.rotation[:] = (rotation,) * self._num_verts
|
||||
|
||||
|
||||
__all__ = 'Arc', 'BezierCurve', 'Circle', 'Ellipse', 'Line', 'Rectangle', 'BorderedRectangle', 'Triangle', 'Star', 'Polygon', 'Sector'
|
||||
|
@ -146,25 +146,12 @@ fragment_array_source = """#version 150 core
|
||||
|
||||
|
||||
def get_default_shader():
|
||||
try:
|
||||
return pyglet.gl.current_context.pyglet_sprite_default_shader
|
||||
except AttributeError:
|
||||
_default_vert_shader = graphics.shader.Shader(vertex_source, 'vertex')
|
||||
_default_frag_shader = graphics.shader.Shader(fragment_source, 'fragment')
|
||||
default_shader_program = graphics.shader.ShaderProgram(_default_vert_shader, _default_frag_shader)
|
||||
pyglet.gl.current_context.pyglet_sprite_default_shader = default_shader_program
|
||||
return pyglet.gl.current_context.pyglet_sprite_default_shader
|
||||
|
||||
return pyglet.gl.current_context.create_program((vertex_source, 'vertex'),
|
||||
(fragment_source, 'fragment'))
|
||||
|
||||
def get_default_array_shader():
|
||||
try:
|
||||
return pyglet.gl.current_context.pyglet_sprite_default_array_shader
|
||||
except AttributeError:
|
||||
_default_vert_shader = graphics.shader.Shader(vertex_source, 'vertex')
|
||||
_default_array_frag_shader = graphics.shader.Shader(fragment_array_source, 'fragment')
|
||||
default_shader_program = graphics.shader.ShaderProgram(_default_vert_shader, _default_array_frag_shader)
|
||||
pyglet.gl.current_context.pyglet_sprite_default_array_shader = default_shader_program
|
||||
return pyglet.gl.current_context.pyglet_sprite_default_array_shader
|
||||
return pyglet.gl.current_context.create_program((vertex_source, 'vertex'),
|
||||
(fragment_array_source, 'fragment'))
|
||||
|
||||
|
||||
class SpriteGroup(graphics.Group):
|
||||
|
@ -127,11 +127,175 @@ from pyglet import graphics
|
||||
from pyglet.gl import *
|
||||
from pyglet.event import EventDispatcher
|
||||
from pyglet.text import runlist
|
||||
from pyglet.graphics import shader
|
||||
from pyglet.font.base import grapheme_break
|
||||
|
||||
_is_pyglet_doc_run = hasattr(sys, "is_pyglet_doc_run") and sys.is_pyglet_doc_run
|
||||
|
||||
|
||||
layout_vertex_source = """#version 330 core
|
||||
in vec3 position;
|
||||
in vec4 colors;
|
||||
in vec3 tex_coords;
|
||||
in vec3 translation;
|
||||
in vec2 anchor;
|
||||
in float rotation;
|
||||
|
||||
out vec4 text_colors;
|
||||
out vec2 texture_coords;
|
||||
out vec4 vert_position;
|
||||
|
||||
uniform WindowBlock
|
||||
{
|
||||
mat4 projection;
|
||||
mat4 view;
|
||||
} window;
|
||||
|
||||
mat4 m_rotation = mat4(1.0);
|
||||
mat4 m_anchor = mat4(1.0);
|
||||
mat4 m_neganchor = mat4(1.0);
|
||||
|
||||
void main()
|
||||
{
|
||||
m_anchor[3][0] = anchor.x;
|
||||
m_anchor[3][1] = anchor.y;
|
||||
m_neganchor[3][0] = -anchor.x;
|
||||
m_neganchor[3][1] = -anchor.y;
|
||||
m_rotation[0][0] = cos(-radians(rotation));
|
||||
m_rotation[0][1] = sin(-radians(rotation));
|
||||
m_rotation[1][0] = -sin(-radians(rotation));
|
||||
m_rotation[1][1] = cos(-radians(rotation));
|
||||
|
||||
gl_Position = window.projection * window.view * m_anchor * m_rotation * m_neganchor * vec4(position + translation, 1.0);
|
||||
|
||||
vert_position = vec4(position + translation, 1.0);
|
||||
text_colors = colors;
|
||||
texture_coords = tex_coords.xy;
|
||||
}
|
||||
"""
|
||||
|
||||
layout_fragment_source = """#version 330 core
|
||||
in vec4 text_colors;
|
||||
in vec2 texture_coords;
|
||||
in vec4 vert_position;
|
||||
|
||||
out vec4 final_colors;
|
||||
|
||||
uniform sampler2D text;
|
||||
uniform bool scissor;
|
||||
uniform vec4 scissor_area;
|
||||
|
||||
void main()
|
||||
{
|
||||
final_colors = vec4(text_colors.rgb, texture(text, texture_coords).a * text_colors.a);
|
||||
if (scissor == true) {
|
||||
if (vert_position.x < scissor_area[0]) discard; // left
|
||||
if (vert_position.y < scissor_area[1]) discard; // bottom
|
||||
if (vert_position.x > scissor_area[0] + scissor_area[2]) discard; // right
|
||||
if (vert_position.y > scissor_area[1] + scissor_area[3]) discard; // top
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
layout_fragment_image_source = """#version 330 core
|
||||
in vec4 text_colors;
|
||||
in vec2 texture_coords;
|
||||
in vec4 vert_position;
|
||||
|
||||
uniform sampler2D image_texture;
|
||||
|
||||
out vec4 final_colors;
|
||||
|
||||
uniform sampler2D text;
|
||||
uniform bool scissor;
|
||||
uniform vec4 scissor_area;
|
||||
|
||||
void main()
|
||||
{
|
||||
final_colors = texture(image_texture, texture_coords.xy);
|
||||
if (scissor == true) {
|
||||
if (vert_position.x < scissor_area[0]) discard; // left
|
||||
if (vert_position.y < scissor_area[1]) discard; // bottom
|
||||
if (vert_position.x > scissor_area[0] + scissor_area[2]) discard; // right
|
||||
if (vert_position.y > scissor_area[1] + scissor_area[3]) discard; // top
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
decoration_vertex_source = """#version 330 core
|
||||
in vec3 position;
|
||||
in vec4 colors;
|
||||
in vec3 translation;
|
||||
in vec2 anchor;
|
||||
in float rotation;
|
||||
|
||||
out vec4 vert_colors;
|
||||
out vec4 vert_position;
|
||||
|
||||
uniform WindowBlock
|
||||
{
|
||||
mat4 projection;
|
||||
mat4 view;
|
||||
} window;
|
||||
|
||||
mat4 m_rotation = mat4(1.0);
|
||||
mat4 m_anchor = mat4(1.0);
|
||||
mat4 m_neganchor = mat4(1.0);
|
||||
|
||||
void main()
|
||||
{
|
||||
m_anchor[3][0] = anchor.x;
|
||||
m_anchor[3][1] = anchor.y;
|
||||
m_neganchor[3][0] = -anchor.x;
|
||||
m_neganchor[3][1] = -anchor.y;
|
||||
m_rotation[0][0] = cos(-radians(rotation));
|
||||
m_rotation[0][1] = sin(-radians(rotation));
|
||||
m_rotation[1][0] = -sin(-radians(rotation));
|
||||
m_rotation[1][1] = cos(-radians(rotation));
|
||||
|
||||
gl_Position = window.projection * window.view * m_anchor * m_rotation * m_neganchor * vec4(position + translation, 1.0);
|
||||
|
||||
vert_position = vec4(position + translation, 1.0);
|
||||
vert_colors = colors;
|
||||
}
|
||||
"""
|
||||
|
||||
decoration_fragment_source = """#version 330 core
|
||||
in vec4 vert_colors;
|
||||
in vec4 vert_position;
|
||||
|
||||
out vec4 final_colors;
|
||||
|
||||
uniform bool scissor;
|
||||
uniform vec4 scissor_area;
|
||||
|
||||
void main()
|
||||
{
|
||||
final_colors = vert_colors;
|
||||
if (scissor == true) {
|
||||
if (vert_position.x < scissor_area[0]) discard; // left
|
||||
if (vert_position.y < scissor_area[1]) discard; // bottom
|
||||
if (vert_position.x > scissor_area[0] + scissor_area[2]) discard; // right
|
||||
if (vert_position.y > scissor_area[1] + scissor_area[3]) discard; // top
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
def get_default_layout_shader():
|
||||
return pyglet.gl.current_context.create_program((layout_vertex_source, 'vertex'),
|
||||
(layout_fragment_source, 'fragment'))
|
||||
|
||||
|
||||
def get_default_image_layout_shader():
|
||||
return pyglet.gl.current_context.create_program((layout_vertex_source, 'vertex'),
|
||||
(layout_fragment_image_source, 'fragment'))
|
||||
|
||||
|
||||
def get_default_decoration_shader():
|
||||
return pyglet.gl.current_context.create_program((decoration_vertex_source, 'vertex'),
|
||||
(decoration_fragment_source, 'fragment'))
|
||||
|
||||
|
||||
_distance_re = re.compile(r'([-0-9.]+)([a-zA-Z]+)')
|
||||
|
||||
|
||||
@ -503,186 +667,7 @@ class _InvalidRange:
|
||||
return self.end > self.start
|
||||
|
||||
|
||||
layout_vertex_source = """#version 330 core
|
||||
in vec3 position;
|
||||
in vec4 colors;
|
||||
in vec3 tex_coords;
|
||||
in vec3 translation;
|
||||
in vec2 anchor;
|
||||
in float rotation;
|
||||
|
||||
out vec4 text_colors;
|
||||
out vec2 texture_coords;
|
||||
out vec4 vert_position;
|
||||
|
||||
uniform WindowBlock
|
||||
{
|
||||
mat4 projection;
|
||||
mat4 view;
|
||||
} window;
|
||||
|
||||
mat4 m_rotation = mat4(1.0);
|
||||
mat4 m_anchor = mat4(1.0);
|
||||
mat4 m_neganchor = mat4(1.0);
|
||||
|
||||
void main()
|
||||
{
|
||||
m_anchor[3][0] = anchor.x;
|
||||
m_anchor[3][1] = anchor.y;
|
||||
m_neganchor[3][0] = -anchor.x;
|
||||
m_neganchor[3][1] = -anchor.y;
|
||||
m_rotation[0][0] = cos(-radians(rotation));
|
||||
m_rotation[0][1] = sin(-radians(rotation));
|
||||
m_rotation[1][0] = -sin(-radians(rotation));
|
||||
m_rotation[1][1] = cos(-radians(rotation));
|
||||
|
||||
gl_Position = window.projection * window.view * m_anchor * m_rotation * m_neganchor * vec4(position + translation, 1.0);
|
||||
|
||||
vert_position = vec4(position + translation, 1.0);
|
||||
text_colors = colors;
|
||||
texture_coords = tex_coords.xy;
|
||||
}
|
||||
"""
|
||||
|
||||
layout_fragment_source = """#version 330 core
|
||||
in vec4 text_colors;
|
||||
in vec2 texture_coords;
|
||||
in vec4 vert_position;
|
||||
|
||||
out vec4 final_colors;
|
||||
|
||||
uniform sampler2D text;
|
||||
uniform bool scissor;
|
||||
uniform vec4 scissor_area;
|
||||
|
||||
void main()
|
||||
{
|
||||
final_colors = vec4(text_colors.rgb, texture(text, texture_coords).a * text_colors.a);
|
||||
if (scissor == true) {
|
||||
if (vert_position.x < scissor_area[0]) discard; // left
|
||||
if (vert_position.y < scissor_area[1]) discard; // bottom
|
||||
if (vert_position.x > scissor_area[0] + scissor_area[2]) discard; // right
|
||||
if (vert_position.y > scissor_area[1] + scissor_area[3]) discard; // top
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
layout_fragment_image_source = """#version 330 core
|
||||
in vec4 text_colors;
|
||||
in vec2 texture_coords;
|
||||
in vec4 vert_position;
|
||||
|
||||
uniform sampler2D image_texture;
|
||||
|
||||
out vec4 final_colors;
|
||||
|
||||
uniform sampler2D text;
|
||||
uniform bool scissor;
|
||||
uniform vec4 scissor_area;
|
||||
|
||||
void main()
|
||||
{
|
||||
final_colors = texture(image_texture, texture_coords.xy);
|
||||
if (scissor == true) {
|
||||
if (vert_position.x < scissor_area[0]) discard; // left
|
||||
if (vert_position.y < scissor_area[1]) discard; // bottom
|
||||
if (vert_position.x > scissor_area[0] + scissor_area[2]) discard; // right
|
||||
if (vert_position.y > scissor_area[1] + scissor_area[3]) discard; // top
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
decoration_vertex_source = """#version 330 core
|
||||
in vec3 position;
|
||||
in vec4 colors;
|
||||
in vec3 translation;
|
||||
in vec2 anchor;
|
||||
in float rotation;
|
||||
|
||||
out vec4 vert_colors;
|
||||
out vec4 vert_position;
|
||||
|
||||
uniform WindowBlock
|
||||
{
|
||||
mat4 projection;
|
||||
mat4 view;
|
||||
} window;
|
||||
|
||||
mat4 m_rotation = mat4(1.0);
|
||||
mat4 m_anchor = mat4(1.0);
|
||||
mat4 m_neganchor = mat4(1.0);
|
||||
|
||||
void main()
|
||||
{
|
||||
m_anchor[3][0] = anchor.x;
|
||||
m_anchor[3][1] = anchor.y;
|
||||
m_neganchor[3][0] = -anchor.x;
|
||||
m_neganchor[3][1] = -anchor.y;
|
||||
m_rotation[0][0] = cos(-radians(rotation));
|
||||
m_rotation[0][1] = sin(-radians(rotation));
|
||||
m_rotation[1][0] = -sin(-radians(rotation));
|
||||
m_rotation[1][1] = cos(-radians(rotation));
|
||||
|
||||
gl_Position = window.projection * window.view * m_anchor * m_rotation * m_neganchor * vec4(position + translation, 1.0);
|
||||
|
||||
vert_position = vec4(position + translation, 1.0);
|
||||
vert_colors = colors;
|
||||
}
|
||||
"""
|
||||
|
||||
decoration_fragment_source = """#version 330 core
|
||||
in vec4 vert_colors;
|
||||
in vec4 vert_position;
|
||||
|
||||
out vec4 final_colors;
|
||||
|
||||
uniform bool scissor;
|
||||
uniform vec4 scissor_area;
|
||||
|
||||
void main()
|
||||
{
|
||||
final_colors = vert_colors;
|
||||
if (scissor == true) {
|
||||
if (vert_position.x < scissor_area[0]) discard; // left
|
||||
if (vert_position.y < scissor_area[1]) discard; // bottom
|
||||
if (vert_position.x > scissor_area[0] + scissor_area[2]) discard; // right
|
||||
if (vert_position.y > scissor_area[1] + scissor_area[3]) discard; // top
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
def get_default_layout_shader():
|
||||
try:
|
||||
return pyglet.gl.current_context.pyglet_text_layout_shader
|
||||
except AttributeError:
|
||||
pyglet.gl.current_context.pyglet_text_layout_shader = shader.ShaderProgram(
|
||||
shader.Shader(layout_vertex_source, 'vertex'),
|
||||
shader.Shader(layout_fragment_source, 'fragment'),
|
||||
)
|
||||
return pyglet.gl.current_context.pyglet_text_layout_shader
|
||||
|
||||
|
||||
def get_default_image_layout_shader():
|
||||
try:
|
||||
return pyglet.gl.current_context.pyglet_text_layout_image_shader
|
||||
except AttributeError:
|
||||
pyglet.gl.current_context.pyglet_text_layout_image_shader = shader.ShaderProgram(
|
||||
shader.Shader(layout_vertex_source, 'vertex'),
|
||||
shader.Shader(layout_fragment_image_source, 'fragment'),
|
||||
)
|
||||
return pyglet.gl.current_context.pyglet_text_layout_image_shader
|
||||
|
||||
|
||||
def get_default_decoration_shader():
|
||||
try:
|
||||
return pyglet.gl.current_context.pyglet_text_decoration_shader
|
||||
except AttributeError:
|
||||
pyglet.gl.current_context.pyglet_text_decoration_shader = shader.ShaderProgram(
|
||||
shader.Shader(decoration_vertex_source, 'vertex'),
|
||||
shader.Shader(decoration_fragment_source, 'fragment'),
|
||||
)
|
||||
return pyglet.gl.current_context.pyglet_text_decoration_shader
|
||||
# ####################
|
||||
|
||||
|
||||
class TextLayoutGroup(graphics.Group):
|
||||
|
@ -213,7 +213,16 @@ MODESWITCH = 0xff7e
|
||||
SCRIPTSWITCH = 0xff7e
|
||||
FUNCTION = 0xffd2
|
||||
|
||||
# Text motion constants: these are allowed to clash with key constants
|
||||
# Text motion constants
|
||||
# These are allowed to clash with key constants since they are
|
||||
# abstractions of keyboard shortcuts. See the following for more
|
||||
# information:
|
||||
#
|
||||
# 1. doc/programming_guide/keyboard.rst
|
||||
# 2. doc/modules/window_key.rst
|
||||
#
|
||||
# To add new motions, consult the Adding New Motions section of
|
||||
# doc/programming_guide/keyboard.rst
|
||||
MOTION_UP = UP
|
||||
MOTION_RIGHT = RIGHT
|
||||
MOTION_DOWN = DOWN
|
||||
|
@ -1,9 +1,12 @@
|
||||
import locale
|
||||
import unicodedata
|
||||
import urllib.parse
|
||||
|
||||
from ctypes import *
|
||||
from functools import lru_cache
|
||||
|
||||
import pyglet
|
||||
|
||||
from pyglet.window import WindowException, MouseCursorException
|
||||
from pyglet.window import MouseCursor, DefaultMouseCursor, ImageMouseCursor
|
||||
from pyglet.window import BaseWindow, _PlatformEventHandler, _ViewEventHandler
|
||||
@ -47,8 +50,7 @@ XA_ATOM = 4
|
||||
|
||||
XDND_VERSION = 5
|
||||
|
||||
# Do we have the November 2000 UTF8 extension?
|
||||
_have_utf8 = hasattr(xlib._lib, 'Xutf8TextListToTextProperty')
|
||||
_have_utf8 = locale.getlocale()[1] == 'UTF-8'
|
||||
|
||||
# symbol,ctrl -> motion mapping
|
||||
_motion_map = {
|
||||
|
7
libs/utils/logger/__init__.py
Normal file
7
libs/utils/logger/__init__.py
Normal file
@ -0,0 +1,7 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
|
9
libs/utils/logger/logger.py
Normal file
9
libs/utils/logger/logger.py
Normal file
@ -0,0 +1,9 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
from lib_not_dr.types.options import Options
|
||||
|
||||
|
33
libs/utils/logger/types.py
Normal file
33
libs/utils/logger/types.py
Normal file
@ -0,0 +1,33 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
import time
|
||||
|
||||
from types import FrameType
|
||||
from typing import List, Optional
|
||||
|
||||
from lib_not_dr.types.options import Options
|
||||
|
||||
|
||||
class LogMessage(Options):
|
||||
name = 'LogMessage'
|
||||
|
||||
# 消息内容本身的属性
|
||||
messages: List[str] = []
|
||||
end: str = '\n'
|
||||
split: str = ' '
|
||||
|
||||
# 消息的属性
|
||||
flush: bool = True
|
||||
level: int = 20
|
||||
log_time: float = time.time_ns()
|
||||
logger_name: str = 'root'
|
||||
logger_tag: Optional[str] = None
|
||||
stack_trace: Optional[FrameType] = None
|
||||
|
||||
|
||||
# [App -> Logger] -> Queue(raw log) -> [Handler -> Formatter -> (File, Socket) Output] ?
|
||||
# |-> Handler -> Formatter -> Console Output
|
@ -9,12 +9,46 @@ import platform
|
||||
import warnings
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
from typing import List, Tuple, Optional, Any
|
||||
from typing import List, Tuple, Optional, Union, Any
|
||||
|
||||
from Difficult_Rocket.api.types import Options, Version, VersionRequirement
|
||||
|
||||
|
||||
def _add_cmd(cmd: List[str], string: Optional[Any]) -> List[str]:
|
||||
def ensure_cmd_readable(cmd: str) -> str:
|
||||
"""
|
||||
保证 参数中 不含空格
|
||||
:param cmd: 要格式化的命令行参数
|
||||
:return: 格式化后的命令行参数
|
||||
"""
|
||||
if ' ' in str(cmd):
|
||||
return f'"{cmd}"'
|
||||
return cmd
|
||||
|
||||
|
||||
def format_cmd(arg_name: Optional[str] = None,
|
||||
arg_value: Optional[Union[str, List[str]]] = None,
|
||||
write: Optional[Any] = True) -> List[str]:
|
||||
"""
|
||||
用来格式化输出命令行参数
|
||||
:param arg_name: 类似 --show-memory 之类的主项
|
||||
:param arg_value: 类似 xxx 类的内容
|
||||
:param write: 是否写入
|
||||
:return: 直接拼接好的命令行参数 不带 =
|
||||
"""
|
||||
if not write:
|
||||
return []
|
||||
if arg_name is None:
|
||||
return []
|
||||
if arg_value is None:
|
||||
return [arg_name]
|
||||
if isinstance(arg_value, list):
|
||||
arg_value = ','.join([ensure_cmd_readable(value) for value in arg_value])
|
||||
return [f'{arg_name}{arg_value}']
|
||||
arg_value = ensure_cmd_readable(arg_value)
|
||||
return [f'{arg_name}{arg_value}']
|
||||
|
||||
|
||||
def _add_cmd(cmd: List[str], string: Optional[str]) -> List[str]:
|
||||
if string is not None and string:
|
||||
cmd.append(string)
|
||||
return cmd
|
||||
@ -32,13 +66,16 @@ class CompilerHelper(Options):
|
||||
src_file: Path = Path('DR.py')
|
||||
|
||||
python_cmd: str = 'python'
|
||||
compat_nuitka_version: VersionRequirement = VersionRequirement("~1.7.1") # STATIC VERSION
|
||||
compat_nuitka_version: VersionRequirement = VersionRequirement("~1.8.1") # STATIC VERSION
|
||||
|
||||
# 以下为 nuitka 的参数
|
||||
use_lto: bool = False # --lto=yes (no is faster)
|
||||
use_clang: bool = True # --clang
|
||||
use_msvc: bool = True # --msvc=latest
|
||||
use_mingw: bool = False # --mingw64
|
||||
|
||||
onefile: bool = False # --onefile
|
||||
onefile_tempdir: Optional[str] = '' # --onefile-tempdir-spec=
|
||||
standalone: bool = True # --standalone
|
||||
use_ccache: bool = True # not --disable-ccache
|
||||
enable_console: bool = True # --enable-console / --disable-console
|
||||
@ -48,6 +85,8 @@ class CompilerHelper(Options):
|
||||
remove_output: bool = True # --remove-output
|
||||
save_xml: bool = False # --xml
|
||||
xml_path: Path = Path('build/compile_data.xml')
|
||||
save_report: bool = False # --report
|
||||
report_path: Path = Path('build/compile_report.xml')
|
||||
|
||||
download_confirm: bool = True # --assume-yes-for-download
|
||||
run_after_build: bool = False # --run
|
||||
@ -71,7 +110,7 @@ class CompilerHelper(Options):
|
||||
include_packages: List[str] = ['Difficult_Rocket.api']
|
||||
|
||||
enable_plugin: List[str] = [] # --enable-plugin=xxx,xxx
|
||||
disable_plugin: List[str] = [] # --disable-plugin=xxx,xxx
|
||||
disable_plugin: List[str] = ['pyqt5', 'tk-inter'] # --disable-plugin=xxx,xxx
|
||||
|
||||
def init(self, **kwargs) -> None:
|
||||
if (compat_version := kwargs.get('compat_nuitka_version')) is not None:
|
||||
@ -132,40 +171,43 @@ class CompilerHelper(Options):
|
||||
cmd_list = [self.python_cmd, '-m', 'nuitka']
|
||||
# macos 和 非 macos icon 参数不同
|
||||
if platform.system() == 'Darwin':
|
||||
cmd_list.append(f"--macos-app-version={self.product_version}")
|
||||
_add_cmd(cmd_list, f'--macos-app-icon={self.icon_path.absolute()}' if self.icon_path else None)
|
||||
cmd_list += format_cmd('--macos-app-version=', self.product_version, self.product_version) # noqa
|
||||
cmd_list += format_cmd('--macos-app-icon=', self.icon_path.absolute(), self.icon_path) # noqa
|
||||
elif platform.system() == 'Windows':
|
||||
_add_cmd(cmd_list, f'--windows-icon-from-ico={self.icon_path.absolute()}' if self.icon_path else None)
|
||||
cmd_list += format_cmd('--windows-icon-from-ico=', self.icon_path.absolute(), self.icon_path) # noqa
|
||||
elif platform.system() == 'Linux':
|
||||
_add_cmd(cmd_list, f'--linux-icon={self.icon_path.absolute()}' if self.icon_path else None)
|
||||
cmd_list += format_cmd('--linux-icon=', self.icon_path.absolute(), self.icon_path) # noqa
|
||||
|
||||
_add_cmd(cmd_list, '--lto=yes' if self.use_lto else '--lto=no')
|
||||
_add_cmd(cmd_list, '--clang' if self.use_clang else None)
|
||||
_add_cmd(cmd_list, '--msvc=latest' if self.use_msvc else None)
|
||||
_add_cmd(cmd_list, '--mingw64' if self.use_mingw else None)
|
||||
_add_cmd(cmd_list, '--standalone' if self.standalone else None)
|
||||
cmd_list += format_cmd('--lto=', 'yes' if self.use_lto else 'no')
|
||||
cmd_list += format_cmd('--clang' if self.use_clang else None)
|
||||
cmd_list += format_cmd('--msvc=latest' if self.use_msvc else None)
|
||||
cmd_list += format_cmd('--mingw64' if self.use_mingw else None)
|
||||
cmd_list += format_cmd('--standalone' if self.standalone else None)
|
||||
cmd_list += format_cmd('--onefile' if self.onefile else None)
|
||||
cmd_list += format_cmd('--onefile-tempdir-spec=', self.onefile_tempdir, self.onefile_tempdir)
|
||||
|
||||
_add_cmd(cmd_list, '--disable-ccache' if not self.use_ccache else None)
|
||||
_add_cmd(cmd_list, '--show-progress' if self.show_progress else None)
|
||||
_add_cmd(cmd_list, '--show-memory' if self.show_memory else None)
|
||||
_add_cmd(cmd_list, '--remove-output' if self.remove_output else None)
|
||||
_add_cmd(cmd_list, '--assume-yes-for-download' if self.download_confirm else None)
|
||||
_add_cmd(cmd_list, '--run' if self.run_after_build else None)
|
||||
_add_cmd(cmd_list, '--enable-console' if self.enable_console else '--disable-console')
|
||||
cmd_list += format_cmd('--disable-ccache' if not self.use_ccache else None)
|
||||
cmd_list += format_cmd('--show-progress' if self.show_progress else None)
|
||||
cmd_list += format_cmd('--show-memory' if self.show_memory else None)
|
||||
cmd_list += format_cmd('--remove-output' if self.remove_output else None)
|
||||
cmd_list += format_cmd('--assume-yes-for-download' if self.download_confirm else None)
|
||||
cmd_list += format_cmd('--run' if self.run_after_build else None)
|
||||
cmd_list += format_cmd('--enable-console' if self.enable_console else '--disable-console')
|
||||
|
||||
_add_cmd(cmd_list, f'--xml={self.xml_path.absolute()}' if self.save_xml else None)
|
||||
_add_cmd(cmd_list, f'--output-dir={self.output_path.absolute()}' if self.output_path else None)
|
||||
_add_cmd(cmd_list, f'--company-name={self.company_name}' if self.company_name else None)
|
||||
_add_cmd(cmd_list, f'--product-name={self.product_name}' if self.product_name else None)
|
||||
_add_cmd(cmd_list, f'--file-version={self.file_version}' if self.file_version else None)
|
||||
_add_cmd(cmd_list, f'--product-version={self.product_version}' if self.product_version else None)
|
||||
_add_cmd(cmd_list, f'--file-description={self.file_description}' if self.file_description else None)
|
||||
_add_cmd(cmd_list, f'--copyright={self.copy_right}' if self.copy_right else None)
|
||||
cmd_list += format_cmd('--xml=', str(self.xml_path.absolute()), self.save_xml)
|
||||
cmd_list += format_cmd('--report=', str(self.report_path.absolute()), self.save_report)
|
||||
cmd_list += format_cmd('--output-dir=', str(self.output_path.absolute()), self.output_path)
|
||||
cmd_list += format_cmd('--company-name=', self.company_name, self.company_name)
|
||||
cmd_list += format_cmd('--product-name=', self.product_name, self.product_name)
|
||||
cmd_list += format_cmd('--file-version=', str(self.file_version), self.file_version)
|
||||
cmd_list += format_cmd('--product-version=', str(self.product_version), self.product_version)
|
||||
cmd_list += format_cmd('--file-description=', self.file_description, self.file_description)
|
||||
cmd_list += format_cmd('--copyright=', self.copy_right, self.copy_right)
|
||||
|
||||
_add_cmd(cmd_list, f'--follow-import-to={",".join(self.follow_import)}' if self.follow_import else None)
|
||||
_add_cmd(cmd_list, f'--nofollow-import-to={",".join(self.no_follow_import)}' if self.no_follow_import else None)
|
||||
_add_cmd(cmd_list, f'--enable-plugin={",".join(self.enable_plugin)}' if self.enable_plugin else None)
|
||||
_add_cmd(cmd_list, f'--disable-plugin={",".join(self.disable_plugin)}' if self.disable_plugin else None)
|
||||
cmd_list += format_cmd('--follow-import-to=', self.follow_import, self.follow_import)
|
||||
cmd_list += format_cmd('--nofollow-import-to=', self.no_follow_import, self.no_follow_import)
|
||||
cmd_list += format_cmd('--enable-plugin=', self.enable_plugin, self.enable_plugin)
|
||||
cmd_list += format_cmd('--disable-plugin=', self.disable_plugin, self.disable_plugin)
|
||||
|
||||
if self.include_data_dir:
|
||||
cmd_list += [f"--include-data-dir={src}={dst}" for src, dst in self.include_data_dir]
|
||||
|
@ -4,7 +4,7 @@
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
from .lib import *
|
||||
from .lib import * # noqa: F403
|
||||
|
||||
from typing import TYPE_CHECKING, Dict, Tuple, Optional, List
|
||||
|
||||
|
41
mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock
generated
41
mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock
generated
@ -139,10 +139,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "1.0.9"
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
@ -348,9 +354,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3"
|
||||
version = "0.19.2"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38"
|
||||
checksum = "04e8453b658fe480c3e70c8ed4e3d3ec33eb74988bd186561b0cc66b85c3bc4b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"indoc",
|
||||
@ -365,9 +371,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-build-config"
|
||||
version = "0.19.2"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5"
|
||||
checksum = "a96fe70b176a89cff78f2fa7b3c930081e163d5379b4dcdf993e3ae29ca662e5"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"target-lexicon",
|
||||
@ -375,9 +381,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-ffi"
|
||||
version = "0.19.2"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9"
|
||||
checksum = "214929900fd25e6604661ed9cf349727c8920d47deff196c4e28165a6ef2a96b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pyo3-build-config",
|
||||
@ -385,25 +391,26 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros"
|
||||
version = "0.19.2"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1"
|
||||
checksum = "dac53072f717aa1bfa4db832b39de8c875b7c7af4f4a6fe93cdbf9264cf8383b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"pyo3-macros-backend",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros-backend"
|
||||
version = "0.19.2"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536"
|
||||
checksum = "7774b5a8282bd4f25f803b1f0d945120be959a36c72e08e7cd031c792fdfd424"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -622,9 +629,9 @@ checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
|
||||
|
||||
[[package]]
|
||||
name = "unindent"
|
||||
version = "0.1.11"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c"
|
||||
checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
|
@ -40,5 +40,5 @@ version = "0.17.2"
|
||||
features = ["simd-stable"]
|
||||
|
||||
[dependencies.pyo3]
|
||||
version = "0.19.2"
|
||||
version = "0.20.0"
|
||||
features = ["extension-module" , "macros"]
|
||||
|
@ -8,4 +8,4 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if not TYPE_CHECKING:
|
||||
from .Difficult_Rocket_rs import *
|
||||
from .Difficult_Rocket_rs import * # noqa: F403
|
||||
|
@ -655,7 +655,6 @@ pub mod ship {
|
||||
}
|
||||
Err(e) => {
|
||||
println!("{:?}", e);
|
||||
// println!("{:?}", e.provide());
|
||||
}
|
||||
}
|
||||
Ok(true)
|
||||
|
@ -1244,6 +1244,8 @@ pub mod dr {
|
||||
pub shape_data: ShapeData,
|
||||
}
|
||||
|
||||
/// 为了保证能使用到 所有类型的 碰撞体
|
||||
/// 写了这么长一个玩意
|
||||
pub enum ShapeData {
|
||||
// rapier2d_f64::geometry::ColliderBuilder
|
||||
/// 球
|
||||
@ -1301,6 +1303,7 @@ pub mod dr {
|
||||
/// 由一系列高度定义的某种东西,大概是地面之类的
|
||||
Heightfield(Vec<(Real, Real)>),
|
||||
/// 凸分解的复合形状
|
||||
/// 就是不知道能不能真用上
|
||||
Compound(Vec<(Isometry<Real>, SharedShape)>), //凸分解,好像可以略微提升复杂刚体碰撞的性能
|
||||
}
|
||||
|
||||
@ -1314,21 +1317,28 @@ pub mod dr {
|
||||
}
|
||||
|
||||
pub struct EngineData {
|
||||
/// 推力大小,if p_type==engine
|
||||
pub power: f64,
|
||||
/// 消耗速率,if p_type==engine
|
||||
pub consumption: f64,
|
||||
pub size: f64,
|
||||
/// 大小,if p_type==engine
|
||||
// pub size: f64,
|
||||
/// 转向范围,if p_type==engine
|
||||
pub turn: f64,
|
||||
/// 燃料类型,if p_type==engine
|
||||
pub fuel_type: f64,
|
||||
pub throttle_exponential: f64,
|
||||
// pub throttle_exponential: f64,
|
||||
}
|
||||
|
||||
pub trait DRPartTypeAttrTrait {
|
||||
fn name() -> String;
|
||||
// fn get_all_attr() -> HashMap<String, >;
|
||||
}
|
||||
|
||||
/// 用于描述一个零件的属性
|
||||
pub struct DRPartType<T>
|
||||
where
|
||||
T: DRPartTypeAttrTrait,
|
||||
T: DRPartTypeAttrTrait + Clone,
|
||||
{
|
||||
/// 部件 ID
|
||||
pub id: String,
|
||||
@ -1344,7 +1354,7 @@ pub mod dr {
|
||||
pub description: String,
|
||||
/// 贴图
|
||||
pub sprite: String,
|
||||
///pub r#type: SR1PartTypeEnum,
|
||||
/// pub r#type: SR1PartTypeEnum,
|
||||
/// 质量,单位500kg
|
||||
pub mass: f64,
|
||||
/// 宽度,用于判断放置时是否回合其他零件重叠
|
||||
@ -1371,4 +1381,25 @@ pub mod dr {
|
||||
// 附加属性
|
||||
pub attr: HashMap<String, T>,
|
||||
}
|
||||
|
||||
impl<T: DRPartTypeAttrTrait> DRPartType<T>
|
||||
where
|
||||
T: DRPartTypeAttrTrait + Clone,
|
||||
{
|
||||
#[inline]
|
||||
pub fn data_ref(&self, name: &str) -> Option<&T> {
|
||||
if let Some(data) = self.attr.get(name) {
|
||||
return Some(data);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn data(&self, name: &str) -> Option<T> {
|
||||
if let Some(data) = self.attr.get(name) {
|
||||
return Some(data.clone());
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
28
mods/dr_game/menu.py
Normal file
28
mods/dr_game/menu.py
Normal file
@ -0,0 +1,28 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
from pyglet.graphics import Batch, Group
|
||||
|
||||
from Difficult_Rocket.client import ClientWindow
|
||||
from Difficult_Rocket.api.screen import BaseScreen
|
||||
|
||||
# from . import DR_mod_runtime
|
||||
|
||||
|
||||
class Menu(BaseScreen):
|
||||
"""
|
||||
DR game 的 菜单
|
||||
"""
|
||||
name = 'DR_game_menu'
|
||||
|
||||
def __init__(self,
|
||||
main_window: ClientWindow):
|
||||
super().__init__(main_window)
|
||||
self.main_batch = Batch()
|
||||
self.main_group = Group(parent=main_window.main_group, order=1)
|
||||
|
||||
# 占位, 高二看看能不能咕出来点啥 (20230911)
|
||||
# 欸呀, 正好是 911 纪念日哦
|
@ -10,7 +10,7 @@ import logging
|
||||
import traceback
|
||||
|
||||
from pathlib import Path
|
||||
from typing import List, TYPE_CHECKING, Dict, Optional, Generator, Tuple
|
||||
from typing import List, Dict, Optional, Generator, Tuple
|
||||
|
||||
from pyglet.gl import gl
|
||||
from pyglet.math import Mat4
|
||||
@ -52,6 +52,11 @@ class SR1ShipRenderStatus(Options): # NOQA
|
||||
focus: bool = True
|
||||
moving: bool = False
|
||||
|
||||
# button status
|
||||
show_moving: bool = False
|
||||
show_focus: bool = False
|
||||
show_scale: bool = False
|
||||
|
||||
# debug status
|
||||
draw_d_pos: bool = False
|
||||
draw_mouse_pos: bool = False
|
||||
@ -61,6 +66,8 @@ class SR1ShipRenderStatus(Options): # NOQA
|
||||
class SR1ShipRender(BaseScreen):
|
||||
"""用于渲染 sr1 船的类"""
|
||||
|
||||
name = 'DR_game_sr1_ship_render'
|
||||
|
||||
def __init__(self,
|
||||
main_window: ClientWindow):
|
||||
super().__init__(main_window)
|
||||
@ -95,8 +102,7 @@ class SR1ShipRender(BaseScreen):
|
||||
x=main_window.width / 2, y=main_window.height / 2)
|
||||
self.render_d_label.visible = self.status.draw_d_pos
|
||||
|
||||
self.test_button = PressTextButton(x=100, y=100,
|
||||
width=150, height=30, text='test button',
|
||||
self.test_button = PressTextButton(x=100, y=100, width=150, height=30, text='test button',
|
||||
batch=self.main_batch, group=Group(5, parent=main_window.main_group))
|
||||
# self.test_button.push_handlers(main_window)
|
||||
main_window.push_handlers(self.test_button)
|
||||
@ -277,8 +283,9 @@ class SR1ShipRender(BaseScreen):
|
||||
def draw_batch(self, window: ClientWindow):
|
||||
if self.status.draw_done:
|
||||
self.render_d_label.text = f'x: {self.group_camera.view_x} y: {self.group_camera.view_y}'
|
||||
self.render_d_label.position = self.group_camera.view_x + (self.window_pointer.width / 2), self.group_camera.view_y + (
|
||||
self.window_pointer.height / 2) + 10, 0 # 0 for z
|
||||
self.render_d_label.position = self.group_camera.view_x + (
|
||||
self.window_pointer.width / 2), self.group_camera.view_y + (
|
||||
self.window_pointer.height / 2) + 10, 0 # 0 for z
|
||||
self.render_d_line.x2 = self.group_camera.view_x
|
||||
self.render_d_line.y2 = self.group_camera.view_y
|
||||
|
||||
@ -480,7 +487,6 @@ class SR1ShipRender(BaseScreen):
|
||||
self.window_pointer.view = value
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from objprint import op
|
||||
|
||||
|
@ -26,6 +26,7 @@ if __name__ == '__main__':
|
||||
compiler.python_cmd = sys.executable
|
||||
|
||||
compiler.xml_path = Path(f"./build/compile_data-{time.time()}.xml")
|
||||
compiler.report_path = Path(f"./build/compile_report-{time.time()}.xml")
|
||||
|
||||
# 检测 --github 参数
|
||||
is_github = False
|
||||
@ -43,6 +44,10 @@ if __name__ == '__main__':
|
||||
compiler.save_xml = True
|
||||
sys.argv.remove('--xml')
|
||||
|
||||
if '--report' in sys.argv:
|
||||
compiler.save_report = True
|
||||
sys.argv.remove('--report')
|
||||
|
||||
# 检测 --output xx 参数
|
||||
if '--output' in sys.argv:
|
||||
# 输入的是输出目录
|
||||
|
@ -6,7 +6,7 @@ build-backend = "pdm.pep517.api"
|
||||
|
||||
[project]
|
||||
name = "difficult-rocket"
|
||||
version = "0.8.6.0"
|
||||
version = "0.8.7.1"
|
||||
description = "A rocket game"
|
||||
authors = [
|
||||
{name = "shenjackyuanjie", email = "3695888@qq.com"}
|
||||
@ -27,7 +27,7 @@ readme = "README.md"
|
||||
build = [
|
||||
"setuptools-rust>=1.5.2,<=1.6.0",
|
||||
"wheel>=0.38.4,<1.0.0",
|
||||
"nuitka>=1.4,<1.5.0",
|
||||
"nuitka>=1.8.1,<1.9.0",
|
||||
"setuptools>=65.5.0",
|
||||
"viztracer<1.0.0,>=0.15.4",
|
||||
"vizplugins<1.0.0,>=0.1.2",
|
||||
|
@ -18,7 +18,7 @@ defusedxml >= 0.7.1
|
||||
objprint >= 0.2.2
|
||||
|
||||
# for compile
|
||||
nuitka >= 1.7.5
|
||||
nuitka >= 1.8.2
|
||||
ordered-set >= 4.1.0
|
||||
imageio >= 2.31.0; (platform_python_implementation == "PyPy" and python_version < "3.10") or platform_python_implementation == "CPython"
|
||||
wheel >= 0.40.0
|
||||
|
@ -21,7 +21,7 @@ viztracer >= 0.15.6; platform_python_implementation != "PyPy"
|
||||
vizplugins >= 0.1.3; platform_python_implementation != "PyPy"
|
||||
|
||||
# for compile
|
||||
nuitka >= 1.7.5
|
||||
nuitka >= 1.8.2
|
||||
ordered-set >= 4.1.0
|
||||
imageio >= 2.31.0; (platform_python_implementation == "PyPy" and python_version < "3.10") or platform_python_implementation == "CPython"
|
||||
wheel >= 0.40.0
|
||||
|
Loading…
Reference in New Issue
Block a user