Compare commits
82 Commits
master
...
engjam_uic
Author | SHA1 | Date |
---|---|---|
John McCardle | f2eaee95ec | |
John McCardle | 494658e5c3 | |
John McCardle | 6e820af8c4 | |
John McCardle | cf485ef327 | |
John McCardle | 3a1432212f | |
John McCardle | 38b6a3cade | |
John McCardle | 1bbb0aa5b8 | |
John McCardle | bec2b3294d | |
John McCardle | 9486104377 | |
John McCardle | 5267287b05 | |
John McCardle | b8af8bc870 | |
John McCardle | 0ef0a5d506 | |
John McCardle | a41d3d4a54 | |
John McCardle | 6d4bc2989c | |
John McCardle | d5a7cbca85 | |
John McCardle | 5d8510747c | |
John McCardle | 06052c81c9 | |
John McCardle | 6fe7b842ef | |
John McCardle | 50d926fe37 | |
John McCardle | 795701c986 | |
John McCardle | 884a49a63a | |
John McCardle | c4d5a497d4 | |
John McCardle | ba97aebf3e | |
John McCardle | ac0ec4bb71 | |
John McCardle | a455c44b34 | |
John McCardle | 96e78e6150 | |
John McCardle | 0dd86056a8 | |
John McCardle | 26cb410b8e | |
John McCardle | d09fc87499 | |
John McCardle | b022dfa6e8 | |
John McCardle | 232ce34d54 | |
John McCardle | c1c17bab69 | |
John McCardle | e85861cbb2 | |
John McCardle | d6446e18ea | |
John McCardle | d3826804a0 | |
John McCardle | b4c49c4619 | |
John McCardle | 76ac236be3 | |
John McCardle | 97793fb26b | |
John McCardle | b3134f0890 | |
John McCardle | dfcc39dd43 | |
John McCardle | 29ac89b489 | |
John McCardle | b4daac6e0c | |
John McCardle | 3fd60d76ea | |
John McCardle | 99fa92f8ba | |
John McCardle | 9441f357df | |
John McCardle | 34feb226e4 | |
John McCardle | 486a1cd17c | |
John McCardle | 8d9148b88d | |
John McCardle | f1798189f0 | |
John McCardle | 5b168737ce | |
John McCardle | 6875cb5fe1 | |
John McCardle | 87483cc8ad | |
John McCardle | 620def19f1 | |
John McCardle | c9b97b9b35 | |
John McCardle | 8e59152a8f | |
John McCardle | fedfcd46a3 | |
John McCardle | c551c721ce | |
John McCardle | d74635ee4e | |
John McCardle | 47e823d5b9 | |
John McCardle | 6dbf8a5119 | |
John McCardle | a53ae29467 | |
John McCardle | 257aa3c3d2 | |
John McCardle | a4b6c2c428 | |
John McCardle | b0ef1d2303 | |
John McCardle | b3f946ecb2 | |
John McCardle | 6a4150ec05 | |
John McCardle | e295bfb742 | |
John McCardle | 2ec97dfb1c | |
John McCardle | f89896176c | |
John McCardle | de753713d5 | |
John McCardle | c8124e84dc | |
John McCardle | a1e9129923 | |
John McCardle | f23dfbe4ba | |
John McCardle | 1e9fd77a13 | |
John McCardle | 2c1946c29b | |
John McCardle | 6d05f8bc63 | |
John McCardle | a4d0efe334 | |
John McCardle | 6a47bc1e28 | |
John McCardle | 6a2c3c6c36 | |
John McCardle | a6f59085eb | |
John McCardle | d2499a67f8 | |
John McCardle | 1784489dfb |
|
@ -3,3 +3,7 @@
|
||||||
bin
|
bin
|
||||||
.msvc-intermediate/
|
.msvc-intermediate/
|
||||||
*.bak*
|
*.bak*
|
||||||
|
PCbuild
|
||||||
|
.vs
|
||||||
|
obj
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
```
|
||||||
|
* python API overhaul
|
||||||
|
* At the very least, a function to turn a color tuple to sf::Color would be good.
|
||||||
|
All the sf::Color objects going into / out of Python need to support transparency (4th value of Alpha) - Python would tolerate it, C++ needs to allow it (parse "iii|i", default alpha of 0 for fully nontransparent)
|
||||||
|
* The entire method of reading properties to re-ingest Grids/Menus is stupid.
|
||||||
|
C++ classes should be exposed more directly, or have clean methods to accept the changes from Python code.
|
||||||
|
* return actual exceptions instead of std::cout and NULL
|
||||||
|
* smart pointers (`std::shared_ptr<PyObject>`) to C++-ify Python object passing? Can this be made to work with reference counting?
|
||||||
|
* Raise Exceptions - see *janknote* in the Animation API method
|
||||||
|
* C++ hygene: Make data members private, call getter/setter methods
|
||||||
|
* std::shared_ptr, not bare pointers. The grid/entity/component connections suffer from this
|
||||||
|
* SFML: "widget" hierarchy. Keep all sizes/positions in the RectangleShape objects. Make Grid and UIMenu subclasses of the same base, and keep a single map of drawable widgets.
|
||||||
|
* UIMenu should become a "frame", and draw any objects of the "Widget" class relatively to its own positions
|
||||||
|
* "Widget" as an abstract class should set the template for going to/from Python; don't copy to and from Python, the C++ object *is* the Python object.
|
||||||
|
* ==Buttons don't know their parent...?== So there's arithmetic happening in the event loop to determine it's actual positions. Fix this with the widgets-on-widgets system (so we can go deeper, and just ask the widgets if they or their children were clicked)
|
||||||
|
* Keep aspect ratio correct (and hopefully unbork any mouse issues) when maximizing / full screening the game
|
||||||
|
```
|
||||||
|
|
||||||
|
# r/RoguelikeDev Does the Complete Roguelike Tutorial - July 2023
|
||||||
|
|
||||||
|
## Planning
|
||||||
|
|
||||||
|
Event ends roughly 26 August (last post will be 22 August)
|
||||||
|
|
||||||
|
* Add and remove keystroke registration from Python scripts
|
||||||
|
* Error checking: raise Python exceptions instead of null reference segfault in C++
|
||||||
|
* Proper exception handling: figure out the "any code at REPL shows the unhandled exception" bug thingy
|
||||||
|
* Extra clarity: display more status info about what Python stuff is being done
|
||||||
|
- load all files in directory at first
|
||||||
|
- list modules / classes found
|
||||||
|
- list Scenes that were found
|
||||||
|
- Read all Python modules, then call objects & methods at C++-managed events (Engine provided decorators, perhaps??)
|
||||||
|
* PythonScene version of MenuScene
|
||||||
|
- instantiate PythonScenes
|
||||||
|
* Switch Scenes from Python (edge of board / stairs / teleportation feature)
|
||||||
|
* Update the visible map from Python (fix "map blank until you move" bug)
|
||||||
|
- update "camera state" and "Recenter camera" buttons' API info as well without a whole Turn
|
||||||
|
* C++/TCOD Entity pathfinding without calling Python every Turn
|
||||||
|
* Replace jank .py files that define engine-required objects with C++ definitions inside of `mcrfpy` module
|
||||||
|
|
||||||
|
This actually a pretty big list, but there's about 7 weeks left, so it's just over one item per week.
|
||||||
|
|
||||||
|
I have no bad feelings if these items leak over to EngJam or beyond.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Notes 12 July
|
||||||
|
|
||||||
|
Some changes to make in McRFPy_API.cpp:
|
||||||
|
* create a parallel to _registerPyAction which will register a keystroke to a Python label in the current scene.
|
||||||
|
|
||||||
|
## Notes 13 July
|
||||||
|
|
||||||
|
- working on API endpoint `_registerInputAction`.
|
||||||
|
|
||||||
|
it will add "_py" as a suffix to the action string and register it along with other scene actions.
|
||||||
|
|
||||||
|
- Adding public Scene methods. These are on the base class with default of return `false`.
|
||||||
|
|
||||||
|
`bool Scene::registerActionInjected(int code, std::string name)` and `unregisterActionInjected`
|
||||||
|
|
||||||
|
the PythonScene (and other scenes that support injected user input) can override this method, check existing registrations, and return `true` when succeeding.
|
||||||
|
|
||||||
|
- then remove `McRFPy_API::player_input`
|
||||||
|
|
||||||
|
This behavior can be more flexibly implemented in Python using keyboard registration. There's some deduplication as well, since I have a Python implementation of collision detection anyway (for items, doors, and NPCs).
|
||||||
|
|
||||||
|
Also, upgraded to C++20 (g++ `c++2a`), mostly because I want to use map::contains.
|
||||||
|
|
||||||
|
More ideas:
|
||||||
|
|
||||||
|
* Need to make "pan" and "zoom" optional on each grid (for minimap type use cases)
|
||||||
|
* clicks are handled by C++ and only used on buttons. Grids could have a Python click function (with pixel & grid coords available)
|
||||||
|
* pixel-on-menu Python click function should be possible too
|
||||||
|
* Need to call a Python update function when C++ events cause camera following to change: UI is only updating after player input
|
||||||
|
|
||||||
|
|
||||||
|
Continue with:
|
||||||
|
|
||||||
|
* implement checks in PythonScene::registerActionInjected - Save injected actions, don't let regular actions be overwritten, return success
|
||||||
|
* Remove PythonScene key definitions and McRFPy_API::player_input
|
||||||
|
* re-implement walking via keyboard input in Python
|
||||||
|
* Find a good spot for camera following to update Python immediately
|
||||||
|
* Find a good spot for grid updates to redraw TCOD line of sight immediately
|
||||||
|
|
||||||
|
## Notes 16 July
|
||||||
|
|
||||||
|
Main problem that came up today: all Python code is executed at the moment the GameEngine instantiates the PythonScene, which is actually when the game starts up. The active scene at that point is the MenuScene, so the Python code registers events against that scene (which rejects injected event binding and has no API functionality).
|
||||||
|
|
||||||
|
Workaround: There's a clickable button that performs the input registration. This is good for working out the behavior, but doesn't really allow Python scripts to properly control and set up their own environment.
|
||||||
|
|
||||||
|
The module name is passed to the PythonScene constructor, and the `start()` method is called to set up class objects. Can I add more methods that are called on this module to swap scenes?
|
||||||
|
|
||||||
|
## Notes 17 July
|
||||||
|
|
||||||
|
The player entity is moving around via Python now!
|
||||||
|
|
||||||
|
Unfortunately, the "actiononce" macro I use in C++ is not the behavior passed on to the Python key events. Key release events are being passed to Python just the way that keypresses are.
|
||||||
|
|
||||||
|
I'll need to expose more of the input event properties down to Python. I also don't like how keycodes are being passed from python to C++, which currently limits user input to key strokes. Mouse buttons and mouse wheel should be possible too (just as they are under the SFML event binding).
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
# About McRogueFace Engine
|
||||||
|
|
||||||
|
This software is distributed on Github and other git repos for review & discussion purposes. This engine was made in preparation and during the 2023 7 Day Roguelike game jam. It's not production ready. I don't want to support this buggy version of the software - do not create derivative works, modify, or redistribute this git repo. Not that you'd actually want to: take a close look at the code and you'll quickly find reasons not to depend on the codebase in its present state.
|
||||||
|
|
||||||
|
I expect to release the engine under BSD, MIT, or similar license after overhauling my technical debt incurred during the game jam. see JANKFILE.md for outstanding issues.
|
||||||
|
|
||||||
# Software Licenses
|
# Software Licenses
|
||||||
|
|
||||||
## Dependencies included in this repo
|
## Dependencies included in this repo
|
||||||
|
|
15
README.md
|
@ -7,7 +7,7 @@ An experimental prototype game engine built for my own use in 7DRL 2023.
|
||||||
## Tenets:
|
## Tenets:
|
||||||
|
|
||||||
* C++ first, Python close behind.
|
* C++ first, Python close behind.
|
||||||
* Entity-Component system based on David Churchill's Memorial University COP4300 course lectures available on Youtube.
|
* Entity-Component system based on David Churchill's Memorial University COMP4300 course lectures available on Youtube.
|
||||||
* Graphics, particles and shaders provided by SFML.
|
* Graphics, particles and shaders provided by SFML.
|
||||||
* Pathfinding, noise generation, and other Roguelike goodness provided by TCOD.
|
* Pathfinding, noise generation, and other Roguelike goodness provided by TCOD.
|
||||||
|
|
||||||
|
@ -18,12 +18,13 @@ I did the r/RoguelikeDev TCOD tutorial in Python. I loved it, but I did not want
|
||||||
## To-do
|
## To-do
|
||||||
|
|
||||||
* ✅ Initial Commit
|
* ✅ Initial Commit
|
||||||
* ❌ Integrate scene, action, entity, component system from COMP4300 engine
|
* ✅ Integrate scene, action, entity, component system from COMP4300 engine
|
||||||
* ❌ Windows / Visual Studio project
|
* ✅ Windows / Visual Studio project
|
||||||
* ❌ Draw Sprites
|
* ✅ Draw Sprites
|
||||||
* ❌ Play Sounds
|
* ✅ Play Sounds
|
||||||
* ❌ Draw UI, spawn entity from Python code
|
* ✅ Draw UI, spawn entity from Python code
|
||||||
* ❌ Python AI for entities (NPCs on set paths, enemies towards player)
|
* ❌ Python AI for entities (NPCs on set paths, enemies towards player)
|
||||||
* ❌ Walking / Collision; "Boards" (stairs / doors / walk off edge of screen)
|
* ✅ Walking / Collision
|
||||||
|
* ❌ "Boards" (stairs / doors / walk off edge of screen)
|
||||||
* ❌ Cutscenes - interrupt normal controls, text scroll, character portraits
|
* ❌ Cutscenes - interrupt normal controls, text scroll, character portraits
|
||||||
* ❌ Mouse integration - tooltips, zoom, click to select targets, cursors
|
* ❌ Mouse integration - tooltips, zoom, click to select targets, cursors
|
||||||
|
|
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 202 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 1.4 KiB |
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#rm -R bin/linux
|
#rm -R bin/linux
|
||||||
mkdir -p bin/linux/lib
|
mkdir -p bin/linux/lib
|
||||||
|
mkdir -p obj
|
||||||
|
rm obj/*
|
||||||
|
|
||||||
# copy shared objects, squish "linux" subdirectory in bin/linux/lib
|
# copy shared objects, squish "linux" subdirectory in bin/linux/lib
|
||||||
#cp -R lib/linux/* bin/linux/lib
|
#cp -R lib/linux/* bin/linux/lib
|
||||||
|
@ -15,13 +17,49 @@ cp -R src/scripts bin/linux/scripts
|
||||||
# work from output directory and change every g++ path to relative D:<
|
# work from output directory and change every g++ path to relative D:<
|
||||||
cd bin/linux
|
cd bin/linux
|
||||||
|
|
||||||
|
# prepare object files of engine classes
|
||||||
|
abort_compile()
|
||||||
|
{
|
||||||
|
echo "Compilation failed on $fn.cpp"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Precompile engine classes. Get errors in their file, not where they're included
|
||||||
|
for fn in $(ls ../../src/*.cpp -1 | cut -d/ -f4 | cut -d. -f1)
|
||||||
|
do
|
||||||
|
# Skip combined_poc.cpp, it has a duplicate main
|
||||||
|
if [ "$fn" = "combined_poc" ]; then continue; fi
|
||||||
|
|
||||||
|
echo "Compile $fn.cpp"
|
||||||
g++ \
|
g++ \
|
||||||
--std=c++17 \
|
|
||||||
-I../../deps_linux \
|
-I../../deps_linux \
|
||||||
-I../../deps_linux/Python-3.11.1 \
|
-I../../deps_linux/Python-3.11.1 \
|
||||||
-I../../platform/linux \
|
-I../../platform/linux \
|
||||||
../../src/combined_poc.cpp \
|
--std=c++2a \
|
||||||
-o poc \
|
-c ../../src/$fn.cpp \
|
||||||
|
-o ../../obj/$fn.o \
|
||||||
|
-lm \
|
||||||
|
-ldl \
|
||||||
|
-lutil \
|
||||||
|
-lpthread \
|
||||||
|
-lpython3.11 \
|
||||||
|
-lsfml-graphics \
|
||||||
|
-lsfml-window \
|
||||||
|
-lsfml-system \
|
||||||
|
-lsfml-audio \
|
||||||
|
-ltcod \
|
||||||
|
|| abort_compile $fn
|
||||||
|
done
|
||||||
|
|
||||||
|
# Final executable
|
||||||
|
# --std= : c++2a vs c++17
|
||||||
|
g++ \
|
||||||
|
--std=c++2a \
|
||||||
|
-I../../deps_linux \
|
||||||
|
-I../../deps_linux/Python-3.11.1 \
|
||||||
|
-I../../platform/linux \
|
||||||
|
../../obj/*.o \
|
||||||
|
-o mcrogueface \
|
||||||
-Wl,-rpath lib \
|
-Wl,-rpath lib \
|
||||||
-L../../deps_linux \
|
-L../../deps_linux \
|
||||||
-lm \
|
-lm \
|
||||||
|
@ -32,5 +70,6 @@ g++ \
|
||||||
-lsfml-graphics \
|
-lsfml-graphics \
|
||||||
-lsfml-window \
|
-lsfml-window \
|
||||||
-lsfml-system \
|
-lsfml-system \
|
||||||
-ltcod
|
-lsfml-audio \
|
||||||
|
-ltcod \
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
cp src/scripts/*.py bin/linux/scripts/
|
||||||
|
cd bin/linux
|
||||||
|
gdb ./mcrogueface
|
|
@ -0,0 +1,710 @@
|
||||||
|
#ifndef Py_CONFIG_H
|
||||||
|
#define Py_CONFIG_H
|
||||||
|
|
||||||
|
/* pyconfig.h. NOT Generated automatically by configure.
|
||||||
|
|
||||||
|
This is a manually maintained version used for the Watcom,
|
||||||
|
Borland and Microsoft Visual C++ compilers. It is a
|
||||||
|
standard part of the Python distribution.
|
||||||
|
|
||||||
|
WINDOWS DEFINES:
|
||||||
|
The code specific to Windows should be wrapped around one of
|
||||||
|
the following #defines
|
||||||
|
|
||||||
|
MS_WIN64 - Code specific to the MS Win64 API
|
||||||
|
MS_WIN32 - Code specific to the MS Win32 (and Win64) API (obsolete, this covers all supported APIs)
|
||||||
|
MS_WINDOWS - Code specific to Windows, but all versions.
|
||||||
|
Py_ENABLE_SHARED - Code if the Python core is built as a DLL.
|
||||||
|
|
||||||
|
Also note that neither "_M_IX86" or "_MSC_VER" should be used for
|
||||||
|
any purpose other than "Windows Intel x86 specific" and "Microsoft
|
||||||
|
compiler specific". Therefore, these should be very rare.
|
||||||
|
|
||||||
|
|
||||||
|
NOTE: The following symbols are deprecated:
|
||||||
|
NT, USE_DL_EXPORT, USE_DL_IMPORT, DL_EXPORT, DL_IMPORT
|
||||||
|
MS_CORE_DLL.
|
||||||
|
|
||||||
|
WIN32 is still required for the locale module.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */
|
||||||
|
#ifdef USE_DL_EXPORT
|
||||||
|
# define Py_BUILD_CORE
|
||||||
|
#endif /* USE_DL_EXPORT */
|
||||||
|
|
||||||
|
/* Visual Studio 2005 introduces deprecation warnings for
|
||||||
|
"insecure" and POSIX functions. The insecure functions should
|
||||||
|
be replaced by *_s versions (according to Microsoft); the
|
||||||
|
POSIX functions by _* versions (which, according to Microsoft,
|
||||||
|
would be ISO C conforming). Neither renaming is feasible, so
|
||||||
|
we just silence the warnings. */
|
||||||
|
|
||||||
|
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||||
|
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||||
|
#endif
|
||||||
|
#ifndef _CRT_NONSTDC_NO_DEPRECATE
|
||||||
|
#define _CRT_NONSTDC_NO_DEPRECATE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HAVE_IO_H
|
||||||
|
#define HAVE_SYS_UTIME_H
|
||||||
|
#define HAVE_TEMPNAM
|
||||||
|
#define HAVE_TMPFILE
|
||||||
|
#define HAVE_TMPNAM
|
||||||
|
#define HAVE_CLOCK
|
||||||
|
#define HAVE_STRERROR
|
||||||
|
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
|
#define HAVE_STRFTIME
|
||||||
|
#define DONT_HAVE_SIG_ALARM
|
||||||
|
#define DONT_HAVE_SIG_PAUSE
|
||||||
|
#define LONG_BIT 32
|
||||||
|
#define WORD_BIT 32
|
||||||
|
|
||||||
|
#define MS_WIN32 /* only support win32 and greater. */
|
||||||
|
#define MS_WINDOWS
|
||||||
|
#define NT_THREADS
|
||||||
|
#define WITH_THREAD
|
||||||
|
#ifndef NETSCAPE_PI
|
||||||
|
#define USE_SOCKET
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Compiler specific defines */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------*/
|
||||||
|
/* Microsoft C defines _MSC_VER */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
/* We want COMPILER to expand to a string containing _MSC_VER's *value*.
|
||||||
|
* This is horridly tricky, because the stringization operator only works
|
||||||
|
* on macro arguments, and doesn't evaluate macros passed *as* arguments.
|
||||||
|
* Attempts simpler than the following appear doomed to produce "_MSC_VER"
|
||||||
|
* literally in the string.
|
||||||
|
*/
|
||||||
|
#define _Py_PASTE_VERSION(SUFFIX) \
|
||||||
|
("[MSC v." _Py_STRINGIZE(_MSC_VER) " " SUFFIX "]")
|
||||||
|
/* e.g., this produces, after compile-time string catenation,
|
||||||
|
* ("[MSC v.1200 32 bit (Intel)]")
|
||||||
|
*
|
||||||
|
* _Py_STRINGIZE(_MSC_VER) expands to
|
||||||
|
* _Py_STRINGIZE1((_MSC_VER)) expands to
|
||||||
|
* _Py_STRINGIZE2(_MSC_VER) but as this call is the result of token-pasting
|
||||||
|
* it's scanned again for macros and so further expands to (under MSVC 6)
|
||||||
|
* _Py_STRINGIZE2(1200) which then expands to
|
||||||
|
* "1200"
|
||||||
|
*/
|
||||||
|
#define _Py_STRINGIZE(X) _Py_STRINGIZE1((X))
|
||||||
|
#define _Py_STRINGIZE1(X) _Py_STRINGIZE2 ## X
|
||||||
|
#define _Py_STRINGIZE2(X) #X
|
||||||
|
|
||||||
|
/* MSVC defines _WINxx to differentiate the windows platform types
|
||||||
|
|
||||||
|
Note that for compatibility reasons _WIN32 is defined on Win32
|
||||||
|
*and* on Win64. For the same reasons, in Python, MS_WIN32 is
|
||||||
|
defined on Win32 *and* Win64. Win32 only code must therefore be
|
||||||
|
guarded as follows:
|
||||||
|
#if defined(MS_WIN32) && !defined(MS_WIN64)
|
||||||
|
*/
|
||||||
|
#ifdef _WIN64
|
||||||
|
#define MS_WIN64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* set the COMPILER and support tier
|
||||||
|
*
|
||||||
|
* win_amd64 MSVC (x86_64-pc-windows-msvc): 1
|
||||||
|
* win32 MSVC (i686-pc-windows-msvc): 1
|
||||||
|
* win_arm64 MSVC (aarch64-pc-windows-msvc): 3
|
||||||
|
* other archs and ICC: 0
|
||||||
|
*/
|
||||||
|
#ifdef MS_WIN64
|
||||||
|
#if defined(_M_X64) || defined(_M_AMD64)
|
||||||
|
#if defined(__INTEL_COMPILER)
|
||||||
|
#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]")
|
||||||
|
#define PY_SUPPORT_TIER 0
|
||||||
|
#else
|
||||||
|
#define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)")
|
||||||
|
#define PY_SUPPORT_TIER 1
|
||||||
|
#endif /* __INTEL_COMPILER */
|
||||||
|
#define PYD_PLATFORM_TAG "win_amd64"
|
||||||
|
#elif defined(_M_ARM64)
|
||||||
|
#define COMPILER _Py_PASTE_VERSION("64 bit (ARM64)")
|
||||||
|
#define PY_SUPPORT_TIER 3
|
||||||
|
#define PYD_PLATFORM_TAG "win_arm64"
|
||||||
|
#else
|
||||||
|
#define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)")
|
||||||
|
#define PY_SUPPORT_TIER 0
|
||||||
|
#endif
|
||||||
|
#endif /* MS_WIN64 */
|
||||||
|
|
||||||
|
/* set the version macros for the windows headers */
|
||||||
|
/* Python 3.9+ requires Windows 8 or greater */
|
||||||
|
#define Py_WINVER 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||||
|
#define Py_NTDDI NTDDI_WIN8
|
||||||
|
|
||||||
|
/* We only set these values when building Python - we don't want to force
|
||||||
|
these values on extensions, as that will affect the prototypes and
|
||||||
|
structures exposed in the Windows headers. Even when building Python, we
|
||||||
|
allow a single source file to override this - they may need access to
|
||||||
|
structures etc so it can optionally use new Windows features if it
|
||||||
|
determines at runtime they are available.
|
||||||
|
*/
|
||||||
|
#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) || defined(Py_BUILD_CORE_MODULE)
|
||||||
|
#ifndef NTDDI_VERSION
|
||||||
|
#define NTDDI_VERSION Py_NTDDI
|
||||||
|
#endif
|
||||||
|
#ifndef WINVER
|
||||||
|
#define WINVER Py_WINVER
|
||||||
|
#endif
|
||||||
|
#ifndef _WIN32_WINNT
|
||||||
|
#define _WIN32_WINNT Py_WINVER
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* _W64 is not defined for VC6 or eVC4 */
|
||||||
|
#ifndef _W64
|
||||||
|
#define _W64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define like size_t, omitting the "unsigned" */
|
||||||
|
#ifdef MS_WIN64
|
||||||
|
typedef __int64 Py_ssize_t;
|
||||||
|
# define PY_SSIZE_T_MAX LLONG_MAX
|
||||||
|
#else
|
||||||
|
typedef _W64 int Py_ssize_t;
|
||||||
|
# define PY_SSIZE_T_MAX INT_MAX
|
||||||
|
#endif
|
||||||
|
#define HAVE_PY_SSIZE_T 1
|
||||||
|
|
||||||
|
#if defined(MS_WIN32) && !defined(MS_WIN64)
|
||||||
|
#if defined(_M_IX86)
|
||||||
|
#if defined(__INTEL_COMPILER)
|
||||||
|
#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]")
|
||||||
|
#define PY_SUPPORT_TIER 0
|
||||||
|
#else
|
||||||
|
#define COMPILER _Py_PASTE_VERSION("32 bit (Intel)")
|
||||||
|
#define PY_SUPPORT_TIER 1
|
||||||
|
#endif /* __INTEL_COMPILER */
|
||||||
|
#define PYD_PLATFORM_TAG "win32"
|
||||||
|
#elif defined(_M_ARM)
|
||||||
|
#define COMPILER _Py_PASTE_VERSION("32 bit (ARM)")
|
||||||
|
#define PYD_PLATFORM_TAG "win_arm32"
|
||||||
|
#define PY_SUPPORT_TIER 0
|
||||||
|
#else
|
||||||
|
#define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)")
|
||||||
|
#define PY_SUPPORT_TIER 0
|
||||||
|
#endif
|
||||||
|
#endif /* MS_WIN32 && !MS_WIN64 */
|
||||||
|
|
||||||
|
typedef int pid_t;
|
||||||
|
|
||||||
|
/* define some ANSI types that are not defined in earlier Win headers */
|
||||||
|
#if _MSC_VER >= 1200
|
||||||
|
/* This file only exists in VC 6.0 or higher */
|
||||||
|
#include <basetsd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------*/
|
||||||
|
/* egcs/gnu-win32 defines __GNUC__ and _WIN32 */
|
||||||
|
#if defined(__GNUC__) && defined(_WIN32)
|
||||||
|
/* XXX These defines are likely incomplete, but should be easy to fix.
|
||||||
|
They should be complete enough to build extension modules. */
|
||||||
|
/* Suggested by Rene Liebscher <R.Liebscher@gmx.de> to avoid a GCC 2.91.*
|
||||||
|
bug that requires structure imports. More recent versions of the
|
||||||
|
compiler don't exhibit this bug.
|
||||||
|
*/
|
||||||
|
#if (__GNUC__==2) && (__GNUC_MINOR__<=91)
|
||||||
|
#warning "Please use an up-to-date version of gcc! (>2.91 recommended)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define COMPILER "[gcc]"
|
||||||
|
#define PY_LONG_LONG long long
|
||||||
|
#define PY_LLONG_MIN LLONG_MIN
|
||||||
|
#define PY_LLONG_MAX LLONG_MAX
|
||||||
|
#define PY_ULLONG_MAX ULLONG_MAX
|
||||||
|
#endif /* GNUC */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------*/
|
||||||
|
/* lcc-win32 defines __LCC__ */
|
||||||
|
#if defined(__LCC__)
|
||||||
|
/* XXX These defines are likely incomplete, but should be easy to fix.
|
||||||
|
They should be complete enough to build extension modules. */
|
||||||
|
|
||||||
|
#define COMPILER "[lcc-win32]"
|
||||||
|
typedef int pid_t;
|
||||||
|
/* __declspec() is supported here too - do nothing to get the defaults */
|
||||||
|
|
||||||
|
#endif /* LCC */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------*/
|
||||||
|
/* End of compilers - finish up */
|
||||||
|
|
||||||
|
#ifndef NO_STDIO_H
|
||||||
|
# include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 64 bit ints are usually spelt __int64 unless compiler has overridden */
|
||||||
|
#ifndef PY_LONG_LONG
|
||||||
|
# define PY_LONG_LONG __int64
|
||||||
|
# define PY_LLONG_MAX _I64_MAX
|
||||||
|
# define PY_LLONG_MIN _I64_MIN
|
||||||
|
# define PY_ULLONG_MAX _UI64_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For Windows the Python core is in a DLL by default. Test
|
||||||
|
Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
|
||||||
|
#if !defined(MS_NO_COREDLL) && !defined(Py_NO_ENABLE_SHARED)
|
||||||
|
# define Py_ENABLE_SHARED 1 /* standard symbol for shared library */
|
||||||
|
# define MS_COREDLL /* deprecated old symbol */
|
||||||
|
#endif /* !MS_NO_COREDLL && ... */
|
||||||
|
|
||||||
|
/* All windows compilers that use this header support __declspec */
|
||||||
|
#define HAVE_DECLSPEC_DLL
|
||||||
|
|
||||||
|
/* For an MSVC DLL, we can nominate the .lib files used by extensions */
|
||||||
|
#ifdef MS_COREDLL
|
||||||
|
# if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN)
|
||||||
|
/* not building the core - must be an ext */
|
||||||
|
# if defined(_MSC_VER)
|
||||||
|
/* So MSVC users need not specify the .lib
|
||||||
|
file in their Makefile (other compilers are
|
||||||
|
generally taken care of by distutils.) */
|
||||||
|
# if defined(_DEBUG)
|
||||||
|
# pragma comment(lib,"python311_d.lib")
|
||||||
|
# elif defined(Py_LIMITED_API)
|
||||||
|
# pragma comment(lib,"python3.lib")
|
||||||
|
# else
|
||||||
|
# pragma comment(lib,"python311.lib")
|
||||||
|
# endif /* _DEBUG */
|
||||||
|
# endif /* _MSC_VER */
|
||||||
|
# endif /* Py_BUILD_CORE */
|
||||||
|
#endif /* MS_COREDLL */
|
||||||
|
|
||||||
|
#if defined(MS_WIN64)
|
||||||
|
/* maintain "win32" sys.platform for backward compatibility of Python code,
|
||||||
|
the Win64 API should be close enough to the Win32 API to make this
|
||||||
|
preferable */
|
||||||
|
# define PLATFORM "win32"
|
||||||
|
# define SIZEOF_VOID_P 8
|
||||||
|
# define SIZEOF_TIME_T 8
|
||||||
|
# define SIZEOF_OFF_T 4
|
||||||
|
# define SIZEOF_FPOS_T 8
|
||||||
|
# define SIZEOF_HKEY 8
|
||||||
|
# define SIZEOF_SIZE_T 8
|
||||||
|
# define ALIGNOF_SIZE_T 8
|
||||||
|
/* configure.ac defines HAVE_LARGEFILE_SUPPORT iff
|
||||||
|
sizeof(off_t) > sizeof(long), and sizeof(long long) >= sizeof(off_t).
|
||||||
|
On Win64 the second condition is not true, but if fpos_t replaces off_t
|
||||||
|
then this is true. The uses of HAVE_LARGEFILE_SUPPORT imply that Win64
|
||||||
|
should define this. */
|
||||||
|
# define HAVE_LARGEFILE_SUPPORT
|
||||||
|
#elif defined(MS_WIN32)
|
||||||
|
# define PLATFORM "win32"
|
||||||
|
# define HAVE_LARGEFILE_SUPPORT
|
||||||
|
# define SIZEOF_VOID_P 4
|
||||||
|
# define SIZEOF_OFF_T 4
|
||||||
|
# define SIZEOF_FPOS_T 8
|
||||||
|
# define SIZEOF_HKEY 4
|
||||||
|
# define SIZEOF_SIZE_T 4
|
||||||
|
# define ALIGNOF_SIZE_T 4
|
||||||
|
/* MS VS2005 changes time_t to a 64-bit type on all platforms */
|
||||||
|
# if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||||
|
# define SIZEOF_TIME_T 8
|
||||||
|
# else
|
||||||
|
# define SIZEOF_TIME_T 4
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
# define Py_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MS_WIN32
|
||||||
|
|
||||||
|
#define SIZEOF_SHORT 2
|
||||||
|
#define SIZEOF_INT 4
|
||||||
|
#define SIZEOF_LONG 4
|
||||||
|
#define ALIGNOF_LONG 4
|
||||||
|
#define SIZEOF_LONG_LONG 8
|
||||||
|
#define SIZEOF_DOUBLE 8
|
||||||
|
#define SIZEOF_FLOAT 4
|
||||||
|
|
||||||
|
/* VC 7.1 has them and VC 6.0 does not. VC 6.0 has a version number of 1200.
|
||||||
|
Microsoft eMbedded Visual C++ 4.0 has a version number of 1201 and doesn't
|
||||||
|
define these.
|
||||||
|
If some compiler does not provide them, modify the #if appropriately. */
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#if _MSC_VER > 1300
|
||||||
|
#define HAVE_UINTPTR_T 1
|
||||||
|
#define HAVE_INTPTR_T 1
|
||||||
|
#else
|
||||||
|
/* VC6, VS 2002 and eVC4 don't support the C99 LL suffix for 64-bit integer literals */
|
||||||
|
#define Py_LL(x) x##I64
|
||||||
|
#endif /* _MSC_VER > 1300 */
|
||||||
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* define signed and unsigned exact-width 32-bit and 64-bit types, used in the
|
||||||
|
implementation of Python integers. */
|
||||||
|
#define PY_UINT32_T uint32_t
|
||||||
|
#define PY_UINT64_T uint64_t
|
||||||
|
#define PY_INT32_T int32_t
|
||||||
|
#define PY_INT64_T int64_t
|
||||||
|
|
||||||
|
/* Fairly standard from here! */
|
||||||
|
|
||||||
|
/* Define if on AIX 3.
|
||||||
|
System headers sometimes define this.
|
||||||
|
We just want to avoid a redefinition error message. */
|
||||||
|
#ifndef _ALL_SOURCE
|
||||||
|
/* #undef _ALL_SOURCE */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define to empty if the keyword does not work. */
|
||||||
|
/* #define const */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <conio.h> header file. */
|
||||||
|
#define HAVE_CONIO_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <direct.h> header file. */
|
||||||
|
#define HAVE_DIRECT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
|
||||||
|
*/
|
||||||
|
#define HAVE_DECL_TZNAME 1
|
||||||
|
|
||||||
|
/* Define if you have dirent.h. */
|
||||||
|
/* #define DIRENT 1 */
|
||||||
|
|
||||||
|
/* Define to the type of elements in the array set by `getgroups'.
|
||||||
|
Usually this is either `int' or `gid_t'. */
|
||||||
|
/* #undef GETGROUPS_T */
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
/* #undef gid_t */
|
||||||
|
|
||||||
|
/* Define if your struct tm has tm_zone. */
|
||||||
|
/* #undef HAVE_TM_ZONE */
|
||||||
|
|
||||||
|
/* Define if you don't have tm_zone but do have the external array
|
||||||
|
tzname. */
|
||||||
|
#define HAVE_TZNAME
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
/* #undef mode_t */
|
||||||
|
|
||||||
|
/* Define if you don't have dirent.h, but have ndir.h. */
|
||||||
|
/* #undef NDIR */
|
||||||
|
|
||||||
|
/* Define to `long' if <sys/types.h> doesn't define. */
|
||||||
|
/* #undef off_t */
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
/* #undef pid_t */
|
||||||
|
|
||||||
|
/* Define if the system does not provide POSIX.1 features except
|
||||||
|
with this defined. */
|
||||||
|
/* #undef _POSIX_1_SOURCE */
|
||||||
|
|
||||||
|
/* Define if you need to in order for stat and other things to work. */
|
||||||
|
/* #undef _POSIX_SOURCE */
|
||||||
|
|
||||||
|
/* Define as the return type of signal handlers (int or void). */
|
||||||
|
#define RETSIGTYPE void
|
||||||
|
|
||||||
|
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||||
|
/* #undef size_t */
|
||||||
|
|
||||||
|
/* Define if you have the ANSI C header files. */
|
||||||
|
#define STDC_HEADERS 1
|
||||||
|
|
||||||
|
/* Define if you don't have dirent.h, but have sys/dir.h. */
|
||||||
|
/* #undef SYSDIR */
|
||||||
|
|
||||||
|
/* Define if you don't have dirent.h, but have sys/ndir.h. */
|
||||||
|
/* #undef SYSNDIR */
|
||||||
|
|
||||||
|
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||||
|
/* #undef TIME_WITH_SYS_TIME */
|
||||||
|
|
||||||
|
/* Define if your <sys/time.h> declares struct tm. */
|
||||||
|
/* #define TM_IN_SYS_TIME 1 */
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
/* #undef uid_t */
|
||||||
|
|
||||||
|
/* Define if the closedir function returns void instead of int. */
|
||||||
|
/* #undef VOID_CLOSEDIR */
|
||||||
|
|
||||||
|
/* Define if getpgrp() must be called as getpgrp(0)
|
||||||
|
and (consequently) setpgrp() as setpgrp(0, 0). */
|
||||||
|
/* #undef GETPGRP_HAVE_ARGS */
|
||||||
|
|
||||||
|
/* Define this if your time.h defines altzone */
|
||||||
|
/* #define HAVE_ALTZONE */
|
||||||
|
|
||||||
|
/* Define if you have the putenv function. */
|
||||||
|
#define HAVE_PUTENV
|
||||||
|
|
||||||
|
/* Define if your compiler supports function prototypes */
|
||||||
|
#define HAVE_PROTOTYPES
|
||||||
|
|
||||||
|
/* Define if you can safely include both <sys/select.h> and <sys/time.h>
|
||||||
|
(which you can't on SCO ODT 3.0). */
|
||||||
|
/* #undef SYS_SELECT_WITH_SYS_TIME */
|
||||||
|
|
||||||
|
/* Define if you want build the _decimal module using a coroutine-local rather
|
||||||
|
than a thread-local context */
|
||||||
|
#define WITH_DECIMAL_CONTEXTVAR 1
|
||||||
|
|
||||||
|
/* Define if you want documentation strings in extension modules */
|
||||||
|
#define WITH_DOC_STRINGS 1
|
||||||
|
|
||||||
|
/* Define if you want to compile in rudimentary thread support */
|
||||||
|
/* #undef WITH_THREAD */
|
||||||
|
|
||||||
|
/* Define if you want to use the GNU readline library */
|
||||||
|
/* #define WITH_READLINE 1 */
|
||||||
|
|
||||||
|
/* Use Python's own small-block memory-allocator. */
|
||||||
|
#define WITH_PYMALLOC 1
|
||||||
|
|
||||||
|
/* Define if you want to compile in object freelists optimization */
|
||||||
|
#define WITH_FREELISTS 1
|
||||||
|
|
||||||
|
/* Define if you have clock. */
|
||||||
|
/* #define HAVE_CLOCK */
|
||||||
|
|
||||||
|
/* Define when any dynamic module loading is enabled */
|
||||||
|
#define HAVE_DYNAMIC_LOADING
|
||||||
|
|
||||||
|
/* Define if you have ftime. */
|
||||||
|
#define HAVE_FTIME
|
||||||
|
|
||||||
|
/* Define if you have getpeername. */
|
||||||
|
#define HAVE_GETPEERNAME
|
||||||
|
|
||||||
|
/* Define if you have getpgrp. */
|
||||||
|
/* #undef HAVE_GETPGRP */
|
||||||
|
|
||||||
|
/* Define if you have getpid. */
|
||||||
|
#define HAVE_GETPID
|
||||||
|
|
||||||
|
/* Define if you have gettimeofday. */
|
||||||
|
/* #undef HAVE_GETTIMEOFDAY */
|
||||||
|
|
||||||
|
/* Define if you have getwd. */
|
||||||
|
/* #undef HAVE_GETWD */
|
||||||
|
|
||||||
|
/* Define if you have lstat. */
|
||||||
|
/* #undef HAVE_LSTAT */
|
||||||
|
|
||||||
|
/* Define if you have the mktime function. */
|
||||||
|
#define HAVE_MKTIME
|
||||||
|
|
||||||
|
/* Define if you have nice. */
|
||||||
|
/* #undef HAVE_NICE */
|
||||||
|
|
||||||
|
/* Define if you have readlink. */
|
||||||
|
/* #undef HAVE_READLINK */
|
||||||
|
|
||||||
|
/* Define if you have setpgid. */
|
||||||
|
/* #undef HAVE_SETPGID */
|
||||||
|
|
||||||
|
/* Define if you have setpgrp. */
|
||||||
|
/* #undef HAVE_SETPGRP */
|
||||||
|
|
||||||
|
/* Define if you have setsid. */
|
||||||
|
/* #undef HAVE_SETSID */
|
||||||
|
|
||||||
|
/* Define if you have setvbuf. */
|
||||||
|
#define HAVE_SETVBUF
|
||||||
|
|
||||||
|
/* Define if you have siginterrupt. */
|
||||||
|
/* #undef HAVE_SIGINTERRUPT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `shutdown' function. */
|
||||||
|
#define HAVE_SHUTDOWN 1
|
||||||
|
|
||||||
|
/* Define if you have symlink. */
|
||||||
|
/* #undef HAVE_SYMLINK */
|
||||||
|
|
||||||
|
/* Define if you have tcgetpgrp. */
|
||||||
|
/* #undef HAVE_TCGETPGRP */
|
||||||
|
|
||||||
|
/* Define if you have tcsetpgrp. */
|
||||||
|
/* #undef HAVE_TCSETPGRP */
|
||||||
|
|
||||||
|
/* Define if you have times. */
|
||||||
|
/* #undef HAVE_TIMES */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `umask' function. */
|
||||||
|
#define HAVE_UMASK 1
|
||||||
|
|
||||||
|
/* Define if you have uname. */
|
||||||
|
/* #undef HAVE_UNAME */
|
||||||
|
|
||||||
|
/* Define if you have waitpid. */
|
||||||
|
/* #undef HAVE_WAITPID */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `wcsftime' function. */
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1310
|
||||||
|
#define HAVE_WCSFTIME 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `wcscoll' function. */
|
||||||
|
#define HAVE_WCSCOLL 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `wcsxfrm' function. */
|
||||||
|
#define HAVE_WCSXFRM 1
|
||||||
|
|
||||||
|
/* Define if the zlib library has inflateCopy */
|
||||||
|
#define HAVE_ZLIB_COPY 1
|
||||||
|
|
||||||
|
/* Define if you have the <dlfcn.h> header file. */
|
||||||
|
/* #undef HAVE_DLFCN_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <errno.h> header file. */
|
||||||
|
#define HAVE_ERRNO_H 1
|
||||||
|
|
||||||
|
/* Define if you have the <fcntl.h> header file. */
|
||||||
|
#define HAVE_FCNTL_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <process.h> header file. */
|
||||||
|
#define HAVE_PROCESS_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <signal.h> header file. */
|
||||||
|
#define HAVE_SIGNAL_H 1
|
||||||
|
|
||||||
|
/* Define if you have the <stdarg.h> prototypes. */
|
||||||
|
#define HAVE_STDARG_PROTOTYPES
|
||||||
|
|
||||||
|
/* Define if you have the <stddef.h> header file. */
|
||||||
|
#define HAVE_STDDEF_H 1
|
||||||
|
|
||||||
|
/* Define if you have the <sys/audioio.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_AUDIOIO_H */
|
||||||
|
|
||||||
|
/* Define if you have the <sys/param.h> header file. */
|
||||||
|
/* #define HAVE_SYS_PARAM_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the <sys/select.h> header file. */
|
||||||
|
/* #define HAVE_SYS_SELECT_H 1 */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#define HAVE_SYS_STAT_H 1
|
||||||
|
|
||||||
|
/* Define if you have the <sys/time.h> header file. */
|
||||||
|
/* #define HAVE_SYS_TIME_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the <sys/times.h> header file. */
|
||||||
|
/* #define HAVE_SYS_TIMES_H 1 */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#define HAVE_SYS_TYPES_H 1
|
||||||
|
|
||||||
|
/* Define if you have the <sys/un.h> header file. */
|
||||||
|
/* #define HAVE_SYS_UN_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the <sys/utime.h> header file. */
|
||||||
|
/* #define HAVE_SYS_UTIME_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the <sys/utsname.h> header file. */
|
||||||
|
/* #define HAVE_SYS_UTSNAME_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the <unistd.h> header file. */
|
||||||
|
/* #define HAVE_UNISTD_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the <utime.h> header file. */
|
||||||
|
/* #define HAVE_UTIME_H 1 */
|
||||||
|
|
||||||
|
/* Define if the compiler provides a wchar.h header file. */
|
||||||
|
#define HAVE_WCHAR_H 1
|
||||||
|
|
||||||
|
/* The size of `wchar_t', as computed by sizeof. */
|
||||||
|
#define SIZEOF_WCHAR_T 2
|
||||||
|
|
||||||
|
/* The size of `_Bool', as computed by sizeof. */
|
||||||
|
#define SIZEOF__BOOL 1
|
||||||
|
|
||||||
|
/* The size of `pid_t', as computed by sizeof. */
|
||||||
|
#define SIZEOF_PID_T SIZEOF_INT
|
||||||
|
|
||||||
|
/* Define if you have the dl library (-ldl). */
|
||||||
|
/* #undef HAVE_LIBDL */
|
||||||
|
|
||||||
|
/* Define if you have the mpc library (-lmpc). */
|
||||||
|
/* #undef HAVE_LIBMPC */
|
||||||
|
|
||||||
|
/* Define if you have the nsl library (-lnsl). */
|
||||||
|
#define HAVE_LIBNSL 1
|
||||||
|
|
||||||
|
/* Define if you have the seq library (-lseq). */
|
||||||
|
/* #undef HAVE_LIBSEQ */
|
||||||
|
|
||||||
|
/* Define if you have the socket library (-lsocket). */
|
||||||
|
#define HAVE_LIBSOCKET 1
|
||||||
|
|
||||||
|
/* Define if you have the sun library (-lsun). */
|
||||||
|
/* #undef HAVE_LIBSUN */
|
||||||
|
|
||||||
|
/* Define if you have the termcap library (-ltermcap). */
|
||||||
|
/* #undef HAVE_LIBTERMCAP */
|
||||||
|
|
||||||
|
/* Define if you have the termlib library (-ltermlib). */
|
||||||
|
/* #undef HAVE_LIBTERMLIB */
|
||||||
|
|
||||||
|
/* Define if you have the thread library (-lthread). */
|
||||||
|
/* #undef HAVE_LIBTHREAD */
|
||||||
|
|
||||||
|
/* WinSock does not use a bitmask in select, and uses
|
||||||
|
socket handles greater than FD_SETSIZE */
|
||||||
|
#define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
|
||||||
|
|
||||||
|
/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the
|
||||||
|
least significant byte first */
|
||||||
|
#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `erf' function. */
|
||||||
|
#define HAVE_ERF 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `erfc' function. */
|
||||||
|
#define HAVE_ERFC 1
|
||||||
|
|
||||||
|
// netdb.h functions (provided by winsock.h)
|
||||||
|
#define HAVE_GETHOSTNAME 1
|
||||||
|
#define HAVE_GETHOSTBYADDR 1
|
||||||
|
#define HAVE_GETHOSTBYNAME 1
|
||||||
|
#define HAVE_GETPROTOBYNAME 1
|
||||||
|
#define HAVE_GETSERVBYNAME 1
|
||||||
|
#define HAVE_GETSERVBYPORT 1
|
||||||
|
// sys/socket.h functions (provided by winsock.h)
|
||||||
|
#define HAVE_INET_PTON 1
|
||||||
|
#define HAVE_INET_NTOA 1
|
||||||
|
#define HAVE_ACCEPT 1
|
||||||
|
#define HAVE_BIND 1
|
||||||
|
#define HAVE_CONNECT 1
|
||||||
|
#define HAVE_GETSOCKNAME 1
|
||||||
|
#define HAVE_LISTEN 1
|
||||||
|
#define HAVE_RECVFROM 1
|
||||||
|
#define HAVE_SENDTO 1
|
||||||
|
#define HAVE_SETSOCKOPT 1
|
||||||
|
#define HAVE_SOCKET 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `dup' function. */
|
||||||
|
#define HAVE_DUP 1
|
||||||
|
|
||||||
|
/* framework name */
|
||||||
|
#define _PYTHONFRAMEWORK ""
|
||||||
|
|
||||||
|
/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */
|
||||||
|
#define HAVE_X509_VERIFY_PARAM_SET1_HOST 1
|
||||||
|
|
||||||
|
#endif /* !Py_CONFIG_H */
|
|
@ -15,10 +15,26 @@ std::wstring executable_path()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wstring executable_filename()
|
||||||
|
{
|
||||||
|
auto exec_path = std::filesystem::canonical("/proc/self/exe");
|
||||||
|
return exec_path.wstring();
|
||||||
|
}
|
||||||
|
|
||||||
std::wstring working_path()
|
std::wstring working_path()
|
||||||
{
|
{
|
||||||
auto cwd = std::filesystem::current_path();
|
auto cwd = std::filesystem::current_path();
|
||||||
return cwd.wstring();
|
return cwd.wstring();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string narrow_string(std::wstring convertme)
|
||||||
|
{
|
||||||
|
//setup converter
|
||||||
|
using convert_type = std::codecvt_utf8<wchar_t>;
|
||||||
|
std::wstring_convert<convert_type, wchar_t> converter;
|
||||||
|
|
||||||
|
//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
|
||||||
|
return converter.to_bytes(convertme);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.32126.315
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mcrogueface_msvc", "mcrogueface_msvc.vcxproj", "{C00F9FB3-0806-41E8-9A10-29A325022EE1}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{C00F9FB3-0806-41E8-9A10-29A325022EE1}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{C00F9FB3-0806-41E8-9A10-29A325022EE1}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{C00F9FB3-0806-41E8-9A10-29A325022EE1}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{C00F9FB3-0806-41E8-9A10-29A325022EE1}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{C00F9FB3-0806-41E8-9A10-29A325022EE1}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{C00F9FB3-0806-41E8-9A10-29A325022EE1}.Release|x64.Build.0 = Release|x64
|
||||||
|
{C00F9FB3-0806-41E8-9A10-29A325022EE1}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{C00F9FB3-0806-41E8-9A10-29A325022EE1}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {1EE0CDF9-5331-47E9-828B-7AAA768F56EC}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,182 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\src\Animation.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\Button.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\Entity.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\EntityManager.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\GameEngine.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\Grid.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\IndexSprite.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\IndexTexture.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\main.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\McRFPy_API.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\MenuScene.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\PythonScene.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\Scene.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\UIMenu.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\UITestScene.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\VectorShape.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\src\ActionCode.h" />
|
||||||
|
<ClInclude Include="..\..\..\src\Common.h" />
|
||||||
|
<ClInclude Include="..\..\..\src\Components.h" />
|
||||||
|
<ClInclude Include="..\platform.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{c00f9fb3-0806-41e8-9a10-29a325022ee1}</ProjectGuid>
|
||||||
|
<RootNamespace>mcroguefacemsvc</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)..\bin\windows\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)..\.msvc-intermediate\$(Configuration)\</IntDir>
|
||||||
|
<TargetName>combined_poc</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)..\..\..\bin\windows\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)..\.msvc-intermediate\$(Configuration)\</IntDir>
|
||||||
|
<TargetName>mcrogueface</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>C:\Users\jpm68\Share\McRogueFace\deps\SFML-2.5.1\include;C:\Users\jpm68\Share\McRogueFace\deps\posix-stub;C:\Users\jpm68\Share\McRogueFace\deps\Python-3.11.1\Include;C:\Users\jpm68\Share\McRogueFace\deps\Python-3.11.1\PC;C:\Users\jpm68\Share\McRogueFace\deps\libtcod-1.23.1-x86_64-msvc\include;C:\Users\jpm68\Share\McRogueFace\platform\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>C:\Users\jpm68\Share\McRogueFace\deps\SFML-2.5.1\include;C:\Users\jpm68\Share\McRogueFace\deps\posix-stub;C:\Users\jpm68\Share\McRogueFace\deps\Python-3.11.1\Include;C:\Users\jpm68\Share\McRogueFace\deps\Python-3.11.1\PC;C:\Users\jpm68\Share\McRogueFace\deps\libtcod-1.23.1-x86_64-msvc\include;C:\Users\jpm68\Share\McRogueFace\platform\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<AdditionalIncludeDirectories>C:\Users\jpm68\Share\McRogueFace\deps\SFML-2.5.1\include;C:\Users\jpm68\Share\McRogueFace\deps\posix-stub;C:\Users\jpm68\Share\McRogueFace\deps\Python-3.11.1\Include;C:\Users\jpm68\Share\McRogueFace\deps\Python-3.11.1\PC;C:\Users\jpm68\Share\McRogueFace\deps\libtcod-1.23.1-x86_64-msvc\include;C:\Users\jpm68\Share\McRogueFace\platform\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<AdditionalIncludeDirectories>C:\Users\jpm68\Share\McRogueFace\deps_windows\posix-stub;C:\Users\jpm68\Share\McRogueFace\platform\windows;C:\Users\jpm68\Share\McRogueFace\deps_windows\SFML-2.5.1\include;C:\Users\jpm68\Share\McRogueFace\deps_windows\Python-3.11.1\Include;C:\Users\jpm68\Share\McRogueFace\deps_windows\Python-3.11.1\PC;C:\Users\jpm68\Share\McRogueFace\deps_windows\libtcod-1.23.1-x86_64-msvc\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>C:\Users\jpm68\Share\McRogueFace\deps_windows\Python-3.11.1\PCbuild\amd64;C:\Users\jpm68\Share\McRogueFace\deps_windows\libtcod-1.23.1-x86_64-msvc;C:\Users\jpm68\Share\McRogueFace\deps_windows\SFML-2.5.1\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>libtcod.lib;sfml-audio.lib;sfml-graphics.lib;sfml-window.lib;sfml-system.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\src\main.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\Button.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\Entity.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\EntityManager.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\GameEngine.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\MenuScene.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\Scene.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\UIMenu.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\UITestScene.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\VectorShape.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\McRFPy_API.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\PythonScene.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\IndexSprite.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\IndexTexture.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\Grid.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\Animation.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\src\ActionCode.h">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\src\Common.h">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\src\Components.h">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\platform.h">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup />
|
||||||
|
</Project>
|
|
@ -12,10 +12,28 @@ std::wstring executable_path()
|
||||||
return exec_path.substr(0, path_index);
|
return exec_path.substr(0, path_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wstring executable_filename()
|
||||||
|
{
|
||||||
|
wchar_t buffer[MAX_PATH];
|
||||||
|
GetModuleFileName(NULL, buffer, MAX_PATH);
|
||||||
|
std::wstring exec_path = buffer;
|
||||||
|
return exec_path;
|
||||||
|
}
|
||||||
|
|
||||||
std::wstring working_path()
|
std::wstring working_path()
|
||||||
{
|
{
|
||||||
auto cwd = std::filesystem::current_path();
|
auto cwd = std::filesystem::current_path();
|
||||||
return cwd.wstring();
|
return cwd.wstring();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string narrow_string(std::wstring convertme)
|
||||||
|
{
|
||||||
|
//setup converter
|
||||||
|
using convert_type = std::codecvt_utf8<wchar_t>;
|
||||||
|
std::wstring_convert<convert_type, wchar_t> converter;
|
||||||
|
|
||||||
|
//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
|
||||||
|
return converter.to_bytes(convertme);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
Required project settings to build in Visual Studio 19:
|
||||||
|
|
||||||
|
C/C++ > General
|
||||||
|
Additional Include Directories
|
||||||
|
\McRogueFace\platform\windows
|
||||||
|
\McRogueFace\deps_windows\libtcod-1.23.1-x86_64-msvc\include
|
||||||
|
\McRogueFace\deps_windows\Python-3.11.1\PC
|
||||||
|
\McRogueFace\deps_windows\Python-3.11.1\Include
|
||||||
|
\McRogueFace\deps_windows\posix-stub
|
||||||
|
\McRogueFace\deps_windows\SFML-2.5.1\include
|
||||||
|
|
||||||
|
C/C++ > Preprocessor
|
||||||
|
Preprocessor Definitions
|
||||||
|
_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
|
||||||
|
|
||||||
|
Linker > General
|
||||||
|
Additional Library Directories
|
||||||
|
\McRogueFace\deps_windows\SFML-2.5.1\lib
|
||||||
|
\McRogueFace\deps_windows\libtcod-1.23.1-x86_64-msvc
|
||||||
|
\McRogueFace\deps_windows\Python-3.11.1\PCbuild\amd64
|
||||||
|
|
||||||
|
Linker > Input
|
||||||
|
Additional Dependencies
|
||||||
|
libtcod.lib
|
||||||
|
sfml-audio.lib
|
||||||
|
sfml-graphics.lib
|
||||||
|
sfml-window.lib
|
||||||
|
sfml-system.lib
|
|
@ -1,3 +1,4 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
cp src/scripts/*.py bin/linux/scripts/
|
||||||
cd bin/linux
|
cd bin/linux
|
||||||
./poc
|
./mcrogueface
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include <SFML/Window/Keyboard.hpp>
|
||||||
|
|
||||||
|
class ActionCode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum CodeType { Key = 0, Mousebutton, Mousewheel };
|
||||||
|
const static int KEY = 4096;
|
||||||
|
const static int MOUSEBUTTON = 8192;
|
||||||
|
const static int MOUSEWHEEL = 16384;
|
||||||
|
|
||||||
|
const static int WHEEL_NUM = 4;
|
||||||
|
const static int WHEEL_NEG = 2;
|
||||||
|
const static int WHEEL_DEL = 1;
|
||||||
|
static int keycode(sf::Keyboard::Key& k) { return KEY + (int)k; }
|
||||||
|
static int keycode(sf::Mouse::Button& b) { return MOUSEBUTTON + (int)b; }
|
||||||
|
//static int keycode(sf::Mouse::Wheel& w, float d) { return MOUSEWHEEL + (((int)w)<<12) + int(d*16) + 512; }
|
||||||
|
static int keycode(sf::Mouse::Wheel& w, float d) {
|
||||||
|
int neg = 0;
|
||||||
|
if (d < 0) { neg = 1; }
|
||||||
|
return MOUSEWHEEL + (w * WHEEL_NUM) + (neg * WHEEL_NEG) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int key(int a) { return a & KEY; }
|
||||||
|
static int mouseButton(int a) { return a & MOUSEBUTTON; }
|
||||||
|
static bool isMouseWheel(int a) { return a & MOUSEWHEEL; }
|
||||||
|
//static int wheel(int a) { return a || MOUSEWHEEL >> 12; }
|
||||||
|
static int wheel(int a) { return (a & WHEEL_NUM) / WHEEL_NUM; }
|
||||||
|
//static float delta(int a) { return (a || MOUSEWHEEL || 2047) / 16.0f - 512; }
|
||||||
|
static int delta(int a) {
|
||||||
|
int factor = 1;
|
||||||
|
if (a & WHEEL_NEG) factor = -1;
|
||||||
|
return (a & WHEEL_DEL) * factor;
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,124 @@
|
||||||
|
#include "Animation.h"
|
||||||
|
|
||||||
|
Animation::Animation(float _d, std::function<void()> _cb, bool _l)
|
||||||
|
:duration(_d), callback(_cb), loop(_l), elapsed(0.0f) {}
|
||||||
|
|
||||||
|
// linear interpolation constructor
|
||||||
|
template<typename T>
|
||||||
|
LerpAnimation<T>::LerpAnimation(float _d, T _ev, T _sv, std::function<void()> _cb, std::function<void(T)> _w, bool _l)
|
||||||
|
:Animation(_d, _cb, _l), //duration(_d), target(_t), callback(_cb), loop(_l),elapsed(0.0f),
|
||||||
|
startvalue(_sv), endvalue(_ev), write(_w) {}
|
||||||
|
|
||||||
|
// discrete values constructor
|
||||||
|
template<typename T>
|
||||||
|
DiscreteAnimation<T>::DiscreteAnimation(float _d, std::vector<T> _v, std::function<void()> _cb, std::function<void(T)> _w, bool _l)
|
||||||
|
:Animation(_d, _cb, _l), //duration(_d), target(_t), callback(_cb), loop(_l), elapsed(0.0f),
|
||||||
|
index(0), nonelapsed(0.0f), values(_v), write(_w) {
|
||||||
|
timestep = _d / _v.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* // don't call virtual functions (like cancel()) from base class destructor
|
||||||
|
* // child classes destructors' are called first anyway
|
||||||
|
Animation::~Animation() {
|
||||||
|
// deconstructor sets target to desired end state (no partial values)
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void LerpAnimation<std::string>::lerp() {
|
||||||
|
//*(std::string*)target = ;
|
||||||
|
write(endvalue.substr(0, endvalue.length() * (elapsed / duration)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void LerpAnimation<int>::lerp() {
|
||||||
|
int delta = endvalue - startvalue;
|
||||||
|
//*(int*)target = ;
|
||||||
|
write(startvalue + (elapsed / duration * delta));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void LerpAnimation<float>::lerp() {
|
||||||
|
int delta = endvalue - startvalue;
|
||||||
|
//*(float*)target = ;
|
||||||
|
write(startvalue + (elapsed / duration * delta));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void LerpAnimation<sf::Vector2f>::lerp() {
|
||||||
|
//std::cout << "sf::Vector2f implementation of lerp." << std::endl;
|
||||||
|
int delta_x = endvalue.x - startvalue.x;
|
||||||
|
int delta_y = endvalue.y - startvalue.y;
|
||||||
|
//std::cout << "Start: " << startvalue.x << ", " << startvalue.y << "; End: " << endvalue.x << ", " << endvalue.y << std::endl;
|
||||||
|
//std::cout << "Delta: " << delta_x << ", " << delta_y << std::endl;
|
||||||
|
//((sf::Vector2f*)target)->x = startvalue.x + (elapsed / duration * delta_x);
|
||||||
|
//((sf::Vector2f*)target)->y = startvalue.y + (elapsed / duration * delta_y);
|
||||||
|
write(sf::Vector2f(startvalue.x + (elapsed / duration * delta_x),
|
||||||
|
startvalue.y + (elapsed / duration * delta_y)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void LerpAnimation<sf::Vector2i>::lerp() {
|
||||||
|
int delta_x = endvalue.x - startvalue.y;
|
||||||
|
int delta_y = endvalue.y - startvalue.y;
|
||||||
|
//((sf::Vector2i*)target)->x = startvalue.x + (elapsed / duration * delta_x);
|
||||||
|
//((sf::Vector2i*)target)->y = startvalue.y + (elapsed / duration * delta_y);
|
||||||
|
write(sf::Vector2i(startvalue.x + (elapsed / duration * delta_x),
|
||||||
|
startvalue.y + (elapsed / duration * delta_y)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void LerpAnimation<T>::step(float delta) {
|
||||||
|
if (complete) return;
|
||||||
|
elapsed += delta;
|
||||||
|
//std::cout << "LerpAnimation step function. Elapsed: " << elapsed <<std::endl;
|
||||||
|
lerp();
|
||||||
|
if (isDone()) { callback(); complete = true; cancel(); }; //use the exact value, not my math
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void DiscreteAnimation<T>::step(float delta)
|
||||||
|
{
|
||||||
|
if (complete) return;
|
||||||
|
nonelapsed += delta;
|
||||||
|
//std::cout << "Nonelapsed: " << nonelapsed << " elapsed (pre-add): " << elapsed << " timestep: " << timestep << " duration: " << duration << " index: " << index << std::endl;
|
||||||
|
if (nonelapsed < timestep) return;
|
||||||
|
//std::cout << "values size: " << values.size() << " isDone(): " << isDone() << std::endl;
|
||||||
|
if (elapsed > duration && !complete) {callback(); complete = true; return; }
|
||||||
|
elapsed += nonelapsed; // or should it be += timestep?
|
||||||
|
if (index == values.size() - 1) return;
|
||||||
|
nonelapsed = 0; // or should it -= timestep?
|
||||||
|
index++;
|
||||||
|
//*(T*)target = values[index];
|
||||||
|
write(values[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void LerpAnimation<T>::cancel() {
|
||||||
|
//*(T*)target = endvalue;
|
||||||
|
write(endvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void DiscreteAnimation<T>::cancel() {
|
||||||
|
//*(T*)target = values[values.size() - 1];
|
||||||
|
write(values[values.size() - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Animation::isDone() {
|
||||||
|
return elapsed + Animation::EPSILON >= duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace animation_template_implementations {
|
||||||
|
// instantiate to compile concrete templates
|
||||||
|
//LerpAnimation<sf::Vector2f> implement_vector2f;
|
||||||
|
|
||||||
|
auto implement_v2f_const = LerpAnimation<sf::Vector2<float>>(4.0, sf::Vector2<float>(), sf::Vector2f(1,1), [](){}, [](sf::Vector2f v){}, false);
|
||||||
|
auto implement_disc_i = DiscreteAnimation<int>(3.0, std::vector<int>{0},[](){},[](int){},false);
|
||||||
|
//LerpAnimation<sf::Vector2i> implement_vector2i;
|
||||||
|
//LerpAnimation<int> implment_int;
|
||||||
|
//LerpAnimation<std::string> implment_string;
|
||||||
|
//LerpAnimation<float> implement_float;
|
||||||
|
//DiscreteAnimation<int> implement_int_discrete;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Common.h"
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class Animation
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
static constexpr float EPSILON = 0.05;
|
||||||
|
float duration, elapsed;
|
||||||
|
std::function<void()> callback;
|
||||||
|
bool loop;
|
||||||
|
bool complete=false;
|
||||||
|
public:
|
||||||
|
//Animation(float, T, T*, std::function<void()>, bool); // lerp
|
||||||
|
//Animation(float, std::vector<T>, T*, std::function<void()>, bool); // discrete
|
||||||
|
Animation(float, std::function<void()>, bool);
|
||||||
|
//Animation() {};
|
||||||
|
virtual void step(float) = 0;
|
||||||
|
virtual void cancel() = 0;
|
||||||
|
bool isDone();
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class LerpAnimation: public Animation
|
||||||
|
{
|
||||||
|
T startvalue, endvalue;
|
||||||
|
std::function<void(T)> write;
|
||||||
|
void lerp();
|
||||||
|
public:
|
||||||
|
~LerpAnimation() { cancel(); }
|
||||||
|
LerpAnimation(float, T, T, std::function<void()>, std::function<void(T)>, bool);
|
||||||
|
//LerpAnimation() {};
|
||||||
|
void step(float) override final;
|
||||||
|
void cancel() override final;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class DiscreteAnimation: public Animation
|
||||||
|
{
|
||||||
|
std::vector<T> values;
|
||||||
|
std::function<void(T)> write;
|
||||||
|
float nonelapsed, timestep;
|
||||||
|
int index;
|
||||||
|
public:
|
||||||
|
DiscreteAnimation(float, std::vector<T>, std::function<void()>, std::function<void(T)>, bool);
|
||||||
|
DiscreteAnimation() {};
|
||||||
|
~DiscreteAnimation() { cancel(); }
|
||||||
|
void step(float) override final;
|
||||||
|
void cancel() override final;
|
||||||
|
};
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "Button.h"
|
||||||
|
|
||||||
|
void Button::render(sf::RenderWindow & window)
|
||||||
|
{
|
||||||
|
window.draw(rect);
|
||||||
|
window.draw(caption);
|
||||||
|
}
|
||||||
|
|
||||||
|
Button::Button(int x, int y, int w, int h,
|
||||||
|
sf::Color _background, sf::Color _textcolor,
|
||||||
|
const char * _caption, sf::Font & font,
|
||||||
|
const char * _action)
|
||||||
|
{
|
||||||
|
rect.setPosition(sf::Vector2f(x, y));
|
||||||
|
rect.setSize(sf::Vector2f(w, h));
|
||||||
|
rect.setFillColor(_background);
|
||||||
|
|
||||||
|
caption.setFillColor(_textcolor);
|
||||||
|
caption.setPosition(sf::Vector2f(x, y));
|
||||||
|
caption.setString(_caption);
|
||||||
|
caption.setFont(font);
|
||||||
|
|
||||||
|
action = _action;
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
class Button
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
public:
|
||||||
|
// TODO / JankMode: setter & getter for these three fields
|
||||||
|
// were protected, but directly changing them should be...fine?
|
||||||
|
sf::RectangleShape rect;
|
||||||
|
sf::Text caption;
|
||||||
|
std::string action;
|
||||||
|
|
||||||
|
Button() {};
|
||||||
|
Button(int x, int y, int w, int h,
|
||||||
|
sf::Color _background, sf::Color _textcolor,
|
||||||
|
const char * _caption, sf::Font & font,
|
||||||
|
const char * _action);
|
||||||
|
void setPosition(sf::Vector2f v) { rect.setPosition(v); caption.setPosition(v); }
|
||||||
|
void setSize(sf::Vector2f & v) { rect.setSize(v); }
|
||||||
|
void setBackground(sf::Color c) { rect.setFillColor(c); }
|
||||||
|
void setCaption(std::string & s) { caption.setString(s); }
|
||||||
|
void setTextColor(sf::Color c) { caption.setFillColor(c); }
|
||||||
|
void render(sf::RenderWindow & window);
|
||||||
|
auto contains(sf::Vector2i p) { return rect.getGlobalBounds().contains(p.x, p.y); }
|
||||||
|
auto contains(sf::Vector2f rel, sf::Vector2i p) {
|
||||||
|
return rect.getGlobalBounds().contains(p.x - rel.x, p.y - rel.y);
|
||||||
|
}
|
||||||
|
auto getAction() { return action; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
|
@ -0,0 +1,16 @@
|
||||||
|
# pragma once
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
#include <SFML/Audio.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
// wstring<->string conversion
|
||||||
|
#include <locale>
|
||||||
|
#include <codecvt>
|
||||||
|
#include <filesystem>
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "IndexSprite.h"
|
||||||
|
#include "Grid.h"
|
||||||
|
//#include "Item.h"
|
||||||
|
#include "Python.h"
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
class CGrid
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool visible;
|
||||||
|
int x, y;
|
||||||
|
IndexSprite indexsprite;
|
||||||
|
Grid* grid;
|
||||||
|
CGrid(Grid* _g, int _ti, int _si, int _x, int _y, bool _v)
|
||||||
|
: visible(_v), x(_x), y(_y), grid(_g), indexsprite(_ti, _si, _x, _y, 1.0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CInventory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//std::list<std::shared_ptr<Item>>;
|
||||||
|
int x;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBehavior
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PyObject* object;
|
||||||
|
CBehavior(PyObject* p): object(p) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
class CCombatant
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int hp;
|
||||||
|
int maxhp;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CCaster
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int mp;
|
||||||
|
int maxmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CLevel
|
||||||
|
{
|
||||||
|
int constitution; // +HP, resist effects
|
||||||
|
int strength; // +damage, block/parry
|
||||||
|
int dexterity; // +speed, dodge
|
||||||
|
int intelligence; // +MP, spell resist
|
||||||
|
int wisdom; // +damage, deflect
|
||||||
|
int luck; // crit, loot
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
class CTransform
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vec2 pos = { 0.0, 0.0 };
|
||||||
|
Vec2 velocity = { 0.0, 0.0 };
|
||||||
|
float angle = 0;
|
||||||
|
|
||||||
|
CTransform(const Vec2 & p, const Vec2 & v, float a)
|
||||||
|
: pos(p), velocity(v), angle(a) {}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
class CShape
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sf::CircleShape circle;
|
||||||
|
|
||||||
|
CShape(float radius, int points, const sf::Color & fill, const sf::Color & outline, float thickness)
|
||||||
|
: circle(radius, points)
|
||||||
|
{
|
||||||
|
circle.setFillColor(fill);
|
||||||
|
circle.setOutlineColor(outline);
|
||||||
|
circle.setOutlineThickness(thickness);
|
||||||
|
circle.setOrigin(radius, radius);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CCollision
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float radius = 0;
|
||||||
|
CCollision(float r)
|
||||||
|
: radius(r) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CScore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int score = 0;
|
||||||
|
CScore(int s)
|
||||||
|
: score(s) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CLifespan
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int remaining = 0;
|
||||||
|
int total = 0;
|
||||||
|
CLifespan(int t)
|
||||||
|
: remaining(t), total(t) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CInput
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool up = false;
|
||||||
|
bool left = false;
|
||||||
|
bool right = false;
|
||||||
|
bool down = false;
|
||||||
|
bool fire = false;
|
||||||
|
|
||||||
|
CInput() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CSteer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sf::Vector2f position;
|
||||||
|
sf::Vector2f velocity;
|
||||||
|
float v_max;
|
||||||
|
float dv_max;
|
||||||
|
float theta_max;
|
||||||
|
float dtheta_max;
|
||||||
|
};
|
||||||
|
*/
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
Entity::Entity(const size_t i, const std::string & t)
|
||||||
|
: m_id(i), m_tag(t) {}
|
||||||
|
|
||||||
|
bool Entity::isActive() const
|
||||||
|
{
|
||||||
|
return m_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string & Entity::tag() const
|
||||||
|
{
|
||||||
|
return m_tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t Entity::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::destroy()
|
||||||
|
{
|
||||||
|
m_active = false;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
#include "Components.h"
|
||||||
|
|
||||||
|
class Entity
|
||||||
|
{
|
||||||
|
friend class EntityManager;
|
||||||
|
|
||||||
|
bool m_active = true;
|
||||||
|
size_t m_id = 0;
|
||||||
|
std::string m_tag = "default";
|
||||||
|
|
||||||
|
//constructor and destructor
|
||||||
|
Entity(const size_t id, const std::string & t);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// component pointers
|
||||||
|
//std::shared_ptr<CTransform> cTransform;
|
||||||
|
//std::shared_ptr<CShape> cShape;
|
||||||
|
//std::shared_ptr<CCollision> cCollision;
|
||||||
|
//std::shared_ptr<CInput> cInput;
|
||||||
|
//std::shared_ptr<CScore> cScore;
|
||||||
|
//std::shared_ptr<CLifespan> cLifespan;
|
||||||
|
std::shared_ptr<CGrid> cGrid;
|
||||||
|
std::shared_ptr<CInventory> cInventory;
|
||||||
|
std::shared_ptr<CBehavior> cBehavior;
|
||||||
|
|
||||||
|
//private member access functions
|
||||||
|
bool isActive() const;
|
||||||
|
const std::string & tag() const;
|
||||||
|
const size_t id() const;
|
||||||
|
void destroy();
|
||||||
|
};
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include "EntityManager.h"
|
||||||
|
|
||||||
|
EntityManager::EntityManager()
|
||||||
|
:m_totalEntities(0) {}
|
||||||
|
|
||||||
|
void EntityManager::update()
|
||||||
|
{
|
||||||
|
//TODO: add entities from m_entitiesToAdd to all vector / tag map
|
||||||
|
removeDeadEntities(m_entities);
|
||||||
|
|
||||||
|
// C++17 way of iterating!
|
||||||
|
for (auto& [tag, entityVec] : m_entityMap)
|
||||||
|
{
|
||||||
|
removeDeadEntities(entityVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& e : m_entitiesToAdd)
|
||||||
|
{
|
||||||
|
m_entities.push_back(e);
|
||||||
|
m_entityMap[e->tag()].push_back(e);
|
||||||
|
}
|
||||||
|
//if (m_entitiesToAdd.size())
|
||||||
|
// m_entitiesToAdd.erase(m_entitiesToAdd.begin(), m_entitiesToAdd.end());
|
||||||
|
m_entitiesToAdd = EntityVec();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityManager::removeDeadEntities(EntityVec & vec)
|
||||||
|
{
|
||||||
|
EntityVec survivors; // New vector
|
||||||
|
for (auto& e : m_entities){
|
||||||
|
if (e->isActive()) survivors.push_back(e); // populate new vector
|
||||||
|
else if (e->cGrid) { // erase vector from grid
|
||||||
|
for( auto it = e->cGrid->grid->entities.begin(); it != e->cGrid->grid->entities.end(); it++){
|
||||||
|
if( *it == e ){
|
||||||
|
e->cGrid->grid->entities.erase( it );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//std::cout << "All entities: " << m_entities.size() << " Survivors: " << survivors.size() << std::endl;
|
||||||
|
m_entities = survivors; // point to new vector
|
||||||
|
for (auto& [tag, entityVec] : m_entityMap)
|
||||||
|
{
|
||||||
|
EntityVec tag_survivors; // New vector
|
||||||
|
for (auto& e : m_entityMap[tag])
|
||||||
|
{
|
||||||
|
if (e->isActive()) tag_survivors.push_back(e); // populate new vector
|
||||||
|
}
|
||||||
|
m_entityMap[tag] = tag_survivors; // point to new vector
|
||||||
|
//std::cout << tag << " entities: " << m_entityMap[tag].size() << " Survivors: " << tag_survivors.size() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Entity> EntityManager::addEntity(const std::string & tag)
|
||||||
|
{
|
||||||
|
// create the entity shared pointer
|
||||||
|
auto entity = std::shared_ptr<Entity>(new Entity(m_totalEntities++, tag));
|
||||||
|
m_entitiesToAdd.push_back(entity);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EntityVec & EntityManager::getEntities()
|
||||||
|
{
|
||||||
|
return m_entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EntityVec & EntityManager::getEntities(const std::string & tag)
|
||||||
|
{
|
||||||
|
return m_entityMap[tag];
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
typedef std::vector<std::shared_ptr<Entity>> EntityVec;
|
||||||
|
typedef std::map<std::string, EntityVec> EntityMap;
|
||||||
|
|
||||||
|
class EntityManager
|
||||||
|
{
|
||||||
|
EntityVec m_entities;
|
||||||
|
EntityVec m_entitiesToAdd;
|
||||||
|
EntityMap m_entityMap;
|
||||||
|
size_t m_totalEntities;
|
||||||
|
|
||||||
|
void removeDeadEntities(EntityVec & vec);
|
||||||
|
|
||||||
|
public:
|
||||||
|
EntityManager();
|
||||||
|
void update();
|
||||||
|
std::shared_ptr<Entity> addEntity(const std::string & tag);
|
||||||
|
const EntityVec & getEntities();
|
||||||
|
const EntityVec & getEntities(const std::string & tag);
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
#include "GameEngine.h"
|
||||||
|
#include "MenuScene.h"
|
||||||
|
//#include "UITestScene.h"
|
||||||
|
#include "ActionCode.h"
|
||||||
|
#include "McRFPy_API.h"
|
||||||
|
#include "PythonScene.h"
|
||||||
|
#include "UITestScene.h"
|
||||||
|
#include "Resources.h"
|
||||||
|
|
||||||
|
GameEngine::GameEngine()
|
||||||
|
{
|
||||||
|
Resources::font.loadFromFile("./assets/JetbrainsMono.ttf");
|
||||||
|
Resources::game = this;
|
||||||
|
window_title = "McRogueFace - r/RoguelikeDev Tutorial Run";
|
||||||
|
window.create(sf::VideoMode(1024, 768), window_title);
|
||||||
|
visible = window.getDefaultView();
|
||||||
|
window.setFramerateLimit(30);
|
||||||
|
scene = "uitest";
|
||||||
|
//std::cout << "Constructing MenuScene" << std::endl;
|
||||||
|
scenes["menu"] = new MenuScene(this);
|
||||||
|
scenes["uitest"] = new UITestScene(this);
|
||||||
|
|
||||||
|
//std::cout << "Constructed MenuScene" <<std::endl;
|
||||||
|
//scenes["play"] = new UITestScene(this);
|
||||||
|
//api = new McRFPy_API(this);
|
||||||
|
|
||||||
|
McRFPy_API::game = this;
|
||||||
|
McRFPy_API::api_init();
|
||||||
|
McRFPy_API::executePyString("import mcrfpy");
|
||||||
|
//McRFPy_API::executePyString("from UIMenu import *");
|
||||||
|
//McRFPy_API::executePyString("from Grid import *");
|
||||||
|
|
||||||
|
//scenes["py"] = new PythonScene(this, "TestScene");
|
||||||
|
|
||||||
|
IndexSprite::game = this;
|
||||||
|
|
||||||
|
clock.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene* GameEngine::currentScene() { return scenes[scene]; }
|
||||||
|
void GameEngine::changeScene(std::string s) { std::cout << "Current scene is now '" << s << "'\n"; scene = s; }
|
||||||
|
void GameEngine::quit() { running = false; }
|
||||||
|
void GameEngine::setPause(bool p) { paused = p; }
|
||||||
|
sf::Font & GameEngine::getFont() { /*return font; */ return Resources::font; }
|
||||||
|
sf::RenderWindow & GameEngine::getWindow() { return window; }
|
||||||
|
|
||||||
|
void GameEngine::run()
|
||||||
|
{
|
||||||
|
float fps = 0.0;
|
||||||
|
clock.restart();
|
||||||
|
while (running)
|
||||||
|
{
|
||||||
|
currentScene()->update();
|
||||||
|
sUserInput();
|
||||||
|
if (!paused)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
currentScene()->sRender();
|
||||||
|
currentFrame++;
|
||||||
|
frameTime = clock.restart().asSeconds();
|
||||||
|
fps = 1 / frameTime;
|
||||||
|
window.setTitle(window_title + " " + std::to_string(fps) + " FPS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameEngine::sUserInput()
|
||||||
|
{
|
||||||
|
sf::Event event;
|
||||||
|
while (window.pollEvent(event))
|
||||||
|
{
|
||||||
|
std::string actionType;
|
||||||
|
int actionCode = 0;
|
||||||
|
|
||||||
|
if (event.type == sf::Event::Closed) { running = false; continue; }
|
||||||
|
else if (event.type == sf::Event::Resized) {
|
||||||
|
sf::FloatRect area(0.f, 0.f, event.size.width, event.size.height);
|
||||||
|
visible = sf::View(area);
|
||||||
|
window.setView(visible);
|
||||||
|
//std::cout << "Visible area set to (0, 0, " << event.size.width << ", " << event.size.height <<")"<<std::endl;
|
||||||
|
actionType = "resize";
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (event.type == sf::Event::KeyPressed || event.type == sf::Event::MouseButtonPressed || event.type == sf::Event::MouseWheelScrolled) actionType = "start";
|
||||||
|
else if (event.type == sf::Event::KeyReleased || event.type == sf::Event::MouseButtonReleased) actionType = "end";
|
||||||
|
|
||||||
|
if (event.type == sf::Event::MouseButtonPressed || event.type == sf::Event::MouseButtonReleased)
|
||||||
|
actionCode = ActionCode::keycode(event.mouseButton.button);
|
||||||
|
else if (event.type == sf::Event::KeyPressed || event.type == sf::Event::KeyReleased)
|
||||||
|
actionCode = ActionCode::keycode(event.key.code);
|
||||||
|
else if (event.type == sf::Event::MouseWheelScrolled)
|
||||||
|
{
|
||||||
|
// //sf::Mouse::Wheel w = event.MouseWheelScrollEvent.wheel;
|
||||||
|
if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
|
||||||
|
{
|
||||||
|
int delta = 1;
|
||||||
|
if (event.mouseWheelScroll.delta < 0) delta = -1;
|
||||||
|
actionCode = ActionCode::keycode(event.mouseWheelScroll.wheel, delta );
|
||||||
|
/*
|
||||||
|
std::cout << "[GameEngine] Generated MouseWheel code w(" << (int)event.mouseWheelScroll.wheel << ") d(" << event.mouseWheelScroll.delta << ") D(" << delta << ") = " << actionCode << std::endl;
|
||||||
|
std::cout << " test decode: isMouseWheel=" << ActionCode::isMouseWheel(actionCode) << ", wheel=" << ActionCode::wheel(actionCode) << ", delta=" << ActionCode::delta(actionCode) << std::endl;
|
||||||
|
std::cout << " math test: actionCode && WHEEL_NEG -> " << (actionCode && ActionCode::WHEEL_NEG) << "; actionCode && WHEEL_DEL -> " << (actionCode && ActionCode::WHEEL_DEL) << ";" << std::endl;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
// float d = event.MouseWheelScrollEvent.delta;
|
||||||
|
// actionCode = ActionCode::keycode(0, d);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//std::cout << "Event produced action code " << actionCode << ": " << actionType << std::endl;
|
||||||
|
|
||||||
|
if (currentScene()->hasAction(actionCode))
|
||||||
|
{
|
||||||
|
std::string name = currentScene()->action(actionCode);
|
||||||
|
currentScene()->doAction(name, actionType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//std::cout << "[GameEngine] Action not registered for input: " << actionCode << ": " << actionType << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<std::vector<std::shared_ptr<UIDrawable>>> GameEngine::scene_ui(std::string target)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// facts about maps
|
||||||
|
// You just can't do this during scenes["new_menu"] being assigned.
|
||||||
|
std::cout << "Current scene is: " << scene << ". Searching for: " << target << ".\n";
|
||||||
|
std::cout << "scenes.size(): " << scenes.size() << std::endl;
|
||||||
|
std::cout << "scenes.count(target): " << scenes.count(target) << std::endl;
|
||||||
|
std::cout << "scenes.find(target): " << std::distance(scenes.begin(), scenes.find(target)) << std::endl;
|
||||||
|
std::cout << "iterators: " << std::distance(scenes.begin(), scenes.begin()) << " " <<
|
||||||
|
std::distance(scenes.begin(), scenes.end()) << std::endl;
|
||||||
|
std::cout << "scenes.contains(target): " << scenes.contains(target) << std::endl;
|
||||||
|
std::cout << "scenes[target]: " << (long)(scenes[target]) << std::endl;
|
||||||
|
*/
|
||||||
|
if (scenes.count(target) == 0) return NULL;
|
||||||
|
return scenes[target]->ui_elements;
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "EntityManager.h"
|
||||||
|
#include "Scene.h"
|
||||||
|
#include "McRFPy_API.h"
|
||||||
|
#include "IndexTexture.h"
|
||||||
|
|
||||||
|
class GameEngine
|
||||||
|
{
|
||||||
|
sf::RenderWindow window;
|
||||||
|
sf::Font font;
|
||||||
|
std::string scene;
|
||||||
|
std::map<std::string, Scene*> scenes;
|
||||||
|
bool running = true;
|
||||||
|
bool paused = false;
|
||||||
|
int currentFrame = 0;
|
||||||
|
sf::View visible;
|
||||||
|
sf::Clock clock;
|
||||||
|
float frameTime;
|
||||||
|
std::string window_title;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GameEngine();
|
||||||
|
Scene* currentScene();
|
||||||
|
void changeScene(std::string);
|
||||||
|
void quit();
|
||||||
|
void setPause(bool);
|
||||||
|
sf::Font & getFont();
|
||||||
|
sf::RenderWindow & getWindow();
|
||||||
|
void run();
|
||||||
|
void sUserInput();
|
||||||
|
int getFrame() { return currentFrame; }
|
||||||
|
float getFrameTime() { return frameTime; }
|
||||||
|
sf::View getView() { return visible; }
|
||||||
|
|
||||||
|
// global textures for scripts to access
|
||||||
|
std::vector<IndexTexture> textures;
|
||||||
|
|
||||||
|
// global audio storage
|
||||||
|
std::vector<sf::SoundBuffer> sfxbuffers;
|
||||||
|
sf::Music music;
|
||||||
|
sf::Sound sfx;
|
||||||
|
std::shared_ptr<std::vector<std::shared_ptr<UIDrawable>>> scene_ui(std::string scene);
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,340 @@
|
||||||
|
#include "Grid.h"
|
||||||
|
#include <cmath>
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
GridPoint::GridPoint():
|
||||||
|
color(0, 0, 0, 0), walkable(false), tilesprite(-1), transparent(false), visible(false), discovered(false), color_overlay(0,0,0,255), tile_overlay(-1), uisprite(-1)
|
||||||
|
{};
|
||||||
|
|
||||||
|
void Grid::setSprite(int ti)
|
||||||
|
{
|
||||||
|
int tx = ti % texture_width, ty = ti / texture_width;
|
||||||
|
sprite.setTextureRect(sf::IntRect(tx * grid_size, ty * grid_size, grid_size, grid_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
Grid::Grid(int gx, int gy, int gs, int _x, int _y, int _w, int _h):
|
||||||
|
grid_size(gs),
|
||||||
|
grid_x(gx), grid_y(gy),
|
||||||
|
zoom(1.0f), center_x((gx/2) * gs), center_y((gy/2) * gs),
|
||||||
|
texture_width(12), texture_height(11), visible(false)
|
||||||
|
{
|
||||||
|
//grid_size = gs;
|
||||||
|
//zoom = 1.0f;
|
||||||
|
//grid_x = gx;
|
||||||
|
//grid_y = gy;
|
||||||
|
tcodmap = new TCODMap(gx, gy);
|
||||||
|
points.resize(gx*gy);
|
||||||
|
box.setSize(sf::Vector2f(_w, _h));
|
||||||
|
box.setPosition(sf::Vector2f(_x, _y));
|
||||||
|
box.setFillColor(sf::Color(0,0,0,0));
|
||||||
|
|
||||||
|
renderTexture.create(_w, _h);
|
||||||
|
|
||||||
|
texture.loadFromFile("./assets/kenney_tinydungeon.png");
|
||||||
|
texture.setSmooth(false);
|
||||||
|
sprite.setTexture(texture);
|
||||||
|
|
||||||
|
//output.setSize(box.getSize());
|
||||||
|
output.setTextureRect(
|
||||||
|
sf::IntRect(0, 0,
|
||||||
|
box.getSize().x, box.getSize().y));
|
||||||
|
output.setPosition(box.getPosition());
|
||||||
|
// textures are upside-down inside renderTexture
|
||||||
|
output.setTexture(renderTexture.getTexture());
|
||||||
|
|
||||||
|
// Show one texture at a time
|
||||||
|
sprite.setTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Grid::refreshTCODmap() {
|
||||||
|
//int total = 0, walkable = 0, transparent = 0;
|
||||||
|
for (int x = 0; x < grid_x; x++) {
|
||||||
|
for (int y = 0; y < grid_y; y++) {
|
||||||
|
auto p = at(x, y);
|
||||||
|
//total++; if (p.walkable) walkable++; if (p.transparent) transparent++;
|
||||||
|
tcodmap->setProperties(x, y, p.transparent, p.walkable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//std::cout << "Map refreshed: " << total << " squares, " << walkable << "walkable, " << transparent << " transparent" << std::endl;
|
||||||
|
}
|
||||||
|
void Grid::refreshTCODsight(int x, int y) {
|
||||||
|
tcodmap->computeFov(x,y, 0, true, FOV_PERMISSIVE_8);
|
||||||
|
for (int x = 0; x < grid_x; x++) {
|
||||||
|
for (int y = 0; y < grid_y; y++) {
|
||||||
|
auto& p = at(x, y);
|
||||||
|
if (p.visible && !tcodmap->isInFov(x, y)) {
|
||||||
|
p.discovered = true;
|
||||||
|
p.visible = false;
|
||||||
|
} else if (!p.visible && tcodmap->isInFov(x,y)) {
|
||||||
|
p.discovered = true;
|
||||||
|
p.visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Grid::inBounds(int x, int y) {
|
||||||
|
return (x >= 0 && y >= 0 && x < grid_x && y < grid_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Grid::screenToGrid(int sx, int sy, int& gx, int& gy) {
|
||||||
|
|
||||||
|
float center_x_sq = center_x / grid_size;
|
||||||
|
float center_y_sq = center_y / grid_size;
|
||||||
|
|
||||||
|
float width_sq = box.getSize().x / (grid_size * zoom);
|
||||||
|
float height_sq = box.getSize().y / (grid_size * zoom);
|
||||||
|
float left_edge = center_x_sq - (width_sq / 2.0);
|
||||||
|
float right_edge = center_x_sq + (width_sq / 2.0);
|
||||||
|
float top_edge = center_y_sq - (height_sq / 2.0);
|
||||||
|
float bottom_edge = center_y_sq + (height_sq / 2.0);
|
||||||
|
|
||||||
|
float grid_px = zoom * grid_size;
|
||||||
|
//std::cout << "##############################" <<
|
||||||
|
// "\nscreen coord: (" << sx << ", " << sy << ")" << std::endl;
|
||||||
|
|
||||||
|
sx -= box.getPosition().x;
|
||||||
|
sy -= box.getPosition().y;
|
||||||
|
|
||||||
|
//std::cout << "box coord: (" << sx << ", " << sy << ")" << std::endl;
|
||||||
|
float mouse_x_sq = sx / grid_px;
|
||||||
|
float mouse_y_sq = sy / grid_px;
|
||||||
|
|
||||||
|
float ans_x = mouse_x_sq + left_edge;
|
||||||
|
float ans_y = mouse_y_sq + top_edge;
|
||||||
|
|
||||||
|
// compare integer method with this (mostly working) one
|
||||||
|
//int diff_realpixel_x = box.getSize().x / 2.0 - sx;
|
||||||
|
//int diff_realpixel_y = box.getSize().y / 2.0 - sy;
|
||||||
|
int left_spritepixels = center_x - (box.getSize().x / 2.0 / zoom);
|
||||||
|
int top_spritepixels = center_y - (box.getSize().y / 2.0 / zoom);
|
||||||
|
|
||||||
|
std::cout << "Float method got ans (" << ans_x << ", " << ans_y << ")"
|
||||||
|
<< std::endl << "Int method px (" << left_spritepixels + (sx/zoom) << ", " <<
|
||||||
|
top_spritepixels + (sy/zoom) << ")" << std::endl <<
|
||||||
|
"Int grid (" << (left_spritepixels + (sx/zoom) ) / grid_size <<
|
||||||
|
", " << (top_spritepixels + (sy/zoom)) / grid_size << ")" <<
|
||||||
|
|
||||||
|
std::endl;
|
||||||
|
|
||||||
|
// casting float turns -0.5 to 0; I want any negative coord to be OOB
|
||||||
|
if (ans_x < 0) ans_x = -1;
|
||||||
|
if (ans_y < 0) ans_y = -1;
|
||||||
|
|
||||||
|
gx = ans_x;
|
||||||
|
gy = ans_y;
|
||||||
|
/*
|
||||||
|
std::cout <<
|
||||||
|
"C: (" << center_x << ", " << center_y << ")" << std::endl <<
|
||||||
|
"W: " << width_sq << " H: " << height_sq << std::endl <<
|
||||||
|
"L: " << left_edge << " T: " << top_edge << std::endl <<
|
||||||
|
"R: " << right_edge << " B: " << bottom_edge << std::endl <<
|
||||||
|
"Grid Px: " << grid_px << "( zoom: " << zoom << ")" << std::endl <<
|
||||||
|
"answer: G(" << ans_x << ", " << ans_y << ")" << std::endl <<
|
||||||
|
"##############################" <<
|
||||||
|
std::endl;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void Grid::renderPxToGrid(int sx, int sy, int& gx, int& gy) {
|
||||||
|
// just like screen px coversion, but no offset by grid's position
|
||||||
|
float center_x_sq = center_x / grid_size;
|
||||||
|
float center_y_sq = center_y / grid_size;
|
||||||
|
|
||||||
|
float width_sq = box.getSize().x / (grid_size * zoom);
|
||||||
|
float height_sq = box.getSize().y / (grid_size * zoom);
|
||||||
|
|
||||||
|
int width_px = box.getSize().x / 2.0;
|
||||||
|
int height_px = box.getSize().y / 2.0;
|
||||||
|
|
||||||
|
float left_edge = center_x_sq - (width_sq / 2.0);
|
||||||
|
float top_edge = center_y_sq - (height_sq / 2.0);
|
||||||
|
|
||||||
|
float grid_px = zoom * grid_size;
|
||||||
|
float sx_sq = sx / grid_px;
|
||||||
|
float sy_sq = sy / grid_px;
|
||||||
|
|
||||||
|
float ans_x = sx_sq + left_edge;
|
||||||
|
float ans_y = sy_sq + top_edge;
|
||||||
|
|
||||||
|
if (ans_x < 0) ans_x = -1;
|
||||||
|
if (ans_y < 0) ans_y = -1;
|
||||||
|
|
||||||
|
gx = ans_x;
|
||||||
|
gy = ans_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Grid::integerGrid(float fx, float fy, int& gx, int& gy) {
|
||||||
|
if (fx < 0) fx -= 0.5;
|
||||||
|
if (fy < 0) fy -= 0.5;
|
||||||
|
gx = fx;
|
||||||
|
gy = fy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Grid::gridToRenderPx(int gx, int gy, int& sx, int& sy) {
|
||||||
|
// integer grid square (gx, gy) - what pixel (on rendertexture)
|
||||||
|
// should it's top left corner be at (the sprite's position)
|
||||||
|
|
||||||
|
// eff_gridsize = grid_size * zoom
|
||||||
|
// if center_x = 161, and grid_size is 16, that's 10 + 1/16 sprites
|
||||||
|
// center_x - (box.getSize().x / 2 / zoom) = left edge (in px)
|
||||||
|
// gx * eff_gridsize = pixel position without panning
|
||||||
|
// pixel_gx - left_edge = grid's render position
|
||||||
|
|
||||||
|
sx = (gx * grid_size * zoom) - (center_x - (box.getSize().x / 2.0 / zoom));
|
||||||
|
sy = (gy * grid_size * zoom) - (center_y - (box.getSize().y / 2.0 / zoom));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Grid::render(sf::RenderWindow & window)
|
||||||
|
{
|
||||||
|
renderTexture.clear();
|
||||||
|
//renderTexture.draw(box);
|
||||||
|
|
||||||
|
// sprites that are visible according to zoom, center_x, center_y, and box width
|
||||||
|
float center_x_sq = center_x / grid_size;
|
||||||
|
float center_y_sq = center_y / grid_size;
|
||||||
|
|
||||||
|
float width_sq = box.getSize().x / (grid_size * zoom);
|
||||||
|
float height_sq = box.getSize().y / (grid_size * zoom);
|
||||||
|
float left_edge = center_x_sq - (width_sq / 2.0);
|
||||||
|
//float right_edge = center_x_sq + (width_sq / 2.0);
|
||||||
|
float top_edge = center_y_sq - (height_sq / 2.0);
|
||||||
|
//float bottom_edge = center_y_sq + (height_sq / 2.0);
|
||||||
|
|
||||||
|
|
||||||
|
int left_spritepixels = center_x - (box.getSize().x / 2.0 / zoom);
|
||||||
|
int top_spritepixels = center_y - (box.getSize().y / 2.0 / zoom);
|
||||||
|
|
||||||
|
sprite.setScale(sf::Vector2f(zoom, zoom));
|
||||||
|
sf::RectangleShape r; // for colors and overlays
|
||||||
|
r.setSize(sf::Vector2f(grid_size * zoom, grid_size * zoom));
|
||||||
|
r.setOutlineThickness(0);
|
||||||
|
|
||||||
|
int x_limit = left_edge + width_sq + 2;
|
||||||
|
if (x_limit > grid_x) x_limit = grid_x;
|
||||||
|
|
||||||
|
int y_limit = top_edge + height_sq + 2;
|
||||||
|
if (y_limit > grid_y) y_limit = grid_y;
|
||||||
|
|
||||||
|
//for (float x = (left_edge >= 0 ? left_edge : 0);
|
||||||
|
for (int x = (left_edge - 1 >= 0 ? left_edge - 1 : 0);
|
||||||
|
x < x_limit; //x < view_width;
|
||||||
|
x+=1)
|
||||||
|
{
|
||||||
|
//for (float y = (top_edge >= 0 ? top_edge : 0);
|
||||||
|
for (int y = (top_edge - 1 >= 0 ? top_edge - 1 : 0);
|
||||||
|
y < y_limit; //y < view_height;
|
||||||
|
y+=1)
|
||||||
|
{
|
||||||
|
// Converting everything to integer pixels to avoid jitter
|
||||||
|
//auto pixel_pos = sf::Vector2f(
|
||||||
|
// (x - left_edge) * (zoom * grid_size),
|
||||||
|
// (y - top_edge) * (zoom * grid_size));
|
||||||
|
|
||||||
|
// This failed horribly:
|
||||||
|
//int gx, gy; integerGrid(x, y, gx, gy);
|
||||||
|
//int px_x, px_y; gridToRenderPx(gx, gy, px_x, px_y);
|
||||||
|
//auto pixel_pos = sf::Vector2f(px_x, px_y);
|
||||||
|
|
||||||
|
// this draws coherently, but the coordinates
|
||||||
|
// don't match up with the mouse cursor function
|
||||||
|
// jitter not eliminated
|
||||||
|
auto pixel_pos = sf::Vector2f(
|
||||||
|
(x*grid_size - left_spritepixels) * zoom,
|
||||||
|
(y*grid_size - top_spritepixels) * zoom );
|
||||||
|
|
||||||
|
auto gridpoint = at(std::floor(x), std::floor(y));
|
||||||
|
|
||||||
|
sprite.setPosition(pixel_pos);
|
||||||
|
|
||||||
|
r.setPosition(pixel_pos);
|
||||||
|
r.setFillColor(gridpoint.color);
|
||||||
|
renderTexture.draw(r);
|
||||||
|
|
||||||
|
// tilesprite
|
||||||
|
// if discovered but not visible, set opacity to 90%
|
||||||
|
// if not discovered... just don't draw it?
|
||||||
|
if (gridpoint.tilesprite != -1) {
|
||||||
|
setSprite(gridpoint.tilesprite);
|
||||||
|
renderTexture.draw(sprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto e : entities) {
|
||||||
|
auto drawent = e->cGrid->indexsprite.drawable();
|
||||||
|
drawent.setScale(zoom, zoom);
|
||||||
|
auto pixel_pos = sf::Vector2f(
|
||||||
|
(drawent.getPosition().x*grid_size - left_spritepixels) * zoom,
|
||||||
|
(drawent.getPosition().y*grid_size - top_spritepixels) * zoom );
|
||||||
|
drawent.setPosition(pixel_pos);
|
||||||
|
renderTexture.draw(drawent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop again and draw on top of entities
|
||||||
|
for (int x = (left_edge - 1 >= 0 ? left_edge - 1 : 0);
|
||||||
|
x < x_limit; //x < view_width;
|
||||||
|
x+=1)
|
||||||
|
{
|
||||||
|
//for (float y = (top_edge >= 0 ? top_edge : 0);
|
||||||
|
for (int y = (top_edge - 1 >= 0 ? top_edge - 1 : 0);
|
||||||
|
y < y_limit; //y < view_height;
|
||||||
|
y+=1)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto pixel_pos = sf::Vector2f(
|
||||||
|
(x*grid_size - left_spritepixels) * zoom,
|
||||||
|
(y*grid_size - top_spritepixels) * zoom );
|
||||||
|
|
||||||
|
auto gridpoint = at(std::floor(x), std::floor(y));
|
||||||
|
|
||||||
|
sprite.setPosition(pixel_pos);
|
||||||
|
|
||||||
|
r.setPosition(pixel_pos);
|
||||||
|
|
||||||
|
// visible & discovered layers for testing purposes
|
||||||
|
if (!gridpoint.discovered) {
|
||||||
|
r.setFillColor(sf::Color(16, 16, 20, 192)); // 255 opacity for actual blackout
|
||||||
|
renderTexture.draw(r);
|
||||||
|
} else if (!gridpoint.visible) {
|
||||||
|
r.setFillColor(sf::Color(32, 32, 40, 128));
|
||||||
|
renderTexture.draw(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
// overlay
|
||||||
|
|
||||||
|
// uisprite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// grid lines for testing & validation
|
||||||
|
/*
|
||||||
|
sf::Vertex line[] =
|
||||||
|
{
|
||||||
|
sf::Vertex(sf::Vector2f(0, 0), sf::Color::Red),
|
||||||
|
sf::Vertex(box.getSize(), sf::Color::Red),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
renderTexture.draw(line, 2, sf::Lines);
|
||||||
|
sf::Vertex lineb[] =
|
||||||
|
{
|
||||||
|
sf::Vertex(sf::Vector2f(0, box.getSize().y), sf::Color::Blue),
|
||||||
|
sf::Vertex(sf::Vector2f(box.getSize().x, 0), sf::Color::Blue),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
renderTexture.draw(lineb, 2, sf::Lines);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// render to window
|
||||||
|
renderTexture.display();
|
||||||
|
window.draw(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
GridPoint& Grid::at(int x, int y)
|
||||||
|
{
|
||||||
|
return points[y * grid_x + x];
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Common.h"
|
||||||
|
#include "libtcod.h"
|
||||||
|
|
||||||
|
//#include "Entity.h"
|
||||||
|
class Entity; // forward declare
|
||||||
|
|
||||||
|
class GridPoint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Layers: color, walkable, tilesprite, transparent, visible, discovered, overlay, uisprite
|
||||||
|
sf::Color color;
|
||||||
|
bool walkable;
|
||||||
|
int tilesprite;
|
||||||
|
bool transparent, visible, discovered;
|
||||||
|
sf::Color color_overlay;
|
||||||
|
int tile_overlay, uisprite;
|
||||||
|
GridPoint();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Grid
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
Grid();
|
||||||
|
sf::RectangleShape box; // view on window
|
||||||
|
bool visible;
|
||||||
|
sf::Texture texture;
|
||||||
|
sf::Sprite sprite, output;
|
||||||
|
sf::RenderTexture renderTexture;
|
||||||
|
TCODMap* tcodmap;
|
||||||
|
void setSprite(int);
|
||||||
|
const int texture_width, texture_height;
|
||||||
|
auto contains(sf::Vector2i p) { return box.getGlobalBounds().contains(p.x, p.y); }
|
||||||
|
|
||||||
|
Grid(int gx, int gy, int gs, int _x, int _y, int _w, int _h);
|
||||||
|
int grid_x, grid_y; // rectangle map size (integer - sprites)
|
||||||
|
int grid_size; // pixel size of 1 sprite
|
||||||
|
float zoom;
|
||||||
|
int center_x, center_y; // center in 1.0x Pixels
|
||||||
|
|
||||||
|
std::vector<GridPoint> points; // grid visible contents
|
||||||
|
std::vector<std::shared_ptr<Entity>> entities;
|
||||||
|
void render(sf::RenderWindow&); // draw to screen
|
||||||
|
GridPoint& at(int, int);
|
||||||
|
bool inBounds(int, int);
|
||||||
|
void screenToGrid(int, int, int&, int&);
|
||||||
|
|
||||||
|
void renderPxToGrid(int, int, int&, int&);
|
||||||
|
void gridToRenderPx(int, int, int&, int&);
|
||||||
|
void integerGrid(float, float, int&, int&);
|
||||||
|
|
||||||
|
void refreshTCODmap();
|
||||||
|
void refreshTCODsight(int, int);
|
||||||
|
TCODDijkstra *dijkstra; //= new TCODDijkstra(myMap);
|
||||||
|
};
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "IndexSprite.h"
|
||||||
|
#include "GameEngine.h"
|
||||||
|
|
||||||
|
//int texture_index, sprite_index, x, y;
|
||||||
|
|
||||||
|
GameEngine* IndexSprite::game;
|
||||||
|
|
||||||
|
sf::Sprite IndexSprite::drawable()
|
||||||
|
{
|
||||||
|
sf::Sprite s;
|
||||||
|
auto& tex = IndexSprite::game->textures[texture_index];
|
||||||
|
s.setTexture(tex.texture);
|
||||||
|
s.setScale(sf::Vector2f(scale, scale));
|
||||||
|
s.setPosition(sf::Vector2f(x, y));
|
||||||
|
//std::cout << "Drawable position: " << x << ", " << y << " -> " << s.getPosition().x << ", " << s.getPosition().y << std::endl;
|
||||||
|
s.setTextureRect(tex.spriteCoordinates(sprite_index));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexSprite::IndexSprite(int _ti, int _si, float _x, float _y, float _s):
|
||||||
|
texture_index(_ti), sprite_index(_si), x(_x), y(_y), scale(_s) {
|
||||||
|
//std::cout << "IndexSprite constructed with x, y " << _x << ", " << _y << std::endl;
|
||||||
|
//std::cout << " * Stored x, y " << x << ", " << y << std::endl;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Common.h"
|
||||||
|
class GameEngine; // forward declare
|
||||||
|
|
||||||
|
class IndexSprite {
|
||||||
|
public:
|
||||||
|
int texture_index, sprite_index;
|
||||||
|
float x, y;
|
||||||
|
float scale;
|
||||||
|
static GameEngine* game;
|
||||||
|
sf::Sprite drawable();
|
||||||
|
IndexSprite(int, int, float, float, float);
|
||||||
|
};
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "IndexTexture.h"
|
||||||
|
|
||||||
|
sf::IntRect IndexTexture::spriteCoordinates(int index) {
|
||||||
|
int tx = index % grid_width, ty = index / grid_width;
|
||||||
|
return sf::IntRect(tx * grid_size, ty * grid_size, grid_size, grid_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexTexture::IndexTexture (sf::Texture t, int gs, int gw, int gh):
|
||||||
|
grid_size(gs), grid_width(gw), grid_height(gh) {
|
||||||
|
texture = t;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Common.h"
|
||||||
|
class GameEngine; // forward declare
|
||||||
|
|
||||||
|
class IndexTexture {
|
||||||
|
public:
|
||||||
|
sf::Texture texture;
|
||||||
|
int grid_size, grid_width, grid_height;
|
||||||
|
static GameEngine* game;
|
||||||
|
sf::IntRect spriteCoordinates(int);
|
||||||
|
IndexTexture(sf::Texture, int, int, int);
|
||||||
|
};
|
|
@ -0,0 +1,162 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
//#include "EntityManager.h"
|
||||||
|
//#include "Scene.h"
|
||||||
|
//#include "GameEngine.h" // can't - need forward declaration
|
||||||
|
//#include "ActionCode.h"
|
||||||
|
#include "Python.h"
|
||||||
|
#include "UIMenu.h"
|
||||||
|
#include "Grid.h"
|
||||||
|
#include "IndexSprite.h"
|
||||||
|
#include "EntityManager.h"
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
// implementation required to link templates
|
||||||
|
#include "Animation.h"
|
||||||
|
|
||||||
|
class GameEngine; // forward declared (circular members)
|
||||||
|
|
||||||
|
class McRFPy_API
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static const int texture_size = 16, // w & h (pixels) of one sprite in the tex
|
||||||
|
texture_width = 12, texture_height = 11, // w & h sprite/frame count
|
||||||
|
texture_sprite_count = 11 * 12; // t_width * t_height, minus blanks?
|
||||||
|
|
||||||
|
// TODO: this is wrong, load resources @ GameEngineSprite sprite;
|
||||||
|
// sf::Texture texture;
|
||||||
|
|
||||||
|
//std::vector<PyMethodDef> mcrfpyMethodsVector;
|
||||||
|
//static PyObject* PyInit_mcrfpy();
|
||||||
|
|
||||||
|
McRFPy_API();
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline static sf::Sprite sprite;
|
||||||
|
inline static sf::Texture texture;
|
||||||
|
static void setSpriteTexture(int);
|
||||||
|
inline static GameEngine* game;
|
||||||
|
static void api_init();
|
||||||
|
static void api_shutdown();
|
||||||
|
// Python API functionality - use mcrfpy.* in scripts
|
||||||
|
static PyObject* _drawSprite(PyObject*, PyObject*);
|
||||||
|
static void REPL_device(FILE * fp, const char *filename);
|
||||||
|
static void REPL();
|
||||||
|
|
||||||
|
// Jank mode engage: let the API hold data for Python to hack on
|
||||||
|
static std::map<std::string, UIMenu*> menus;
|
||||||
|
static EntityManager entities; // this is also kinda good, entities not on the current grid can still act (like monsters following you through doors??)
|
||||||
|
static std::map<std::string, Grid*> grids;
|
||||||
|
static std::list<Animation*> animations;
|
||||||
|
static std::vector<sf::SoundBuffer> soundbuffers;
|
||||||
|
static sf::Music music;
|
||||||
|
static sf::Sound sfx;
|
||||||
|
|
||||||
|
static std::shared_ptr<Entity> player;
|
||||||
|
|
||||||
|
static std::map<std::string, PyObject*> callbacks;
|
||||||
|
|
||||||
|
// Jank Python Method Exposures
|
||||||
|
static PyObject* _createMenu(PyObject*, PyObject*); // creates a new menu object in McRFPy_API::menus
|
||||||
|
static PyObject* _listMenus(PyObject*, PyObject*);
|
||||||
|
static PyObject* _modMenu(PyObject*, PyObject*);
|
||||||
|
|
||||||
|
static PyObject* _createCaption(PyObject*, PyObject*); // calls menu.add_caption
|
||||||
|
static PyObject* _createButton(PyObject*, PyObject*);
|
||||||
|
static PyObject* _createTexture(PyObject*, PyObject*);
|
||||||
|
static PyObject* _listTextures(PyObject*, PyObject*);
|
||||||
|
static PyObject* _createSprite(PyObject*, PyObject*);
|
||||||
|
|
||||||
|
// use _listMenus, probably will not implement
|
||||||
|
//static PyObject* _listCaptions(PyObject*, PyObject*);
|
||||||
|
//static PyObject* _listButtons(PyObject*, PyObject*);
|
||||||
|
|
||||||
|
static PyObject* _createEntity(PyObject*, PyObject*);
|
||||||
|
//static PyObject* _listEntities(PyObject*, PyObject*);
|
||||||
|
|
||||||
|
static PyObject* _createGrid(PyObject*, PyObject*);
|
||||||
|
static PyObject* _listGrids(PyObject*, PyObject*);
|
||||||
|
static PyObject* _modGrid(PyObject*, PyObject*);
|
||||||
|
|
||||||
|
static PyObject* _createAnimation(PyObject*, PyObject*);
|
||||||
|
|
||||||
|
static PyObject* _registerPyAction(PyObject*, PyObject*);
|
||||||
|
static PyObject* _registerInputAction(PyObject*, PyObject*);
|
||||||
|
|
||||||
|
static PyObject* _createSoundBuffer(PyObject*, PyObject*);
|
||||||
|
static PyObject* _loadMusic(PyObject*, PyObject*);
|
||||||
|
static PyObject* _setMusicVolume(PyObject*, PyObject*);
|
||||||
|
static PyObject* _setSoundVolume(PyObject*, PyObject*);
|
||||||
|
static PyObject* _playSound(PyObject*, PyObject*);
|
||||||
|
static PyObject* _getMusicVolume(PyObject*, PyObject*);
|
||||||
|
static PyObject* _getSoundVolume(PyObject*, PyObject*);
|
||||||
|
|
||||||
|
// allow all player actions (items, menus, movement, combat)
|
||||||
|
static PyObject* _unlockPlayerInput(PyObject*, PyObject*);
|
||||||
|
// disallow player actions (animating enemy actions)
|
||||||
|
static PyObject* _lockPlayerInput(PyObject*, PyObject*);
|
||||||
|
// prompt C++/Grid Objects to callback with a target Entity or grid space
|
||||||
|
static PyObject* _requestGridTarget(PyObject*, PyObject*);
|
||||||
|
// string for labeling the map
|
||||||
|
static std::string active_grid;
|
||||||
|
static PyObject* _activeGrid(PyObject*, PyObject*);
|
||||||
|
static PyObject* _setActiveGrid(PyObject*, PyObject*);
|
||||||
|
// string for prompting input
|
||||||
|
static std::string input_mode;
|
||||||
|
static PyObject* _inputMode(PyObject*, PyObject*);
|
||||||
|
// turn cycle
|
||||||
|
static int turn_number;
|
||||||
|
static PyObject* _turnNumber(PyObject*, PyObject*);
|
||||||
|
static PyObject* _refreshFov(PyObject*, PyObject*);
|
||||||
|
static bool do_camfollow;
|
||||||
|
static void camFollow();
|
||||||
|
static PyObject* _camFollow(PyObject*, PyObject*);
|
||||||
|
|
||||||
|
static PyObject* _sceneUI(PyObject*, PyObject*);
|
||||||
|
|
||||||
|
// accept keyboard input from scene
|
||||||
|
static sf::Vector2i cursor_position;
|
||||||
|
static void player_input(int, int);
|
||||||
|
static void computerTurn();
|
||||||
|
static void playerTurn();
|
||||||
|
|
||||||
|
// Jank Functionality
|
||||||
|
static UIMenu* createMenu(int posx, int posy, int sizex, int sizey);
|
||||||
|
static void createCaption(std::string menukey, std::string text, int fontsize, sf::Color textcolor);
|
||||||
|
static void createButton(std::string menukey, int x, int y, int w, int h, sf::Color bgcolor, sf::Color textcolor, std::string caption, std::string action);
|
||||||
|
static void createSprite(std::string menukey, int ti, int si, float x, float y, float scale);
|
||||||
|
static int createTexture(std::string filename, int grid_size, int grid_width, int grid_height);
|
||||||
|
//static void playSound(const char * filename);
|
||||||
|
//static void playMusic(const char * filename);
|
||||||
|
|
||||||
|
static void doAction(std::string);
|
||||||
|
|
||||||
|
// McRFPy_API(GameEngine*);
|
||||||
|
|
||||||
|
// API functionality - use from C++ directly
|
||||||
|
|
||||||
|
//void spawnEntity(int tex_index, int grid_x, int grid_y, PyObject* script);
|
||||||
|
|
||||||
|
static void executeScript(std::string);
|
||||||
|
static void executePyString(std::string);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
static PyMethodDef mcrfpyMethods[] = {
|
||||||
|
{"drawSprite", McRFPy_API::_drawSprite, METH_VARARGS,
|
||||||
|
"Draw a sprite (index, x, y)"},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyModuleDef mcrfpyModule = {
|
||||||
|
PyModuleDef_HEAD_INIT, "mcrfpy", NULL, -1, mcrfpyMethods,
|
||||||
|
NULL, NULL, NULL, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
// Module initializer fn, passed to PyImport_AppendInittab
|
||||||
|
PyObject* PyInit_mcrfpy()
|
||||||
|
{
|
||||||
|
return PyModule_Create(&mcrfpyModule);
|
||||||
|
}
|
||||||
|
*/
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "MenuScene.h"
|
||||||
|
#include "ActionCode.h"
|
||||||
|
|
||||||
|
MenuScene::MenuScene(GameEngine* g) : Scene(g)
|
||||||
|
{
|
||||||
|
text.setFont(game->getFont());
|
||||||
|
text.setString("McRogueFace Engine - r/RoguelikeDev Tutorial 2023");
|
||||||
|
text.setCharacterSize(24);
|
||||||
|
//std::cout << "MenuScene Initialized. " << game << std::endl;
|
||||||
|
//std::cout << "Font: " << game->getFont().getInfo().family << std::endl;
|
||||||
|
|
||||||
|
text2.setFont(game->getFont());
|
||||||
|
text2.setString("Press 'Spacebar' to run demo");
|
||||||
|
text2.setCharacterSize(16);
|
||||||
|
text2.setPosition(0.0f, 50.0f);
|
||||||
|
|
||||||
|
text3.setFont(game->getFont());
|
||||||
|
text3.setString("use 'W' 'A' 'S' 'D' to move (even when blank; it's a bug)");
|
||||||
|
text3.setCharacterSize(16);
|
||||||
|
text3.setPosition(0.0f, 80.0f);
|
||||||
|
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Space, "start_game");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Up, "up");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Down, "down");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuScene::update()
|
||||||
|
{
|
||||||
|
//std::cout << "MenuScene update" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuScene::doAction(std::string name, std::string type)
|
||||||
|
{
|
||||||
|
//std::cout << "MenuScene doAction: " << name << ", " << type << std::endl;
|
||||||
|
//if (name.compare("start_game") == 0 and type.compare("start") == 0)
|
||||||
|
if(ACTION("start_game", "start"))
|
||||||
|
game->changeScene("py");
|
||||||
|
/*
|
||||||
|
else if(ACTIONONCE("up"))
|
||||||
|
game->getWindow().setSize(sf::Vector2u(1280, 800));
|
||||||
|
else if(ACTIONONCE("down"))
|
||||||
|
game->getWindow().setSize(sf::Vector2u(1024, 768));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuScene::sRender()
|
||||||
|
{
|
||||||
|
game->getWindow().clear();
|
||||||
|
game->getWindow().draw(text);
|
||||||
|
game->getWindow().draw(text2);
|
||||||
|
game->getWindow().draw(text3);
|
||||||
|
game->getWindow().display();
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Scene.h"
|
||||||
|
#include "GameEngine.h"
|
||||||
|
|
||||||
|
class MenuScene: public Scene
|
||||||
|
{
|
||||||
|
sf::Text text;
|
||||||
|
sf::Text text2;
|
||||||
|
sf::Text text3;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MenuScene(GameEngine*);
|
||||||
|
void update() override final;
|
||||||
|
void doAction(std::string, std::string) override final;
|
||||||
|
void sRender() override final;
|
||||||
|
};
|
|
@ -0,0 +1,269 @@
|
||||||
|
#include "PythonScene.h"
|
||||||
|
#include "ActionCode.h"
|
||||||
|
#include "McRFPy_API.h"
|
||||||
|
//#include "Animation.h"
|
||||||
|
|
||||||
|
PythonScene::PythonScene(GameEngine* g, std::string pymodule)
|
||||||
|
: Scene(g) {
|
||||||
|
// mouse events
|
||||||
|
registerAction(ActionCode::MOUSEBUTTON + sf::Mouse::Left, "click");
|
||||||
|
registerAction(ActionCode::MOUSEBUTTON + sf::Mouse::Right, "rclick");
|
||||||
|
registerAction(ActionCode::MOUSEWHEEL + ActionCode::WHEEL_DEL, "wheel_up");
|
||||||
|
registerAction(ActionCode::MOUSEWHEEL + ActionCode::WHEEL_NEG + ActionCode::WHEEL_DEL, "wheel_down");
|
||||||
|
|
||||||
|
// keyboard events
|
||||||
|
/*
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Q, "upleft");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::W, "up");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::E, "upright");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::A, "left");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::S, "down");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::D, "right");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Z, "downleft");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::X, "wait");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::C, "downright");
|
||||||
|
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad7, "upleft");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad8, "up");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad9, "upright");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad4, "left");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad5, "wait");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad6, "right");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad1, "downleft");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad2, "down");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad3, "downright");
|
||||||
|
*/
|
||||||
|
// window resize
|
||||||
|
registerAction(0, "event");
|
||||||
|
|
||||||
|
dragging = false;
|
||||||
|
drag_grid = NULL;
|
||||||
|
|
||||||
|
// import pymodule and call start()
|
||||||
|
McRFPy_API::executePyString("import " + pymodule);
|
||||||
|
McRFPy_API::executePyString(pymodule + ".start()");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::animate() {
|
||||||
|
//std::cout << "Number of animations: " << McRFPy_API::animations.size() << std::endl;
|
||||||
|
auto frametime = game->getFrameTime();
|
||||||
|
auto it = McRFPy_API::animations.begin();
|
||||||
|
while (it != McRFPy_API::animations.end()) {
|
||||||
|
//std::cout << "Iterating" << std::endl;
|
||||||
|
(*it)->step(frametime);
|
||||||
|
//std::cout << "Step complete" << std::endl;
|
||||||
|
if ((*it)->isDone()) {
|
||||||
|
//std::cout << "Cleaning up Animation" << std::endl;
|
||||||
|
auto prev = it;
|
||||||
|
it++;
|
||||||
|
McRFPy_API::animations.erase(prev);
|
||||||
|
} else it++;
|
||||||
|
}
|
||||||
|
/* // workin on it
|
||||||
|
for (auto p : animations) {
|
||||||
|
if (p.first == "int") {
|
||||||
|
((Animation<int>)p.second).step(frametime);
|
||||||
|
} else if (p.first == "string") {
|
||||||
|
((Animation<std::string>)p.second).step(frametime);
|
||||||
|
} else if (p.first == "float") {
|
||||||
|
((Animation<float>)p.second).step(frametime);
|
||||||
|
} else if (p.first == "vector2f") {
|
||||||
|
((Animation<sf::Vector2f>)p.second).step(frametime);
|
||||||
|
} else if (p.first == "vector2i") {
|
||||||
|
((Animation<sf::Vector2i>)p.second).step(frametime);
|
||||||
|
} else if (p.first == "color") {
|
||||||
|
((Animation<int>)p.second).step(frametime); // TODO
|
||||||
|
} else {
|
||||||
|
std::cout << "Animation has label " << p.first << "; no type found" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto it = animations.begin();
|
||||||
|
while (it != animations.end()) {
|
||||||
|
bool done = false;
|
||||||
|
if (p.first == "int") {
|
||||||
|
((Animation<int>)p.second).step(frametime);
|
||||||
|
} else if (p.first == "string") {
|
||||||
|
if ((Animation<std::string>)p.second).isDone()
|
||||||
|
delete (Animation<std::string>)p.second
|
||||||
|
} else if (p.first == "float") {
|
||||||
|
((Animation<float>)p.second).step(frametime);
|
||||||
|
} else if (p.first == "vector2f") {
|
||||||
|
((Animation<sf::Vector2f>)p.second).step(frametime);
|
||||||
|
} else if (p.first == "vector2i") {
|
||||||
|
((Animation<sf::Vector2i>)p.second).step(frametime);
|
||||||
|
} else if (p.first == "color") {
|
||||||
|
((Animation<int>)p.second).step(frametime); // TODO
|
||||||
|
if ((*it).second.isDone()) {
|
||||||
|
animations.erase(it++);
|
||||||
|
} else { it++; }
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::update() {
|
||||||
|
|
||||||
|
// turn cycle: If player's input made the state "computerturnwait", finish
|
||||||
|
// all animations and then let the NPCs act
|
||||||
|
if (McRFPy_API::animations.size() == 0 && McRFPy_API::input_mode.compare("computerturnwait") == 0) {
|
||||||
|
McRFPy_API::input_mode = "computerturn";
|
||||||
|
}
|
||||||
|
else if (McRFPy_API::animations.size() == 0 && McRFPy_API::input_mode.compare("computerturnrunning") == 0) {
|
||||||
|
McRFPy_API::input_mode = "playerturnstart";
|
||||||
|
}
|
||||||
|
McRFPy_API::entities.update();
|
||||||
|
|
||||||
|
// check if left click is still down & mouse has moved
|
||||||
|
// continue the drag motion
|
||||||
|
if (dragging && drag_grid) {
|
||||||
|
//std::cout << "Compute dragging" << std::endl;
|
||||||
|
auto mousepos = sf::Mouse::getPosition(game->getWindow());
|
||||||
|
auto dx = mouseprev.x - mousepos.x,
|
||||||
|
dy = mouseprev.y - mousepos.y;
|
||||||
|
if (dx != 0 || dy != 0) { McRFPy_API::do_camfollow = false; }
|
||||||
|
drag_grid->center_x += (dx / drag_grid->zoom);
|
||||||
|
drag_grid->center_y += (dy / drag_grid->zoom);
|
||||||
|
mouseprev = mousepos;
|
||||||
|
}
|
||||||
|
|
||||||
|
animate();
|
||||||
|
McRFPy_API::camFollow();
|
||||||
|
if (McRFPy_API::input_mode.compare(std::string("computerturn")) == 0) McRFPy_API::computerTurn();
|
||||||
|
if (McRFPy_API::input_mode.compare(std::string("playerturnstart")) == 0) McRFPy_API::playerTurn();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::doLClick(sf::Vector2i mousepos) {
|
||||||
|
// UI buttons get first chance
|
||||||
|
for (auto pair : McRFPy_API::menus) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
for (auto b : pair.second->buttons) {
|
||||||
|
//std::cout << "Box: " << pair.second->box.getPosition().x << ", "
|
||||||
|
//<< pair.second->box.getPosition().y << "; Button:" << b.rect.getPosition().x <<
|
||||||
|
//", " << b.rect.getPosition().y << "; Mouse: " << mousepos.x << ", " <<
|
||||||
|
//mousepos.y << std::endl;
|
||||||
|
|
||||||
|
// JANK: provide the button a relative coordinate.
|
||||||
|
if (b.contains(pair.second->box.getPosition(), mousepos)) {
|
||||||
|
McRFPy_API::doAction(b.getAction());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// left clicking a grid to select a square
|
||||||
|
for (auto pair : McRFPy_API::grids) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
if (pair.second->contains(mousepos)) {
|
||||||
|
// grid was clicked
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::doRClick(sf::Vector2i mousepos) {
|
||||||
|
// just grids for right click
|
||||||
|
for (auto pair : McRFPy_API::grids) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
if (pair.second->contains(mousepos)) {
|
||||||
|
// grid was clicked
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::doZoom(sf::Vector2i mousepos, int value) {
|
||||||
|
// just grids for right click
|
||||||
|
for (auto pair : McRFPy_API::grids) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
if (pair.second->contains(mousepos)) {
|
||||||
|
// grid was zoomed
|
||||||
|
float new_zoom = pair.second->zoom + (value * 0.25);
|
||||||
|
if (new_zoom >= 0.5 && new_zoom <= 5.0) {
|
||||||
|
pair.second->zoom = new_zoom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::doAction(std::string name, std::string type) {
|
||||||
|
auto mousepos = sf::Mouse::getPosition(game->getWindow());
|
||||||
|
//std::cout << "name: " << name << ", type: " << type << std::endl;
|
||||||
|
if (ACTIONPY) {
|
||||||
|
McRFPy_API::doAction(name.substr(0, name.size() - 3));
|
||||||
|
}
|
||||||
|
else if (ACTIONONCE("click")) {
|
||||||
|
// left click start
|
||||||
|
//std::cout << "LClick started at (" << mousepos.x << ", " << mousepos.y << ")" << std::endl;
|
||||||
|
dragstart = mousepos;
|
||||||
|
mouseprev = mousepos;
|
||||||
|
dragging = true;
|
||||||
|
|
||||||
|
// determine the grid that contains the cursor
|
||||||
|
for (auto pair : McRFPy_API::grids) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
if (pair.second->contains(mousepos)) {
|
||||||
|
// grid was clicked
|
||||||
|
drag_grid = pair.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ACTIONAFTER("click")) {
|
||||||
|
// left click end
|
||||||
|
//std::cout << "LClick ended at (" << mousepos.x << ", " << mousepos.y << ")" << std::endl;
|
||||||
|
// if click ended without starting a drag event, try lclick?
|
||||||
|
if (dragstart == mousepos) {
|
||||||
|
// mouse did not move, do click
|
||||||
|
//std::cout << "(did not move)" << std::endl;
|
||||||
|
doLClick(mousepos);
|
||||||
|
}
|
||||||
|
dragging = false;
|
||||||
|
drag_grid = NULL;
|
||||||
|
}
|
||||||
|
else if (ACTIONONCE("rclick")) {
|
||||||
|
// not going to test for right click drag - just rclick
|
||||||
|
doRClick(mousepos);
|
||||||
|
}
|
||||||
|
else if (ACTIONONCE("wheel_up")) {
|
||||||
|
// try zoom in
|
||||||
|
doZoom(mousepos, 1);
|
||||||
|
}
|
||||||
|
else if (ACTIONONCE("wheel_down")) {
|
||||||
|
// try zoom out
|
||||||
|
doZoom(mousepos, -1);
|
||||||
|
}
|
||||||
|
else if (ACTIONONCE("up")) { McRFPy_API::player_input(+0, -1); }
|
||||||
|
else if (ACTIONONCE("upright")) { McRFPy_API::player_input(+1, -1); }
|
||||||
|
else if (ACTIONONCE("right")) { McRFPy_API::player_input(+1, +0); }
|
||||||
|
else if (ACTIONONCE("downright")) { McRFPy_API::player_input(+1, +1); }
|
||||||
|
else if (ACTIONONCE("down")) { McRFPy_API::player_input(+0, +1); }
|
||||||
|
else if (ACTIONONCE("downleft")) { McRFPy_API::player_input(-1, +1); }
|
||||||
|
else if (ACTIONONCE("left")) { McRFPy_API::player_input(-1, +0); }
|
||||||
|
else if (ACTIONONCE("upleft")) { McRFPy_API::player_input(-1, -1); }
|
||||||
|
else if (ACTIONONCE("wait")) { McRFPy_API::player_input(+0, +0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PythonScene::registerActionInjected(int code, std::string name) {
|
||||||
|
std::cout << "Registering injected action (PythonScene): " << code << " (" << ActionCode::KEY + code << ")\n";
|
||||||
|
registerAction(ActionCode::KEY + code, name);
|
||||||
|
//return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PythonScene::unregisterActionInjected(int code, std::string name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::sRender() {
|
||||||
|
game->getWindow().clear();
|
||||||
|
|
||||||
|
for (auto pair: McRFPy_API::grids) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
pair.second->render(game->getWindow());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto pair: McRFPy_API::menus) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
pair.second->render(game->getWindow());
|
||||||
|
}
|
||||||
|
|
||||||
|
game->getWindow().display();
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Scene.h"
|
||||||
|
#include "GameEngine.h"
|
||||||
|
#include "Grid.h"
|
||||||
|
//#include "Animation.h"
|
||||||
|
//#include <list>
|
||||||
|
|
||||||
|
class PythonScene: public Scene
|
||||||
|
{
|
||||||
|
sf::Vector2i dragstart, mouseprev;
|
||||||
|
bool dragging;
|
||||||
|
Grid* drag_grid;
|
||||||
|
void doLClick(sf::Vector2i);
|
||||||
|
void doRClick(sf::Vector2i);
|
||||||
|
void doZoom(sf::Vector2i, int);
|
||||||
|
//std::list<Animation*> animations;
|
||||||
|
void animate();
|
||||||
|
std::map<std::string, bool> actionInjected;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PythonScene(GameEngine*, std::string);
|
||||||
|
void update() override final;
|
||||||
|
void doAction(std::string, std::string) override final;
|
||||||
|
void sRender() override final;
|
||||||
|
bool registerActionInjected(int, std::string) override;
|
||||||
|
bool unregisterActionInjected(int, std::string) override;
|
||||||
|
};
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "Resources.h"
|
||||||
|
#include <list>
|
||||||
|
#include "UI.h"
|
||||||
|
// Resources class members memory allocation
|
||||||
|
|
||||||
|
sf::Font Resources::font;
|
||||||
|
GameEngine* Resources::game;
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Common.h"
|
||||||
|
#include <list>
|
||||||
|
#include "UI.h"
|
||||||
|
|
||||||
|
class GameEngine; // forward declared
|
||||||
|
|
||||||
|
class Resources
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static sf::Font font;
|
||||||
|
static GameEngine* game;
|
||||||
|
};
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include "Scene.h"
|
||||||
|
#include "UI.h"
|
||||||
|
|
||||||
|
//Scene::Scene() { game = 0; std::cout << "WARN: default Scene constructor called. (game = " << game << ")" << std::endl;};
|
||||||
|
Scene::Scene(GameEngine* g)
|
||||||
|
{
|
||||||
|
game = g;
|
||||||
|
ui_elements = std::make_shared<std::vector<std::shared_ptr<UIDrawable>>>();
|
||||||
|
}
|
||||||
|
void Scene::registerAction(int code, std::string name)
|
||||||
|
{
|
||||||
|
actions[code] = name;
|
||||||
|
actionState[name] = false;
|
||||||
|
}
|
||||||
|
bool Scene::hasAction(std::string name)
|
||||||
|
{
|
||||||
|
for (auto& item : actions)
|
||||||
|
if (item.second == name) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scene::hasAction(int code)
|
||||||
|
{
|
||||||
|
return (actions.find(code) != actions.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Scene::action(int code)
|
||||||
|
{
|
||||||
|
return actions[code];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scene::registerActionInjected(int code, std::string name)
|
||||||
|
{
|
||||||
|
std::cout << "Inject registered action - default implementation\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scene::unregisterActionInjected(int code, std::string name)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// macros for scene input
|
||||||
|
#define ACTION(X, Y) (name.compare(X) == 0 && type.compare(Y) == 0)
|
||||||
|
#define ACTIONONCE(X) ((name.compare(X) == 0 && type.compare("start") == 0 && !actionState[name]))
|
||||||
|
#define ACTIONAFTER(X) ((name.compare(X) == 0 && type.compare("end") == 0))
|
||||||
|
#define ACTIONPY ((name.size() > 3 && name.compare(name.size() - 3, 3, "_py") == 0))
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include <list>
|
||||||
|
#include "UI.h"
|
||||||
|
//#include "GameEngine.h"
|
||||||
|
|
||||||
|
class GameEngine; // forward declare
|
||||||
|
|
||||||
|
class Scene
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
bool hasEnded = false;
|
||||||
|
bool paused = false;
|
||||||
|
std::map<int, std::string> actions;
|
||||||
|
std::map<std::string, bool> actionState;
|
||||||
|
GameEngine* game;
|
||||||
|
|
||||||
|
void simulate(int);
|
||||||
|
void registerAction(int, std::string);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
//Scene();
|
||||||
|
Scene(GameEngine*);
|
||||||
|
virtual void update() = 0;
|
||||||
|
virtual void sRender() = 0;
|
||||||
|
virtual void doAction(std::string, std::string) = 0;
|
||||||
|
bool hasAction(std::string);
|
||||||
|
bool hasAction(int);
|
||||||
|
std::string action(int);
|
||||||
|
|
||||||
|
virtual bool registerActionInjected(int, std::string);
|
||||||
|
virtual bool unregisterActionInjected(int, std::string);
|
||||||
|
|
||||||
|
std::shared_ptr<std::vector<std::shared_ptr<UIDrawable>>> ui_elements;
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,237 @@
|
||||||
|
#include "UI.h"
|
||||||
|
#include "Resources.h"
|
||||||
|
#include "GameEngine.h"
|
||||||
|
|
||||||
|
void UIDrawable::render()
|
||||||
|
{
|
||||||
|
//std::cout << "Rendering base UIDrawable\n";
|
||||||
|
render(sf::Vector2f());
|
||||||
|
}
|
||||||
|
UIFrame::UIFrame():
|
||||||
|
x(0), y(0), w(0), h(0), outline(0)
|
||||||
|
{
|
||||||
|
children = std::make_shared<std::vector<std::shared_ptr<UIDrawable>>>();
|
||||||
|
/*
|
||||||
|
pyOutlineColor = NULL;
|
||||||
|
pyFillColor = NULL;
|
||||||
|
_outlineColor = NULL;
|
||||||
|
_fillColor = NULL;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
UIFrame::UIFrame(float _x, float _y, float _w, float _h):
|
||||||
|
x(_x), y(_y), w(_w), h(_h), outline(0)
|
||||||
|
{
|
||||||
|
children = std::make_shared<std::vector<std::shared_ptr<UIDrawable>>>();
|
||||||
|
/*
|
||||||
|
pyOutlineColor = NULL;
|
||||||
|
pyFillColor = NULL;
|
||||||
|
_outlineColor = NULL;
|
||||||
|
_fillColor = NULL;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
UIFrame::~UIFrame()
|
||||||
|
{
|
||||||
|
children.reset();
|
||||||
|
/*
|
||||||
|
if (pyOutlineColor) Py_DECREF(pyOutlineColor);
|
||||||
|
else if (_outlineColor) delete _outlineColor;
|
||||||
|
if (pyFillColor) Py_DECREF(pyFillColor);
|
||||||
|
else if (_fillColor) delete _fillColor;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
sf::Color& fillColor(); // getter
|
||||||
|
void fillColor(sf::Color c); // C++ setter
|
||||||
|
void fillColor(PyObject* pyColor); // Python setter
|
||||||
|
|
||||||
|
sf::Color& outlineColor(); // getter
|
||||||
|
void outlineColor(sf::Color c); // C++ setter
|
||||||
|
void outlineColor(PyObject* pyColor); // Python setter
|
||||||
|
*/
|
||||||
|
|
||||||
|
PyObjectsEnum UIFrame::derived_type()
|
||||||
|
{
|
||||||
|
return PyObjectsEnum::UIFRAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIFrame::render(sf::Vector2f offset)
|
||||||
|
{
|
||||||
|
//std::cout << "Rendering UIFrame w/ offset " << offset.x << ", " << offset.y << "\n";
|
||||||
|
//std::cout << "position = " << x << ", " << y << "\n";
|
||||||
|
box.move(offset);
|
||||||
|
Resources::game->getWindow().draw(box);
|
||||||
|
box.move(-offset);
|
||||||
|
//sf::RectangleShape box = sf::RectangleShape(sf::Vector2f(w,h));
|
||||||
|
//sf::Vector2f pos = sf::Vector2f(x, y);
|
||||||
|
//box.setPosition(offset + pos);
|
||||||
|
//if (_fillColor) { box.setFillColor(fillColor()); }
|
||||||
|
//if (_outlineColor) { box.setOutlineColor(outlineColor()); }
|
||||||
|
//box.setOutlineThickness(outline);
|
||||||
|
//Resources::game->getWindow().draw(box);
|
||||||
|
for (auto drawable : *children) {
|
||||||
|
drawable->render(offset + box.getPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UICaption::render(sf::Vector2f offset)
|
||||||
|
{
|
||||||
|
//std::cout << "Rendering Caption with offset\n";
|
||||||
|
text.move(offset);
|
||||||
|
Resources::game->getWindow().draw(text);
|
||||||
|
text.move(-offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
UISprite::UISprite() {}
|
||||||
|
|
||||||
|
UISprite::UISprite(IndexTexture* _itex, int _sprite_index, float x = 0.0, float y = 0.0, float s = 1.0)
|
||||||
|
: itex(_itex), sprite_index(_sprite_index)
|
||||||
|
{
|
||||||
|
sprite.setTexture(_itex->texture);
|
||||||
|
sprite.setTextureRect(_itex->spriteCoordinates(_sprite_index));
|
||||||
|
sprite.setPosition(sf::Vector2f(x, y));
|
||||||
|
sprite.setScale(sf::Vector2f(s, s));
|
||||||
|
}
|
||||||
|
|
||||||
|
UISprite::UISprite(IndexTexture* _itex, int _sprite_index, sf::Vector2f pos, float s = 1.0)
|
||||||
|
: itex(_itex), sprite_index(_sprite_index)
|
||||||
|
{
|
||||||
|
sprite.setTexture(_itex->texture);
|
||||||
|
sprite.setTextureRect(_itex->spriteCoordinates(_sprite_index));
|
||||||
|
sprite.setPosition(pos);
|
||||||
|
sprite.setScale(sf::Vector2f(s, s));
|
||||||
|
}
|
||||||
|
|
||||||
|
//void UISprite::update()
|
||||||
|
//{
|
||||||
|
//auto& tex = Resources::game->textures[texture_index];
|
||||||
|
//sprite.setTexture(tex.texture);
|
||||||
|
//sprite.setScale(sf::Vector2f(scale, scale));
|
||||||
|
//sprite.setPosition(sf::Vector2f(x, y));
|
||||||
|
//std::cout << "Drawable position: " << x << ", " << y << " -> " << s.getPosition().x << ", " << s.getPosition().y << std::endl;
|
||||||
|
//sprite.setTextureRect(tex.spriteCoordinates(sprite_index));
|
||||||
|
//}
|
||||||
|
|
||||||
|
void UISprite::render(sf::Vector2f offset)
|
||||||
|
{
|
||||||
|
sprite.move(offset);
|
||||||
|
Resources::game->getWindow().draw(sprite);
|
||||||
|
sprite.move(-offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UISprite::setPosition(float x, float y)
|
||||||
|
{
|
||||||
|
setPosition(sf::Vector2f(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UISprite::setPosition(sf::Vector2f pos)
|
||||||
|
{
|
||||||
|
sprite.setPosition(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UISprite::setScale(float s)
|
||||||
|
{
|
||||||
|
sprite.setScale(sf::Vector2f(s, s));
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObjectsEnum UICaption::derived_type()
|
||||||
|
{
|
||||||
|
return PyObjectsEnum::UICAPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObjectsEnum UISprite::derived_type()
|
||||||
|
{
|
||||||
|
return PyObjectsEnum::UISPRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* DEFUNCT_py_instance(std::shared_ptr<UIDrawable> source)
|
||||||
|
{
|
||||||
|
// takes a UI drawable, calls its derived_type virtual function, and builds a Python object based on the return value.
|
||||||
|
using namespace mcrfpydef;
|
||||||
|
|
||||||
|
PyObject* newobj = NULL;
|
||||||
|
std::cout << "py_instance called\n";
|
||||||
|
switch (source->derived_type())
|
||||||
|
{
|
||||||
|
case PyObjectsEnum::UIFRAME:
|
||||||
|
{
|
||||||
|
std::cout << "UIFRAME case\n" << std::flush;
|
||||||
|
PyTypeObject* UIFrameType = &PyUIFrameType;
|
||||||
|
//std::cout << "tp_alloc\n" << std::flush;
|
||||||
|
//PyObject* _o = UIFrameType->tp_alloc(UIFrameType, 0);
|
||||||
|
//std::cout << "reinterpret_cast\n" << std::flush;
|
||||||
|
//auto o = reinterpret_cast<PyUICollectionObject*>(_o);
|
||||||
|
//PyUIFrameObject* o = (PyUIFrameObject*)PyObject_New(PyUIFrameObject, UIFrameType);
|
||||||
|
|
||||||
|
PyUIFrameObject* o = (PyUIFrameObject*)(UIFrameType->tp_alloc(UIFrameType, 0));
|
||||||
|
//PyUIFrameObject* o = PyObject_New(PyUIFrameObject, UIFrameType);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// backtracking the problem: instantiate a PyColor of (255, 0, 0) for testing
|
||||||
|
PyTypeObject* colorType = &PyColorType;
|
||||||
|
PyObject* pyColor = colorType->tp_alloc(colorType, 0);
|
||||||
|
if (pyColor == NULL)
|
||||||
|
{
|
||||||
|
std::cout << "failure to allocate mcrfpy.Color / PyColorType" << std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyColorObject* pyColorObj = reinterpret_cast<PyColorObject*>(pyColor);
|
||||||
|
pyColorObj->data = std::make_shared<sf::Color>();
|
||||||
|
pyColorObj->data-> r = 255;
|
||||||
|
return (PyObject*)pyColorObj;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "pointer check: " << o << "\n" << std::flush;
|
||||||
|
if (o)
|
||||||
|
{
|
||||||
|
std::cout << "Casting data...\n" << std::flush;
|
||||||
|
auto p = std::static_pointer_cast<UIFrame>(source);
|
||||||
|
std::cout << "casted. Assigning...\n" << std::flush;
|
||||||
|
//o->data = std::make_shared<UIFrame>();
|
||||||
|
|
||||||
|
o->data = p;
|
||||||
|
//std::cout << "assigned.\n" << std::flush;
|
||||||
|
auto usource = o->data; //(UIFrame*)source.get();
|
||||||
|
std::cout << "Loaded data into object. " << usource->box.getPosition().x << " " << usource->box.getPosition().y << " " <<
|
||||||
|
usource->box.getSize().x << " " << usource->box.getSize().y << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Allocation failed.\n" << std::flush;
|
||||||
|
}
|
||||||
|
newobj = (PyObject*)o;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
case PyObjectsEnum::UICAPTION:
|
||||||
|
{
|
||||||
|
std::cout << "UICAPTION case\n";
|
||||||
|
PyErr_SetString(PyExc_NotImplementedError, "UICaption class not implemented in Python yet.");
|
||||||
|
/* not yet implemented
|
||||||
|
PyUICaptionObject* o = (PyUICaptionObject*)PyUICaptionType.tp_alloc(&PyUICaptionType, 0);
|
||||||
|
if (o)
|
||||||
|
o->data = std::static_pointer_cast<UICaption>(source);
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PyObjectsEnum::UISPRITE:
|
||||||
|
{
|
||||||
|
std::cout << "UISPRITE case\n";
|
||||||
|
PyErr_SetString(PyExc_NotImplementedError, "UISprite class not implemented in Python yet.");
|
||||||
|
/*
|
||||||
|
PyUISpriteObject* o = (PyUISpriteObject*)PyUISpriteType.tp_alloc(&PyUISpriteType, 0);
|
||||||
|
if (o)
|
||||||
|
o->data = std::static_pointer_cast<UISprite>(source);
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newobj;
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
#include "UIMenu.h"
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Resources.h"
|
||||||
|
|
||||||
|
UIMenu::UIMenu(sf::Font & _font)
|
||||||
|
: font(_font)
|
||||||
|
{
|
||||||
|
//font = _font;
|
||||||
|
box.setSize(sf::Vector2f(300, 400));
|
||||||
|
box.setPosition(sf::Vector2f(300, 250));
|
||||||
|
box.setFillColor(sf::Color(0,0,255));
|
||||||
|
}
|
||||||
|
|
||||||
|
UIMenu::UIMenu()
|
||||||
|
: font(Resources::font)
|
||||||
|
{
|
||||||
|
box.setSize(sf::Vector2f(300, 400));
|
||||||
|
box.setPosition(sf::Vector2f(300, 250));
|
||||||
|
box.setFillColor(sf::Color(0,0,255));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMenu::render(sf::RenderWindow & window)
|
||||||
|
{
|
||||||
|
window.draw(box);
|
||||||
|
for (auto& s: sprites) {
|
||||||
|
auto _s = s.drawable();
|
||||||
|
//std::cout << "Sprite has values " << s.x << ", " << s.y << std::endl;
|
||||||
|
//std::cout << "Drawable generated @ " << _s.getPosition().x << ", " << _s.getPosition().y << std::endl;
|
||||||
|
_s.move(box.getPosition());
|
||||||
|
//std::cout << "Moved by " << box.getPosition().x << ", " << box.getPosition().y << std::endl;
|
||||||
|
//std::cout << "Render UIMenu Sprite @ " << _s.getPosition().x << ", " << _s.getPosition().y << std::endl;
|
||||||
|
window.draw(_s);
|
||||||
|
}
|
||||||
|
for (auto& c : captions) {
|
||||||
|
//auto s = std::string(c.getString());
|
||||||
|
//std::cout << s << std::flush << std::endl;
|
||||||
|
c.move(box.getPosition());
|
||||||
|
window.draw(c);
|
||||||
|
c.move(-box.getPosition());
|
||||||
|
}
|
||||||
|
for (auto& b : buttons) {
|
||||||
|
//b.render(window);
|
||||||
|
b.setPosition(box.getPosition() + b.rect.getPosition());
|
||||||
|
//b.caption.setPosition(box.getPosition() + b.caption.getPosition());
|
||||||
|
b.render(window);
|
||||||
|
b.setPosition(b.rect.getPosition() - box.getPosition());
|
||||||
|
//b.caption.setPosition(b.caption.getPosition() - box.getPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMenu::refresh()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMenu::add_caption(const char* text, int tsize, sf::Color color)
|
||||||
|
{
|
||||||
|
auto c = sf::Text();
|
||||||
|
//auto bpos = box.getPosition();
|
||||||
|
|
||||||
|
c.setFillColor(color);
|
||||||
|
c.setPosition(10, next_text);
|
||||||
|
next_text += 50;
|
||||||
|
c.setCharacterSize(tsize);
|
||||||
|
c.setString(text);
|
||||||
|
c.setFont(font);
|
||||||
|
captions.push_back(c);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMenu::add_button(Button b)
|
||||||
|
{
|
||||||
|
b.setPosition(sf::Vector2f(box.getSize().x / 2.0f, next_button));
|
||||||
|
next_button += 50;
|
||||||
|
buttons.push_back(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMenu::add_sprite(IndexSprite s)
|
||||||
|
{
|
||||||
|
//std::cout << "Adding sprite to UIMenu x,y " << s.x << ", " << s.y << std::endl;
|
||||||
|
sprites.push_back(s);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Button.h"
|
||||||
|
#include "IndexSprite.h"
|
||||||
|
|
||||||
|
class UIMenu
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//UIMenu() {};
|
||||||
|
sf::Font & font;
|
||||||
|
UIMenu(sf::Font & _font);
|
||||||
|
UIMenu();
|
||||||
|
std::vector<sf::Text> captions;
|
||||||
|
std::vector<Button> buttons;
|
||||||
|
std::vector<IndexSprite> sprites;
|
||||||
|
|
||||||
|
/* idea: */ //std::vector<UIDrawable> children; // on the UIBox class?
|
||||||
|
|
||||||
|
sf::RectangleShape box;
|
||||||
|
bool visible = false;
|
||||||
|
int next_text = 10;
|
||||||
|
int next_button = 10;
|
||||||
|
|
||||||
|
void render(sf::RenderWindow & window);
|
||||||
|
void refresh();
|
||||||
|
void add_caption(const char* text, int size, sf::Color color);
|
||||||
|
void add_button(Button b);
|
||||||
|
void add_sprite(IndexSprite s);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,149 @@
|
||||||
|
#include "UITestScene.h"
|
||||||
|
#include "ActionCode.h"
|
||||||
|
#include "Resources.h"
|
||||||
|
|
||||||
|
UITestScene::UITestScene(GameEngine* g) : Scene(g)
|
||||||
|
{
|
||||||
|
text.setFont(game->getFont());
|
||||||
|
text.setString("Test Scene for UI elements");
|
||||||
|
text.setCharacterSize(24);
|
||||||
|
|
||||||
|
|
||||||
|
//registerAction(ActionCode::KEY + sf::Keyboard::Space, "start_game");
|
||||||
|
//registerAction(ActionCode::KEY + sf::Keyboard::Up, "up");
|
||||||
|
//registerAction(ActionCode::KEY + sf::Keyboard::Down, "down");
|
||||||
|
|
||||||
|
// note - you can't use the pointer to UI elements in constructor.
|
||||||
|
// The scene map is still being assigned to, so this object can't be looked up.
|
||||||
|
/*
|
||||||
|
auto ui = Resources::game->scene_ui("uitest");
|
||||||
|
if (ui)
|
||||||
|
{
|
||||||
|
std::cout << "Got back a UI vector from Resources::game.\n";
|
||||||
|
} else {
|
||||||
|
std::cout << "No UI vector was returned.\n";
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Create a UI element or three?
|
||||||
|
auto e1 = std::make_shared<UIFrame>(100,150,400,400);
|
||||||
|
e1->box.setPosition(100, 150);
|
||||||
|
e1->box.setSize(sf::Vector2f(400,400));
|
||||||
|
e1->box.setFillColor(sf::Color(255, 0, 0));
|
||||||
|
//e1.fillColor(sf::Color(255,0,0));
|
||||||
|
//if (ui) ui->push_back(e1);
|
||||||
|
ui_elements->push_back(e1);
|
||||||
|
|
||||||
|
auto e1a = std::make_shared<UIFrame>(50,50,200,200);
|
||||||
|
e1a->box.setPosition(50, 50);
|
||||||
|
e1a->box.setSize(sf::Vector2f(200,200));
|
||||||
|
e1a->box.setFillColor(sf::Color(0, 255, 0));
|
||||||
|
//e1a.fillColor(sf::Color(0, 255, 0));
|
||||||
|
e1->children->push_back(e1a);
|
||||||
|
|
||||||
|
auto e1aa = std::make_shared<UIFrame>(5,5,100,100);
|
||||||
|
e1aa->box.setPosition(5, 5);
|
||||||
|
e1aa->box.setSize(sf::Vector2f(100,100));
|
||||||
|
e1aa->box.setFillColor(sf::Color(0, 0, 255));
|
||||||
|
//e1aa.fillColor(sf::Color(0, 0, 255));
|
||||||
|
e1a->children->push_back(e1aa);
|
||||||
|
|
||||||
|
auto e2 = std::make_shared<UICaption>();
|
||||||
|
e2->text.setFont(game->getFont());
|
||||||
|
e2->text.setString("Hello World.");
|
||||||
|
//e2.text.setColor(sf::Color(255, 255, 255));
|
||||||
|
e2->text.setPosition(50, 250);
|
||||||
|
|
||||||
|
//if (ui) ui->push_back(e2);
|
||||||
|
ui_elements->push_back(e2);
|
||||||
|
//ui_elements.push_back(&e1);
|
||||||
|
//ui_elements.push_back(&e2);
|
||||||
|
|
||||||
|
t.loadFromFile("./assets/kenney_tinydungeon.png");
|
||||||
|
t.setSmooth(false);
|
||||||
|
auto* indextex = new IndexTexture(t, 16, 12, 11);
|
||||||
|
Resources::game->textures.push_back(*indextex);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//std::cout << Resources::game->textures.size() << " textures loaded.\n";
|
||||||
|
auto e3 = std::make_shared<UISprite>();
|
||||||
|
|
||||||
|
// Make UISprite more like IndexSprite: this is bad
|
||||||
|
//e3->x = 10; e3->y = 10;
|
||||||
|
//e3->texture_index = 0;
|
||||||
|
//e3->sprite_index = 84;
|
||||||
|
//e3->scale = 4.0f;
|
||||||
|
//e3->update();
|
||||||
|
|
||||||
|
// This goes to show how inconvenient the default constructor is. It should be removed
|
||||||
|
e3->itex = &Resources::game->textures[0];
|
||||||
|
e3->sprite.setTexture(e3->itex->texture);
|
||||||
|
e3->sprite_index = 84;
|
||||||
|
e3->sprite.setTextureRect(e3->itex->spriteCoordinates(e3->sprite_index));
|
||||||
|
e3->setPosition(10, 10);
|
||||||
|
e3->setScale(4.0f);
|
||||||
|
|
||||||
|
e1aa->children->push_back(e3);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
auto e4 = std::make_shared<UISprite>(
|
||||||
|
indextex, //&Resources::game->textures[0],
|
||||||
|
85, sf::Vector2f(90, 10), 4.0);
|
||||||
|
e1aa->children->push_back(e4);
|
||||||
|
//std::cout << "UISprite built: " << e4->sprite.getPosition().x << " " << e4->sprite.getPosition().y << " " << e4->sprite.getScale().x << " " <<
|
||||||
|
// e4->sprite_index << " " << std::endl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// note - you can't use the pointer to UI elements in constructor.
|
||||||
|
// The scene map is still being assigned to, so this object can't be looked up.
|
||||||
|
if (ui)
|
||||||
|
std::cout << "pointer to ui_elements now shows size=" << ui->size() << std::endl;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestScene::update()
|
||||||
|
{
|
||||||
|
//std::cout << "MenuScene update" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestScene::doAction(std::string name, std::string type)
|
||||||
|
{
|
||||||
|
//std::cout << "MenuScene doAction: " << name << ", " << type << std::endl;
|
||||||
|
//if (name.compare("start_game") == 0 and type.compare("start") == 0)
|
||||||
|
if(ACTION("start_game", "start"))
|
||||||
|
game->changeScene("py");
|
||||||
|
/*
|
||||||
|
else if(ACTIONONCE("up"))
|
||||||
|
game->getWindow().setSize(sf::Vector2u(1280, 800));
|
||||||
|
else if(ACTIONONCE("down"))
|
||||||
|
game->getWindow().setSize(sf::Vector2u(1024, 768));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestScene::sRender()
|
||||||
|
{
|
||||||
|
game->getWindow().clear();
|
||||||
|
game->getWindow().draw(text);
|
||||||
|
|
||||||
|
// draw all UI elements
|
||||||
|
//for (auto e: ui_elements)
|
||||||
|
//auto ui = Resources::game->scene_ui("uitest");
|
||||||
|
//if (ui)
|
||||||
|
auto vec = *ui_elements;
|
||||||
|
for (auto e: vec)
|
||||||
|
{
|
||||||
|
//std::cout << "Rendering element\n";
|
||||||
|
if (e)
|
||||||
|
e->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
//e1.render(sf::Vector2f(0, 0));
|
||||||
|
|
||||||
|
//e1.render(sf::Vector2f(-100, -100));
|
||||||
|
|
||||||
|
game->getWindow().display();
|
||||||
|
|
||||||
|
McRFPy_API::REPL();
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Scene.h"
|
||||||
|
#include "GameEngine.h"
|
||||||
|
//#include <list>
|
||||||
|
//#include "UI.h"
|
||||||
|
|
||||||
|
class UITestScene: public Scene
|
||||||
|
{
|
||||||
|
sf::Text text;
|
||||||
|
//UIFrame e1, e1a, e1aa;
|
||||||
|
//UICaption e2;
|
||||||
|
//std::vector<UIDrawable*> ui_elements;
|
||||||
|
sf::Texture t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UITestScene(GameEngine*);
|
||||||
|
void update() override final;
|
||||||
|
void doAction(std::string, std::string) override final;
|
||||||
|
void sRender() override final;
|
||||||
|
};
|
|
@ -1,292 +0,0 @@
|
||||||
// Python script engine includes
|
|
||||||
#include <Python.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// wstring<->string conversion
|
|
||||||
#include <locale>
|
|
||||||
#include <codecvt>
|
|
||||||
|
|
||||||
// SFML
|
|
||||||
#include <SFML/Graphics.hpp>
|
|
||||||
#include <SFML/Audio.hpp>
|
|
||||||
|
|
||||||
sf::RenderWindow window;
|
|
||||||
sf::Font font;
|
|
||||||
sf::Text text;
|
|
||||||
|
|
||||||
// TCOD
|
|
||||||
#include <libtcod.hpp>
|
|
||||||
|
|
||||||
#include "platform.h"
|
|
||||||
|
|
||||||
|
|
||||||
std::string narrow_string(std::wstring convertme)
|
|
||||||
{
|
|
||||||
//setup converter
|
|
||||||
using convert_type = std::codecvt_utf8<wchar_t>;
|
|
||||||
std::wstring_convert<convert_type, wchar_t> converter;
|
|
||||||
|
|
||||||
//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
|
|
||||||
return converter.to_bytes(convertme);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fexists(std::string filename)
|
|
||||||
{
|
|
||||||
return std::filesystem::exists(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
// init_python - configure interpreter details here
|
|
||||||
PyStatus init_python(const char *program_name)
|
|
||||||
{
|
|
||||||
std::cout << "called init_python" << std::endl;
|
|
||||||
PyStatus status;
|
|
||||||
|
|
||||||
//**preconfig to establish locale**
|
|
||||||
PyPreConfig preconfig;
|
|
||||||
PyPreConfig_InitIsolatedConfig(&preconfig);
|
|
||||||
|
|
||||||
preconfig.utf8_mode = 1;
|
|
||||||
|
|
||||||
status = Py_PreInitialize(&preconfig);
|
|
||||||
if (PyStatus_Exception(status)) {
|
|
||||||
Py_ExitStatusException(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyConfig config;
|
|
||||||
PyConfig_InitIsolatedConfig(&config);
|
|
||||||
config.dev_mode = 1;
|
|
||||||
|
|
||||||
|
|
||||||
PyConfig_SetBytesString(&config, &config.home,
|
|
||||||
narrow_string(executable_path() + L"/Python311").c_str());
|
|
||||||
std::cout << "config.home: "; std::wcout << config.home << std::endl;
|
|
||||||
|
|
||||||
/* Set the program name before reading the configuration
|
|
||||||
(decode byte string from the locale encoding).
|
|
||||||
|
|
||||||
Implicitly preinitialize Python. */
|
|
||||||
|
|
||||||
// windows can't name the Python interpreter...?
|
|
||||||
status = PyConfig_SetBytesString(&config, &config.program_name,
|
|
||||||
program_name);
|
|
||||||
|
|
||||||
// under Windows, the search paths are correct; under Linux, they need manual insertion
|
|
||||||
#if __PLATFORM_SET_PYTHON_SEARCH_PATHS == 1
|
|
||||||
config.module_search_paths_set = 1;
|
|
||||||
|
|
||||||
// search paths for python libs/modules/scripts
|
|
||||||
const wchar_t* str_arr[] = {
|
|
||||||
L"/scripts",
|
|
||||||
L"/Python311/lib.linux-x86_64-3.11",
|
|
||||||
L"/Python311",
|
|
||||||
L"/Python311/Lib",
|
|
||||||
L"/venv/lib/python3.11/site-packages"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
for(auto s : str_arr) {
|
|
||||||
status = PyWideStringList_Append(&config.module_search_paths, (executable_path() + s).c_str());
|
|
||||||
std::wcout << "`" << s
|
|
||||||
<< "` transformed to `" << (executable_path() + s).c_str()
|
|
||||||
<< "` and got status error (`" << PyStatus_IsError(status) << "`)" << std::endl;
|
|
||||||
|
|
||||||
if (PyStatus_Exception(status)) {
|
|
||||||
std::wcout << "Exception handling " << s << std::endl << std::flush;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
status = Py_InitializeFromConfig(&config);
|
|
||||||
std::cout << "Python Initialized" << std::endl;
|
|
||||||
|
|
||||||
done:
|
|
||||||
//PyConfig_Clear(&config);
|
|
||||||
//free(python_home_ptr);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// C++ example functionality
|
|
||||||
int recurse_fib(int i)
|
|
||||||
{
|
|
||||||
if (i <= 1) return 1;
|
|
||||||
return recurse_fib(i-1) + recurse_fib(i-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a python module to expose C++ functionality
|
|
||||||
static PyObject* scriptable_fibonacci(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
// get input (single integer) from args
|
|
||||||
if (!PyArg_ParseTuple(args, "i", &x)) return NULL;
|
|
||||||
return PyLong_FromLong(recurse_fib(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyMethodDef scriptableMethods[] = {
|
|
||||||
{"fibonacci", scriptable_fibonacci, METH_VARARGS,
|
|
||||||
"Fibonacci sequence by index"},
|
|
||||||
{NULL, NULL, 0, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyModuleDef scriptableModule = {
|
|
||||||
PyModuleDef_HEAD_INIT, "scriptable", NULL, -1, scriptableMethods,
|
|
||||||
NULL, NULL, NULL, NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyObject* PyInit_scriptable(void)
|
|
||||||
{
|
|
||||||
return PyModule_Create(&scriptableModule);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char ** argv)
|
|
||||||
{
|
|
||||||
std::cout << "Output." << std::endl;
|
|
||||||
std::wcout << "Current executable path: " << executable_path()
|
|
||||||
<< "\nCurrent working directory: " << working_path() << std::endl;
|
|
||||||
|
|
||||||
std::cout << "[C++] Initializing Python\n";
|
|
||||||
//setenv("PYTHONHOME", "./Python-3.11.1", 0);
|
|
||||||
//Express this program as a module before pyinit
|
|
||||||
PyImport_AppendInittab("scriptable", &PyInit_scriptable);
|
|
||||||
//Initialize the python instance
|
|
||||||
|
|
||||||
//Py_SetPythonHome is deprecated
|
|
||||||
//Py_SetPythonHome(L"./lib/python-dist");
|
|
||||||
|
|
||||||
std::cout << "Output. (2)" << std::endl;
|
|
||||||
PyStatus status = init_python(argv[0]);
|
|
||||||
std::cout << "Output. (3)" << std::endl;
|
|
||||||
|
|
||||||
std::cout << "***\n[C++] Executing some Python\n***\n";
|
|
||||||
int result = PyRun_SimpleString("import sys,datetime\n"
|
|
||||||
"print('test\\n', datetime.__file__)\n");
|
|
||||||
std::cout << "\n***\n[C++] Execution Complete\nResult = " << result << std::endl;
|
|
||||||
|
|
||||||
std::cout << "On to other modules..." << std::endl;
|
|
||||||
|
|
||||||
//Py_Initialize();
|
|
||||||
|
|
||||||
|
|
||||||
std::string asset_path = narrow_string(executable_path()) + "/assets";
|
|
||||||
std::string script_path = narrow_string(executable_path()) + "/scripts";
|
|
||||||
|
|
||||||
// SFML demo setup
|
|
||||||
//font.loadFromFile("./assets/JetbrainsMono.ttf");
|
|
||||||
font.loadFromFile(asset_path + "/JetbrainsMono.ttf");
|
|
||||||
window.create(sf::VideoMode(640, 480), "Python/SFML/TCOD test");
|
|
||||||
|
|
||||||
|
|
||||||
// TCOD demo setup
|
|
||||||
|
|
||||||
//Run a simple string
|
|
||||||
PyRun_SimpleString("from time import time,ctime\n"
|
|
||||||
"print('Today is',ctime(time()))\n");
|
|
||||||
|
|
||||||
std::cout << "[C++] Executing engine_user.py\n";
|
|
||||||
//FILE* PScriptFile = fopen("./scripts/engine_user.py", "r");
|
|
||||||
FILE* PScriptFile = fopen((script_path + "/engine_user.py").c_str(), "r");
|
|
||||||
if(PScriptFile) {
|
|
||||||
PyRun_SimpleFile(PScriptFile, "engine_user.py");
|
|
||||||
fclose(PScriptFile);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
std::cout << "[C++] Executing Python string\n";
|
|
||||||
PyRun_SimpleString("import sys;print(sys.version)");
|
|
||||||
|
|
||||||
//Run a simple file
|
|
||||||
std::cout << "[C++] executing the contents of test.py\n";
|
|
||||||
FILE* PScriptFile = fopen("test.py", "r");
|
|
||||||
if(PScriptFile){
|
|
||||||
PyRun_SimpleFile(PScriptFile, "test.py");
|
|
||||||
fclose(PScriptFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "[C++] importing script.script_function and executing from C++. Aquiring GIL...\n";
|
|
||||||
//Run a python function
|
|
||||||
PyObject *pName, *pModule, *pFunc, *pArgs, *pValue;
|
|
||||||
|
|
||||||
pName = PyUnicode_FromString((char*)"script");
|
|
||||||
|
|
||||||
// acquire GIL
|
|
||||||
PyGILState_STATE gstate;
|
|
||||||
gstate = PyGILState_Ensure();
|
|
||||||
|
|
||||||
pModule = PyImport_Import(pName);
|
|
||||||
pFunc = PyObject_GetAttrString(pModule, (char*)"script_function");
|
|
||||||
pArgs = PyTuple_Pack(1, PyUnicode_FromString((char*)"Embedded Python"));
|
|
||||||
pValue = PyObject_CallObject(pFunc, pArgs);
|
|
||||||
|
|
||||||
std::cout << "[C++] Result:\n";
|
|
||||||
auto result = _PyUnicode_AsString(pValue);
|
|
||||||
std::cout << result << std::endl;
|
|
||||||
|
|
||||||
// release GIL
|
|
||||||
PyGILState_Release(gstate);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TCOD functionality - gather noise
|
|
||||||
TCODNoise noise_{2, TCOD_NOISE_SIMPLEX};
|
|
||||||
float hurst_ = TCOD_NOISE_DEFAULT_HURST;
|
|
||||||
float lacunarity_ = TCOD_NOISE_DEFAULT_LACUNARITY;
|
|
||||||
noise_ = TCODNoise(2, hurst_, lacunarity_);
|
|
||||||
|
|
||||||
float display_noise[64][48];
|
|
||||||
int generated = 0;
|
|
||||||
float n_min = 0, n_max = 0;
|
|
||||||
for (int x = 0; x < 64; x++) {
|
|
||||||
for (int y = 0; y < 48; y++) {
|
|
||||||
float f[2] = {float(x * 10 + 5) / 100.0f, float(y * 10 + 5) / 100.0f};
|
|
||||||
display_noise[x][y] = float(noise_.get(f, TCOD_NOISE_SIMPLEX));
|
|
||||||
//display_noise[x][y] = float(rand()) / RAND_MAX;
|
|
||||||
generated++;
|
|
||||||
if (display_noise[x][y] > n_max) n_max = display_noise[x][y];
|
|
||||||
else if (display_noise[x][y] < n_min) n_min = display_noise[x][y];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "Generated " << generated << " points of noise: "
|
|
||||||
<< n_min << " - " << n_max << std::endl;
|
|
||||||
|
|
||||||
// SFML/graphical run
|
|
||||||
window.setFramerateLimit(30);
|
|
||||||
text.setFont(font);
|
|
||||||
text.setString("asdf");
|
|
||||||
text.setCharacterSize(16);
|
|
||||||
|
|
||||||
bool running = true;
|
|
||||||
while (running) {
|
|
||||||
// render
|
|
||||||
window.clear();
|
|
||||||
// draw boxes of noise
|
|
||||||
for (int x = 0; x < 64; x++) {
|
|
||||||
for (int y = 0; y < 48; y++) {
|
|
||||||
//int x1 = x * 10, x2 = (x+1) * 10, y1 = y * 10, y2 = (y+1) * 10;
|
|
||||||
sf::RectangleShape r;
|
|
||||||
r.setPosition(sf::Vector2f(x * 10, y * 10));
|
|
||||||
r.setSize(sf::Vector2f(10, 10));
|
|
||||||
r.setOutlineThickness(0);
|
|
||||||
r.setFillColor(sf::Color(display_noise[x][y] * 255, 0, 0));
|
|
||||||
window.draw(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
window.draw(text);
|
|
||||||
window.display();
|
|
||||||
|
|
||||||
// user input
|
|
||||||
sf::Event event;
|
|
||||||
while (window.pollEvent(event)) {
|
|
||||||
if (event.type == sf::Event::Closed) { running = false; continue; }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//Close the python instance
|
|
||||||
Py_Finalize();
|
|
||||||
|
|
||||||
std::cout << "[C++] Exiting normally.\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
#include "GameEngine.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
GameEngine g;
|
||||||
|
g.run();
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
class GridPoint:
|
||||||
|
def __init__(self, color, walkable, tilesprite, transparent, visible, discovered, color_overlay, tile_overlay, uisprite):
|
||||||
|
self.color = color
|
||||||
|
self.walkable = walkable
|
||||||
|
self.tilesprite = tilesprite
|
||||||
|
self.transparent = transparent
|
||||||
|
self.visible = visible
|
||||||
|
self.discovered = discovered
|
||||||
|
self.color_overlay = color_overlay
|
||||||
|
self.tile_overlay = tile_overlay
|
||||||
|
self.uisprite = uisprite
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<GridPoint {self.color}, {self.tilesprite}/{self.uisprite} {'W' if self.walkable else '-'}{'T' if self.transparent else '-'}{'V' if self.visible else '-'}{'D' if self.discovered else '-'} {self.color_overlay}/{self.tile_overlay}>"
|
||||||
|
|
||||||
|
class Grid:
|
||||||
|
def __init__(self, title, gx, gy, gs, x, y, w, h, visible=False):
|
||||||
|
self.title = title
|
||||||
|
self.grid_x = gx
|
||||||
|
self.grid_y = gy
|
||||||
|
self.grid_size = gs
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.w = w
|
||||||
|
self.h = h
|
||||||
|
self.visible = visible
|
||||||
|
|
||||||
|
self.points = []
|
||||||
|
self.entities = []
|
||||||
|
|
||||||
|
def at(self, x, y):
|
||||||
|
if not (x > 0 and y > 0 and x < self.grid_x and y < self.grid_y): return None
|
||||||
|
return self.points[y * self.grid_y + x]
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Grid {self.grid_x}x{self.grid_y}, grid_size={self.grid_size}, (({self.x},{self.y}), ({self.w}, {self.h})), visible={self.visible}>"
|
||||||
|
|
||||||
|
|
||||||
|
# CGrid(Grid* _g, int _ti, int _si, int _x, int _y, bool _v)
|
||||||
|
class Entity:
|
||||||
|
def __init__(self, parent, tex_index, sprite_index, x, y, visible=True):
|
||||||
|
self.parent = parent
|
||||||
|
self.tex_index = tex_index
|
||||||
|
self.sprite_index = sprite_index
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.visible = visible
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Entity on grid {repr(self.parent)}@({self.x},{self.y}), TI={self.tex_index}, SI={self.sprite_index}, visible={self.visible}>"
|
|
@ -0,0 +1,79 @@
|
||||||
|
import mcrfpy
|
||||||
|
BLACK = (0, 0, 0)
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
RED, GREEN, BLUE = (255, 0, 0), (0, 255, 0), (0, 0, 255)
|
||||||
|
DARKRED, DARKGREEN, DARKBLUE = (192, 0, 0), (0, 192, 0), (0, 0, 192)
|
||||||
|
class MusicScene:
|
||||||
|
def __init__(self, ui_name = "demobox1", grid_name = "demogrid"):
|
||||||
|
# Texture & Sound Loading
|
||||||
|
print("Load textures")
|
||||||
|
mcrfpy.createTexture("./assets/test_portraits.png", 32, 8, 8) #0 - portraits
|
||||||
|
mcrfpy.createTexture("./assets/alives_other.png", 16, 64, 64) #1 - TinyWorld NPCs
|
||||||
|
mcrfpy.createTexture("./assets/alives_other.png", 32, 32, 32) #2 - TinyWorld NPCs - 2x2 sprite
|
||||||
|
# {"createSoundBuffer", McRFPy_API::_createSoundBuffer, METH_VARARGS, "(filename)"},
|
||||||
|
#{"loadMusic", McRFPy_API::_loadMusic, METH_VARARGS, "(filename)"},
|
||||||
|
#{"setMusicVolume", McRFPy_API::_setMusicVolume, METH_VARARGS, "(int)"},
|
||||||
|
#{"setSoundVolume", McRFPy_API::_setSoundVolume, METH_VARARGS, "(int)"},
|
||||||
|
#{"playSound", McRFPy_API::_playSound, METH_VARARGS, "(int)"},
|
||||||
|
#{"getMusicVolume", McRFPy_API::_getMusicVolume, METH_VARARGS, ""},
|
||||||
|
#{"getSoundVolume", McRFPy_API::_getSoundVolume, METH_VARARGS, ""},
|
||||||
|
|
||||||
|
mcrfpy.loadMusic("./assets/ultima.ogg")
|
||||||
|
mcrfpy.createSoundBuffer("./assets/boom.wav")
|
||||||
|
self.ui_name = ui_name
|
||||||
|
self.grid_name = grid_name
|
||||||
|
|
||||||
|
print("Create UI")
|
||||||
|
# Create dialog UI
|
||||||
|
mcrfpy.createMenu(ui_name, 20, 540, 500, 200)
|
||||||
|
mcrfpy.createCaption(ui_name, f"Music Volume: {mcrfpy.getMusicVolume()}", 24, RED)
|
||||||
|
mcrfpy.createCaption(ui_name, f"SFX Volume: {mcrfpy.getSoundVolume()}", 24, RED)
|
||||||
|
#mcrfpy.createButton(ui_name, 250, 20, 100, 50, DARKBLUE, (0, 0, 0), "clicky", "testaction")
|
||||||
|
mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKRED, (0, 0, 0), "Music+", "mvol+")
|
||||||
|
mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKGREEN, (0, 0, 0), "Music-", "mvol-")
|
||||||
|
mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKBLUE, GREEN, "SFX+", "svol+")
|
||||||
|
mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKBLUE, RED, "SFX-", "svol-")
|
||||||
|
mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKRED, (0, 0, 0), "REPL", "startrepl")
|
||||||
|
mcrfpy.createSprite(ui_name, 1, 0, 20, 40, 3.0)
|
||||||
|
|
||||||
|
print("Create UI 2")
|
||||||
|
entitymenu = "entitytestmenu"
|
||||||
|
|
||||||
|
mcrfpy.createMenu(entitymenu, 840, 20, 20, 500)
|
||||||
|
mcrfpy.createButton(entitymenu, 0, 10, 150, 40, DARKBLUE, BLACK, "PlayM", "playm")
|
||||||
|
mcrfpy.createButton(entitymenu, 0, 60, 150, 40, DARKBLUE, BLACK, "StopM", "stopm")
|
||||||
|
mcrfpy.createButton(entitymenu, 0, 110, 150, 40, DARKBLUE, BLACK, "SFX", "boom")
|
||||||
|
print("Make UIs visible")
|
||||||
|
self.menus = mcrfpy.listMenus()
|
||||||
|
self.menus[0].visible = True
|
||||||
|
self.menus[1].w = 170
|
||||||
|
self.menus[1].visible = True
|
||||||
|
mcrfpy.modMenu(self.menus[0])
|
||||||
|
mcrfpy.modMenu(self.menus[1])
|
||||||
|
self.mvol = mcrfpy.getMusicVolume()
|
||||||
|
self.svol = mcrfpy.getSoundVolume()
|
||||||
|
mcrfpy.registerPyAction("mvol+", lambda: self.setmvol(self.mvol+10))
|
||||||
|
mcrfpy.registerPyAction("mvol-", lambda: self.setmvol(self.mvol-10))
|
||||||
|
mcrfpy.registerPyAction("svol+", lambda: self.setsvol(self.svol+10))
|
||||||
|
mcrfpy.registerPyAction("svol-", lambda: self.setsvol(self.svol-10))
|
||||||
|
mcrfpy.registerPyAction("playm", lambda: None)
|
||||||
|
mcrfpy.registerPyAction("stopm", lambda: None)
|
||||||
|
mcrfpy.registerPyAction("boom", lambda: mcrfpy.playSound(0))
|
||||||
|
|
||||||
|
def setmvol(self, v):
|
||||||
|
mcrfpy.setMusicVolume(int(v))
|
||||||
|
self.menus[0].captions[0].text = f"Music Volume: {mcrfpy.getMusicVolume():.1f}"
|
||||||
|
mcrfpy.modMenu(self.menus[0])
|
||||||
|
self.mvol = mcrfpy.getMusicVolume()
|
||||||
|
|
||||||
|
def setsvol(self, v):
|
||||||
|
mcrfpy.setSoundVolume(int(v))
|
||||||
|
self.menus[0].captions[1].text = f"Sound Volume: {mcrfpy.getSoundVolume():.1f}"
|
||||||
|
mcrfpy.modMenu(self.menus[0])
|
||||||
|
self.svol = mcrfpy.getSoundVolume()
|
||||||
|
|
||||||
|
scene = None
|
||||||
|
def start():
|
||||||
|
global scene
|
||||||
|
scene = MusicScene()
|
||||||
|
|
|
@ -0,0 +1,575 @@
|
||||||
|
import UIMenu
|
||||||
|
import Grid
|
||||||
|
import mcrfpy
|
||||||
|
from random import randint, choice
|
||||||
|
from pprint import pprint
|
||||||
|
#print("TestScene imported")
|
||||||
|
BLACK = (0, 0, 0)
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
RED, GREEN, BLUE = (255, 0, 0), (0, 255, 0), (0, 0, 255)
|
||||||
|
DARKRED, DARKGREEN, DARKBLUE = (192, 0, 0), (0, 192, 0), (0, 0, 192)
|
||||||
|
|
||||||
|
animations_in_progress = 0
|
||||||
|
|
||||||
|
# don't load grid over and over, use the global scene
|
||||||
|
scene = None
|
||||||
|
|
||||||
|
class TestEntity:
|
||||||
|
def __init__(self, grid, label, tex_index, basesprite, x, y, texture_width=64, walk_frames=5, attack_frames=6, do_fov=False):
|
||||||
|
self.grid = grid
|
||||||
|
self.basesprite = basesprite
|
||||||
|
self.texture_width = texture_width
|
||||||
|
self.walk_frames = walk_frames
|
||||||
|
self.attack_frames = attack_frames
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.facing_direction = 0
|
||||||
|
self.do_fov = do_fov
|
||||||
|
self.label = label
|
||||||
|
self.inventory = []
|
||||||
|
#print(f"Calling C++ with: {repr((self.grid, label, tex_index, self.basesprite, x, y, self))}")
|
||||||
|
grids = mcrfpy.listGrids()
|
||||||
|
for g in grids:
|
||||||
|
if g.title == self.grid:
|
||||||
|
self.entity_index = len(g.entities)
|
||||||
|
mcrfpy.createEntity(self.grid, label, tex_index, self.basesprite, x, y, self)
|
||||||
|
|
||||||
|
def ai_act(self):
|
||||||
|
return # no AI motion
|
||||||
|
#if self.label == "player": return
|
||||||
|
self.move(randint(-1, 1), randint(-1, 1))
|
||||||
|
scene.actors += 1
|
||||||
|
|
||||||
|
def player_act(self):
|
||||||
|
#print("I'M INTERVENING")
|
||||||
|
mcrfpy.unlockPlayerInput()
|
||||||
|
scene.updatehints()
|
||||||
|
|
||||||
|
def die(self):
|
||||||
|
#self.x = -2
|
||||||
|
#self.y = -2
|
||||||
|
self.move(-1000,-1000)
|
||||||
|
self.animate(0,animove=(-1000,-1000))
|
||||||
|
self.x = -1000
|
||||||
|
self.y = -1000
|
||||||
|
self.label = "dead"
|
||||||
|
|
||||||
|
def interact(self, initiator, callback):
|
||||||
|
print(f"Interacted with {self.label}. ", end='')
|
||||||
|
if self.label == 'item':
|
||||||
|
print("'taking' item.")
|
||||||
|
callback()
|
||||||
|
self.die()
|
||||||
|
else:
|
||||||
|
print("blocking movement.")
|
||||||
|
|
||||||
|
def move(self, dx, dy, force=False):
|
||||||
|
# select animation direction
|
||||||
|
# prefer left or right for diagonals.
|
||||||
|
#grids = mcrfpy.listGrids()
|
||||||
|
for g in scene.grids:
|
||||||
|
if g.title == self.grid:
|
||||||
|
if not force and g.at(self.x + dx, self.y + dy) is None or not g.at(self.x + dx, self.y + dy).walkable:
|
||||||
|
#print("Blocked at target location.")
|
||||||
|
return
|
||||||
|
if not force: # entities can be stepped on when force=True (like collecting items!)
|
||||||
|
for entity in scene.tes:
|
||||||
|
if (entity.x, entity.y) == (self.x + dx, self.y + dy):
|
||||||
|
print(f"Blocked by entity {entity.label} at ({entity.x}, {entity.y})")
|
||||||
|
return entity.interact(self, lambda: self.move(dx, dy, force=True))
|
||||||
|
if self.label == "player":
|
||||||
|
mcrfpy.lockPlayerInput()
|
||||||
|
scene.updatehints()
|
||||||
|
if (dx == 0 and dy == 0):
|
||||||
|
direction = self.facing_direction # TODO, jump straight to computer turn
|
||||||
|
elif (dx):
|
||||||
|
direction = 2 if dx == +1 else 3
|
||||||
|
else:
|
||||||
|
direction = 0 if dy == +1 else 1
|
||||||
|
self.animate(direction, move=True, animove=(self.x + dx, self.y+dy))
|
||||||
|
self.facing_direction = direction
|
||||||
|
if (self.do_fov): mcrfpy.refreshFov()
|
||||||
|
|
||||||
|
|
||||||
|
def animate(self, direction, attacking=False, move=False, animove=None):
|
||||||
|
start_sprite = self.basesprite + (self.texture_width * (direction + (4 if attacking else 0)))
|
||||||
|
animation_frames = [start_sprite + i for i in range((self.attack_frames if attacking else self.walk_frames))]
|
||||||
|
mcrfpy.createAnimation(
|
||||||
|
0.15, # duration, seconds
|
||||||
|
self.grid, # parent: a UIMenu or Grid key
|
||||||
|
"entity", # target type: 'menu', 'grid', 'caption', 'button', 'sprite', or 'entity'
|
||||||
|
self.entity_index, # target id: integer index for menu or grid objs; None for grid/menu
|
||||||
|
"sprite", # field: 'position', 'size', 'bgcolor', 'textcolor', or 'sprite'
|
||||||
|
self.animation_done, #callback: callable once animation is complete
|
||||||
|
False, #loop: repeat indefinitely
|
||||||
|
animation_frames # values: iterable of frames for 'sprite', lerp target for others
|
||||||
|
)
|
||||||
|
#global animations_in_progress
|
||||||
|
#animations_in_progress += 1
|
||||||
|
if move:
|
||||||
|
pos = [self.x, self.y]
|
||||||
|
if (direction == 0): pos[1] += 1
|
||||||
|
elif (direction == 1): pos[1] -= 1
|
||||||
|
elif (direction == 2): pos[0] += 1
|
||||||
|
elif (direction == 3): pos[0] -= 1
|
||||||
|
if not animove:
|
||||||
|
self.x, self.y = pos
|
||||||
|
animove = pos
|
||||||
|
else:
|
||||||
|
pos = animove
|
||||||
|
self.x, self.y = animove
|
||||||
|
#scene.move_entity(self.grid, self.entity_index, pos)
|
||||||
|
#for g in mcrfpy.listGrids():
|
||||||
|
for g in scene.grids:
|
||||||
|
if g.title == self.grid:
|
||||||
|
g.entities[self.entity_index].x = pos[0]
|
||||||
|
g.entities[self.entity_index].y = pos[1]
|
||||||
|
mcrfpy.modGrid(g, True)
|
||||||
|
if animove:
|
||||||
|
mcrfpy.createAnimation(
|
||||||
|
0.25, # duration, seconds
|
||||||
|
self.grid, # parent: a UIMenu or Grid key
|
||||||
|
"entity", # target type: 'menu', 'grid', 'caption', 'button', 'sprite', or 'entity'
|
||||||
|
self.entity_index, # target id: integer index for menu or grid objs; None for grid/menu
|
||||||
|
"position", # field: 'position', 'size', 'bgcolor', 'textcolor', or 'sprite'
|
||||||
|
self.animation_done, #callback: callable once animation is complete
|
||||||
|
False, #loop: repeat indefinitely
|
||||||
|
animove # values: iterable of frames for 'sprite', lerp target for others
|
||||||
|
)
|
||||||
|
#animations_in_progress += 1
|
||||||
|
|
||||||
|
|
||||||
|
def animation_done(self):
|
||||||
|
#global animations_in_progress
|
||||||
|
#animations_in_progress -= 1
|
||||||
|
scene.actors -= 1
|
||||||
|
#print(f"{self} done animating - {scene.actors} remaining")
|
||||||
|
if scene.actors <= 0:
|
||||||
|
scene.actors = 0
|
||||||
|
mcrfpy.unlockPlayerInput()
|
||||||
|
scene.updatehints()
|
||||||
|
|
||||||
|
class TestItemEntity(TestEntity):
|
||||||
|
def __init__(self, grid, label, tex_index, basesprite, x, y, texture_width=64, walk_frames=5, attack_frames=6, do_fov=False, item="Nothing"):
|
||||||
|
super().__init__(grid, label, tex_index, basesprite, x, y, texture_width, walk_frames, attack_frames, do_fov)
|
||||||
|
self.item = item
|
||||||
|
|
||||||
|
def interact(self, initiator, callback):
|
||||||
|
if self.label == 'dead': return super().interact(initiator, callback)
|
||||||
|
print(f"Interacted with {self.label}, an item. Adding {self.item} to {initiator.label}'s inventory")
|
||||||
|
initiator.inventory.append(self.item)
|
||||||
|
callback()
|
||||||
|
scene.itemguis()
|
||||||
|
self.die()
|
||||||
|
|
||||||
|
class TestDoorEntity(TestEntity):
|
||||||
|
def __init__(self, grid, label, tex_index, basesprite, x, y, texture_width=64, walk_frames=5, attack_frames=6, do_fov=False, key="Nothing"):
|
||||||
|
super().__init__(grid, label, tex_index, basesprite, x, y, texture_width, walk_frames, attack_frames, do_fov)
|
||||||
|
self.key = key
|
||||||
|
|
||||||
|
def interact(self, initiator, callback):
|
||||||
|
if self.label == 'dead': return super().interact(initiator, callback)
|
||||||
|
print(f"Interacted with {self.label}, a Door. ", end='')
|
||||||
|
if self.key in initiator.inventory:
|
||||||
|
initiator.inventory.remove(self.key)
|
||||||
|
print("Taking key & passing.")
|
||||||
|
callback()
|
||||||
|
scene.itemguis()
|
||||||
|
self.die()
|
||||||
|
else:
|
||||||
|
print("The door is locked.")
|
||||||
|
|
||||||
|
class TestScene:
|
||||||
|
def __init__(self, ui_name = "demobox1", grid_name = "demogrid"):
|
||||||
|
# Texture & Sound Loading
|
||||||
|
self.actors = 0
|
||||||
|
#print("Load textures")
|
||||||
|
mcrfpy.createTexture("./assets/test_portraits.png", 32, 8, 8) #0 - portraits
|
||||||
|
mcrfpy.createTexture("./assets/alives_other.png", 16, 64, 64) #1 - TinyWorld NPCs
|
||||||
|
mcrfpy.createTexture("./assets/alives_other.png", 32, 32, 32) #2 - TinyWorld NPCs - 2x2 sprite
|
||||||
|
mcrfpy.createTexture("./assets/custom_player.png", 16, 5, 13) #3 - player
|
||||||
|
mcrfpy.createTexture("./assets/Sprite-0001.png", 80, 10, 10) #4 - LGJ2023 keycard + other icons
|
||||||
|
mcrfpy.createTexture("./assets/tiny_keycards.png", 16, 8, 8) #5 - tiny keycards (ground items)
|
||||||
|
self.ui_name = ui_name
|
||||||
|
self.grid_name = grid_name
|
||||||
|
|
||||||
|
# Menu index = 0
|
||||||
|
#print("Create UI")
|
||||||
|
# Create dialog UI
|
||||||
|
mcrfpy.createMenu(ui_name, 20, 540, 500, 200)
|
||||||
|
#mcrfpy.createCaption(ui_name, "Hello There", 18, BLACK)
|
||||||
|
mcrfpy.createCaption(ui_name, "", 24, RED)
|
||||||
|
#mcrfpy.createButton(ui_name, 250, 20, 100, 50, DARKBLUE, (0, 0, 0), "clicky", "testaction")
|
||||||
|
mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKRED, (0, 0, 0), "REPL", "startrepl")
|
||||||
|
##mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKGREEN, (0, 0, 0), "map gen", "gridgen")
|
||||||
|
#mcrfpy.createButton(ui_name, 250, 20, 100, 50, DARKGREEN, (0, 0, 0), "mapL", "gridgen2")
|
||||||
|
#mcrfpy.createButton(ui_name, 250, 20, 100, 50, DARKBLUE, (192, 0, 0), "a_menu", "animtest")
|
||||||
|
#mcrfpy.createButton(ui_name, 250, 20, 100, 50, DARKRED, GREEN, "a_spr", "animtest2")
|
||||||
|
#mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKBLUE, GREEN, "Next sp", "nextsp")
|
||||||
|
#mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKBLUE, RED, "Prev sp", "prevsp")
|
||||||
|
#mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKBLUE, DARKGREEN, "+16 sp", "skipsp")
|
||||||
|
mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKGREEN, (0, 0, 0), "Next", "nextsp")
|
||||||
|
mcrfpy.createButton(ui_name, 250, 0, 130, 40, DARKBLUE, (0, 0, 0), "Prev", "prevsp")
|
||||||
|
mcrfpy.createSprite(ui_name, 4, 1, 10, 10, 2.0)
|
||||||
|
|
||||||
|
# Menu index = 1
|
||||||
|
#print("Create UI 2")
|
||||||
|
entitymenu = "entitytestmenu"
|
||||||
|
mcrfpy.createMenu(entitymenu, 840, 20, 20, 500)
|
||||||
|
mcrfpy.createButton(entitymenu, 0, 10, 150, 40, DARKBLUE, BLACK, "Up", "test_up")
|
||||||
|
mcrfpy.createButton(entitymenu, 0, 60, 150, 40, DARKBLUE, BLACK, "Down", "test_down")
|
||||||
|
mcrfpy.createButton(entitymenu, 0, 110, 150, 40, DARKBLUE, BLACK, "Left", "test_left")
|
||||||
|
mcrfpy.createButton(entitymenu, 0, 160, 150, 40, DARKBLUE, BLACK, "Right", "test_right")
|
||||||
|
mcrfpy.createButton(entitymenu, 0, 210, 150, 40, DARKBLUE, BLACK, "Attack", "test_attack")
|
||||||
|
mcrfpy.createButton(entitymenu, 0, 210, 150, 40, DARKBLUE, RED, "TE", "testent")
|
||||||
|
|
||||||
|
# Menu index = 2
|
||||||
|
mcrfpy.createMenu( "gridtitlemenu", 0, -10, 0, 0)
|
||||||
|
mcrfpy.createCaption("gridtitlemenu", "<grid name>", 18, WHITE)
|
||||||
|
#mcrfpy.createCaption("gridtitlemenu", "<camstate>", 16, WHITE)
|
||||||
|
|
||||||
|
# Menu index = 3
|
||||||
|
mcrfpy.createMenu( "hintsmenu", 0, 505, 0, 0)
|
||||||
|
mcrfpy.createCaption("hintsmenu", "<hintline>", 16, WHITE)
|
||||||
|
|
||||||
|
# Menu index = 4
|
||||||
|
# menu names must be created in alphabetical order (?!) - thanks, C++ hash map
|
||||||
|
mcrfpy.createMenu( "i", 600, 20, 0, 0)
|
||||||
|
#mcrfpy.createMenu( "camstatemenu", 600, 20, 0, 0)
|
||||||
|
mcrfpy.createCaption("i", "<camstate>", 16, WHITE)
|
||||||
|
|
||||||
|
# Menu index = 5
|
||||||
|
mcrfpy.createMenu( "j", 600, 500, 0, 0)
|
||||||
|
mcrfpy.createButton( "j", 0, 0, 80, 40, DARKBLUE, WHITE, "Recenter", "activatecamfollow")
|
||||||
|
|
||||||
|
# Menu index = 6, 7, 8, 9, 10: keycard sprites
|
||||||
|
mcrfpy.createMenu("k", 540, 540, 80, 80) #6
|
||||||
|
mcrfpy.createSprite("k", 4, 0, 10, 10, 1.0)
|
||||||
|
|
||||||
|
mcrfpy.createMenu("l", 540 + (80 * 1), 540, 80, 80) #7
|
||||||
|
mcrfpy.createSprite("l", 4, 1, 10, 10, 1.0)
|
||||||
|
|
||||||
|
mcrfpy.createMenu("m", 540 + (80 * 2), 540, 80, 80) #8
|
||||||
|
mcrfpy.createSprite("m", 4, 2, 10, 10, 1.0)
|
||||||
|
|
||||||
|
mcrfpy.createMenu("n", 540 + (80 * 3), 540, 80, 80) #9
|
||||||
|
mcrfpy.createSprite("n", 4, 3, 10, 10, 1.0)
|
||||||
|
|
||||||
|
mcrfpy.createMenu("o", 540 + (80 * 4), 540, 80, 80) #10
|
||||||
|
mcrfpy.createSprite("o", 4, 4, 10, 10, 1.0)
|
||||||
|
|
||||||
|
mcrfpy.createMenu("p", 20, 20, 40, 40) #11
|
||||||
|
#mcrfpy.createButton("p", 0, 0, 130, 40, DARKGREEN, (0, 0, 0), "Register", "keyregistration")
|
||||||
|
mcrfpy.createButton("p", 0, 0, 130, 40, DARKGREEN, (0, 0, 0), "Register", "startrepl")
|
||||||
|
mcrfpy.registerPyAction("keyregistration", keyregistration)
|
||||||
|
#print("Make UIs visible")
|
||||||
|
self.menus = mcrfpy.listMenus()
|
||||||
|
self.menus[0].visible = True
|
||||||
|
self.menus[1].w = 170
|
||||||
|
self.menus[1].visible = True
|
||||||
|
self.menus[2].visible = True
|
||||||
|
|
||||||
|
for mn in range(2, 6):
|
||||||
|
self.menus[mn].bgcolor = BLACK
|
||||||
|
self.menus[mn].visible = True
|
||||||
|
mcrfpy.modMenu(self.menus[mn])
|
||||||
|
|
||||||
|
for mn in range(6, 11):
|
||||||
|
self.menus[mn].bgcolor = BLACK
|
||||||
|
self.menus[mn].visible = False
|
||||||
|
mcrfpy.modMenu(self.menus[mn])
|
||||||
|
|
||||||
|
self.menus[11].visible=True
|
||||||
|
mcrfpy.modMenu(self.menus[11])
|
||||||
|
|
||||||
|
#self.menus[2].bgcolor = BLACK
|
||||||
|
#self.menus[3].visible = True
|
||||||
|
#self.menus[3].bgcolor = BLACK
|
||||||
|
#self.menus[4].visible = True
|
||||||
|
#self.menus[4].bgcolor = BLACK
|
||||||
|
#self.menus[5].visible = True
|
||||||
|
#mcrfpy.modMenu(self.menus[0])
|
||||||
|
#mcrfpy.modMenu(self.menus[1])
|
||||||
|
#mcrfpy.modMenu(self.menus[2])
|
||||||
|
#mcrfpy.modMenu(self.menus[3])
|
||||||
|
#mcrfpy.modMenu(self.menus[4])
|
||||||
|
#mcrfpy.modMenu(self.menus[5])
|
||||||
|
#pprint(mcrfpy.listMenus())
|
||||||
|
#print(f"UI 1 gave back this sprite: {self.menus[0].sprites}")
|
||||||
|
|
||||||
|
#print("Create grid")
|
||||||
|
# create grid (title, gx, gy, gs, x, y, w, h)
|
||||||
|
mcrfpy.createGrid(grid_name, 100, 100, 16, 20, 20, 800, 500)
|
||||||
|
self.grids = mcrfpy.listGrids()
|
||||||
|
#print(self.grids)
|
||||||
|
|
||||||
|
#print("Create entities")
|
||||||
|
#mcrfpy.createEntity("demogrid", "dragon", 2, 545, 10, 10, lambda: None)
|
||||||
|
#mcrfpy.createEntity("demogrid", "tinyenemy", 1, 1538, 3, 6, lambda: None)
|
||||||
|
|
||||||
|
#print("Create fancy entity")
|
||||||
|
self.player = TestEntity("demogrid", "player", 3, 20, 17, 3, 5, walk_frames=4, attack_frames=5, do_fov=True)
|
||||||
|
self.tes = [
|
||||||
|
TestEntity("demogrid", "classtest", 1, 1538, 5, 7, 64, walk_frames=5, attack_frames=6),
|
||||||
|
TestEntity("demogrid", "classtest", 1, 1545, 7, 9, 64, walk_frames=5, attack_frames=6),
|
||||||
|
TestEntity("demogrid", "classtest", 1, 1552, 9, 11, 64, walk_frames=5, attack_frames=6),
|
||||||
|
TestEntity("demogrid", "classtest", 1, 1566, 11, 13, 64, walk_frames=4, attack_frames=6),
|
||||||
|
#TestEntity("demogrid", "item", 1, 1573, 13, 15, 64, walk_frames=4, attack_frames=6),
|
||||||
|
TestEntity("demogrid", "classtest", 1, 1583, 15, 17, 64, walk_frames=4, attack_frames=6),
|
||||||
|
TestEntity("demogrid", "classtest", 1, 130, 9, 7, 64, walk_frames=5, attack_frames=6),
|
||||||
|
TestEntity("demogrid", "classtest", 1, 136, 11, 9, 64, walk_frames=5, attack_frames=6),
|
||||||
|
TestEntity("demogrid", "classtest", 1, 143, 13, 11, 64, walk_frames=5, attack_frames=6),
|
||||||
|
TestEntity("demogrid", "classtest", 1, 158, 15, 13, 64, walk_frames=5, attack_frames=6),
|
||||||
|
TestEntity("demogrid", "classtest", 1, 165, 17, 15, 64, walk_frames=5, attack_frames=6),
|
||||||
|
self.player,
|
||||||
|
|
||||||
|
TestItemEntity("demogrid", "GreenKeyCard", 5, 0, 19, 3, texture_width=64,
|
||||||
|
walk_frames=5, attack_frames=6, do_fov=False, item="Green Keycard"),
|
||||||
|
TestItemEntity("demogrid", "BlueKeyCard", 5, 1, 21, 3, texture_width=64,
|
||||||
|
walk_frames=5, attack_frames=6, do_fov=False, item="Blue Keycard"),
|
||||||
|
TestItemEntity("demogrid", "RedKeyCard", 5, 2, 23, 3, texture_width=64,
|
||||||
|
walk_frames=5, attack_frames=6, do_fov=False, item="Red Keycard"),
|
||||||
|
TestItemEntity("demogrid", "OrangeKeyCard", 5, 3, 25, 3, texture_width=64,
|
||||||
|
walk_frames=5, attack_frames=6, do_fov=False, item="Orange Keycard"),
|
||||||
|
TestItemEntity("demogrid", "DevilKeyCard", 5, 4, 27, 3, texture_width=64,
|
||||||
|
walk_frames=5, attack_frames=6, do_fov=False, item="Devil Keycard"),
|
||||||
|
|
||||||
|
TestDoorEntity("demogrid", "GreenKeyDoor", 5, 8, 19, 5, texture_width=64,
|
||||||
|
walk_frames=5, attack_frames=6, do_fov=False, key="Green Keycard"),
|
||||||
|
TestDoorEntity("demogrid", "BlueKeyDoor", 5, 9, 21, 5, texture_width=64,
|
||||||
|
walk_frames=5, attack_frames=6, do_fov=False, key="Blue Keycard"),
|
||||||
|
TestDoorEntity("demogrid", "RedKeyDoor", 5, 10, 23, 5, texture_width=64,
|
||||||
|
walk_frames=5, attack_frames=6, do_fov=False, key="Red Keycard"),
|
||||||
|
TestDoorEntity("demogrid", "OrangeKeyDoor", 5, 11, 25, 5, texture_width=64,
|
||||||
|
walk_frames=5, attack_frames=6, do_fov=False, key="Orange Keycard"),
|
||||||
|
TestDoorEntity("demogrid", "DevilKeyDoor", 5, 12, 27, 5, texture_width=64,
|
||||||
|
walk_frames=5, attack_frames=6, do_fov=False, key="Devil Keycard")
|
||||||
|
]
|
||||||
|
self.grids = mcrfpy.listGrids()
|
||||||
|
|
||||||
|
self.entity_direction = 0
|
||||||
|
mcrfpy.registerPyAction("test_down", lambda: [te.animate(0, False, True) for te in self.tes])
|
||||||
|
mcrfpy.registerPyAction("test_up", lambda: [te.animate(1, False, True) for te in self.tes])
|
||||||
|
mcrfpy.registerPyAction("test_right", lambda: [te.animate(2, False, True) for te in self.tes])
|
||||||
|
mcrfpy.registerPyAction("test_left", lambda: [te.animate(3, False, True) for te in self.tes])
|
||||||
|
mcrfpy.registerPyAction("test_attack", lambda: [te.animate(0, True) for te in self.tes])
|
||||||
|
mcrfpy.registerPyAction("testent", lambda: [te.animate(2, True) for te in self.tes])
|
||||||
|
mcrfpy.registerPyAction("activatecamfollow", lambda: mcrfpy.camFollow(True))
|
||||||
|
|
||||||
|
# Button behavior
|
||||||
|
self.clicks = 0
|
||||||
|
self.sprite_index = 0
|
||||||
|
#mcrfpy.registerPyAction("testaction", self.click)
|
||||||
|
mcrfpy.registerPyAction("gridgen", self.gridgen)
|
||||||
|
#mcrfpy.registerPyAction("gridgen2", lambda: self.gridgen())
|
||||||
|
#mcrfpy.registerPyAction("animtest", lambda: self.createAnimation())
|
||||||
|
#mcrfpy.registerPyAction("animtest2", lambda: self.createAnimation2())
|
||||||
|
mcrfpy.registerPyAction("nextsp", lambda: self.changesprite(1))
|
||||||
|
mcrfpy.registerPyAction("prevsp", lambda: self.changesprite(-1))
|
||||||
|
mcrfpy.registerPyAction("skipsp", lambda: self.changesprite(16))
|
||||||
|
mcrfpy.unlockPlayerInput()
|
||||||
|
mcrfpy.setActiveGrid("demogrid")
|
||||||
|
self.gridgen()
|
||||||
|
self.updatehints()
|
||||||
|
mcrfpy.camFollow(True)
|
||||||
|
|
||||||
|
def itemguis(self):
|
||||||
|
print(self.player.inventory)
|
||||||
|
items = ["Green Keycard", "Blue Keycard", "Red Keycard", "Orange Keycard", "Devil Keycard"]
|
||||||
|
for mn in range(6, 11):
|
||||||
|
self.menus[mn].visible = items[mn-6] in self.player.inventory
|
||||||
|
mcrfpy.modMenu(self.menus[mn])
|
||||||
|
|
||||||
|
def animate_entity(self, direction, attacking=False):
|
||||||
|
if direction is None:
|
||||||
|
direction = self.entity_direction
|
||||||
|
else:
|
||||||
|
self.entity_direction = direction
|
||||||
|
|
||||||
|
dragon_sprite = 545 + (32 * (direction + (4 if attacking else 0)))
|
||||||
|
dragon_animation = [dragon_sprite + i for i in range((5 if attacking else 4))]
|
||||||
|
mcrfpy.createAnimation(
|
||||||
|
1.0, # duration, seconds
|
||||||
|
"demogrid", # parent: a UIMenu or Grid key
|
||||||
|
"entity", # target type: 'menu', 'grid', 'caption', 'button', 'sprite', or 'entity'
|
||||||
|
0, # target id: integer index for menu or grid objs; None for grid/menu
|
||||||
|
"sprite", # field: 'position', 'size', 'bgcolor', 'textcolor', or 'sprite'
|
||||||
|
lambda: self.animation_done("demobox1"), #callback: callable once animation is complete
|
||||||
|
False, #loop: repeat indefinitely
|
||||||
|
dragon_animation # values: iterable of frames for 'sprite', lerp target for others
|
||||||
|
)
|
||||||
|
|
||||||
|
orc_sprite = 1538 + (64 * (direction + (4 if attacking else 0)))
|
||||||
|
orc_animation = [orc_sprite + i for i in range((5 if attacking else 4))]
|
||||||
|
mcrfpy.createAnimation(
|
||||||
|
1.0, # duration, seconds
|
||||||
|
"demogrid", # parent: a UIMenu or Grid key
|
||||||
|
"entity", # target type: 'menu', 'grid', 'caption', 'button', 'sprite', or 'entity'
|
||||||
|
1, # target id: integer index for menu or grid objs; None for grid/menu
|
||||||
|
"sprite", # field: 'position', 'size', 'bgcolor', 'textcolor', or 'sprite'
|
||||||
|
lambda: self.animation_done("demobox1"), #callback: callable once animation is complete
|
||||||
|
False, #loop: repeat indefinitely
|
||||||
|
orc_animation # values: iterable of frames for 'sprite', lerp target for others
|
||||||
|
)
|
||||||
|
|
||||||
|
#def move_entity(self, targetgrid, entity_index, position):
|
||||||
|
# for i, g in enumerate(self.grids):
|
||||||
|
# if g.title == targetgrid:
|
||||||
|
# g.entities[entity_index].x = position[0]
|
||||||
|
# g.entities[entity_index].y = position[1]
|
||||||
|
# #pts = g.points
|
||||||
|
# g.visible = True
|
||||||
|
# mcrfpy.modGrid(g)
|
||||||
|
# self.grids = mcrfpy.listGrids()
|
||||||
|
# #self.grids[i].points = pts
|
||||||
|
# return
|
||||||
|
|
||||||
|
|
||||||
|
def changesprite(self, n):
|
||||||
|
self.sprite_index += n
|
||||||
|
self.menus[0].captions[0].text = f"Sprite #{self.sprite_index}"
|
||||||
|
self.menus[0].sprites[0].sprite_index = self.sprite_index
|
||||||
|
mcrfpy.modMenu(self.menus[0])
|
||||||
|
|
||||||
|
def click(self):
|
||||||
|
self.clicks += 1
|
||||||
|
self.menus[0].captions[0].text = f"Clicks: {self.clicks}"
|
||||||
|
self.menus[0].sprites[0].sprite_index = randint(0, 3)
|
||||||
|
mcrfpy.modMenu(self.menus[0])
|
||||||
|
|
||||||
|
def updatehints(self):
|
||||||
|
self.menus[2].captions[0].text=mcrfpy.activeGrid()
|
||||||
|
mcrfpy.modMenu(self.menus[2])
|
||||||
|
|
||||||
|
self.menus[3].captions[0].text=mcrfpy.inputMode()
|
||||||
|
mcrfpy.modMenu(self.menus[3])
|
||||||
|
#self.menus[4].captions[0].text=f"follow: {mcrfpy.camFollow()}"
|
||||||
|
|
||||||
|
self.menus[4].captions[0].text="following" if mcrfpy.camFollow() else "free"
|
||||||
|
mcrfpy.modMenu(self.menus[4])
|
||||||
|
|
||||||
|
self.menus[5].visible = not mcrfpy.camFollow()
|
||||||
|
mcrfpy.modMenu(self.menus[5])
|
||||||
|
|
||||||
|
|
||||||
|
def gridgen(self):
|
||||||
|
|
||||||
|
#print(f"[Python] modifying {len(self.grids[0].points)} grid points")
|
||||||
|
for p in self.grids[0].points:
|
||||||
|
#p.color = (randint(0, 255), randint(64, 192), 0)
|
||||||
|
p.color = (0,0,0)
|
||||||
|
p.walkable = False
|
||||||
|
p.transparent = False
|
||||||
|
|
||||||
|
room_centers = [(randint(0, self.grids[0].grid_x-1), randint(0, self.grids[0].grid_y-1)) for i in range(20)] + [(17, 3), (20,10) + (20,5)]
|
||||||
|
#room_centers.append((3, 5))
|
||||||
|
for r in room_centers:
|
||||||
|
# random hallway
|
||||||
|
target = choice(room_centers)
|
||||||
|
length1 = abs(target[0] - r[0])
|
||||||
|
|
||||||
|
xbase = min(target[0], r[0])
|
||||||
|
for x in range(length1):
|
||||||
|
gpoint = self.grids[0].at(x, r[1])
|
||||||
|
if gpoint is None: continue
|
||||||
|
gpoint.walkable = True
|
||||||
|
gpoint.transparent = True
|
||||||
|
gpoint.color = (192, 192, 192)
|
||||||
|
|
||||||
|
length2 = abs(target[1] - r[1])
|
||||||
|
ybase = min(target[1], r[1])
|
||||||
|
for y in range(length2):
|
||||||
|
gpoint = self.grids[0].at(r[0], y)
|
||||||
|
if gpoint is None: continue
|
||||||
|
gpoint.walkable = True
|
||||||
|
gpoint.transparent = True
|
||||||
|
gpoint.color = (192, 192, 192)
|
||||||
|
|
||||||
|
for r in room_centers:
|
||||||
|
#print(r)
|
||||||
|
room_color = (randint(16, 24)*8, randint(16, 24)*8, randint(16, 24)*8)
|
||||||
|
#self.grids[0].at(r[0], r[1]).walkable = True
|
||||||
|
#self.grids[0].at(r[0], r[1]).color = room_color
|
||||||
|
halfx, halfy = randint(2, 11), randint(2,11)
|
||||||
|
for p_x in range(r[0] - halfx, r[0] + halfx):
|
||||||
|
for p_y in range(r[1] - halfy, r[1] + halfy):
|
||||||
|
gpoint = self.grids[0].at(p_x, p_y)
|
||||||
|
if gpoint is None: continue
|
||||||
|
gpoint.walkable = True
|
||||||
|
gpoint.transparent = True
|
||||||
|
gpoint.color = room_color
|
||||||
|
#print()
|
||||||
|
|
||||||
|
#print("[Python] Modifying:")
|
||||||
|
self.grids[0].at(10, 10).color = (255, 255, 255)
|
||||||
|
self.grids[0].at(10, 10).walkable = False
|
||||||
|
self.grids[0].visible = True
|
||||||
|
mcrfpy.modGrid(self.grids[0])
|
||||||
|
#self.grids = mcrfpy.listGrids()
|
||||||
|
#print(f"Sent grid: {repr(self.grids[0])}")
|
||||||
|
#print(f"Received grid: {repr(mcrfpy.listGrids()[0])}")
|
||||||
|
|
||||||
|
def animation_done(self, s):
|
||||||
|
print(f"The `{s}` animation completed.")
|
||||||
|
#self.menus = mcrfpy.listMenus()
|
||||||
|
|
||||||
|
# if (!PyArg_ParseTuple(args, "fsssiOOO", &duration, &parent, &target_type, &target_id, &field, &callback, &loop_obj, &values_obj)) return NULL;
|
||||||
|
def createAnimation(self):
|
||||||
|
print(self.menus)
|
||||||
|
self.menus = mcrfpy.listMenus()
|
||||||
|
self.menus[0].w = 500
|
||||||
|
self.menus[0].h = 200
|
||||||
|
print(self.menus)
|
||||||
|
mcrfpy.modMenu(self.menus[0])
|
||||||
|
print(self.menus)
|
||||||
|
mcrfpy.createAnimation(
|
||||||
|
3.0, # duration, seconds
|
||||||
|
"demobox1", # parent: a UIMenu or Grid key
|
||||||
|
"menu", # target type: 'menu', 'grid', 'caption', 'button', 'sprite', or 'entity'
|
||||||
|
0, # target id: integer index for menu or grid objs; None for grid/menu
|
||||||
|
"size", # field: 'position', 'size', 'bgcolor', 'textcolor', or 'sprite'
|
||||||
|
lambda: self.animation_done("demobox1"), #callback: callable once animation is complete
|
||||||
|
False, #loop: repeat indefinitely
|
||||||
|
[150, 100] # values: iterable of frames for 'sprite', lerp target for others
|
||||||
|
)
|
||||||
|
|
||||||
|
def createAnimation2(self):
|
||||||
|
mcrfpy.createAnimation(
|
||||||
|
5,
|
||||||
|
"demobox1",
|
||||||
|
"sprite",
|
||||||
|
0,
|
||||||
|
"sprite",
|
||||||
|
lambda: self.animation_done("sprite change"),
|
||||||
|
False,
|
||||||
|
[0, 1, 2, 1, 2, 0]
|
||||||
|
)
|
||||||
|
|
||||||
|
def keytest():
|
||||||
|
print("Key tested.")
|
||||||
|
|
||||||
|
def keyregistration():
|
||||||
|
print("Registering 'keytest'")
|
||||||
|
mcrfpy.registerPyAction("keytest", keytest)
|
||||||
|
print("Registering input")
|
||||||
|
print(mcrfpy.registerInputAction(15, "keytest")) # 15 = P
|
||||||
|
|
||||||
|
mcrfpy.registerPyAction("player_move_up", lambda: scene.player.move(0, -1))
|
||||||
|
mcrfpy.registerPyAction("player_move_left", lambda: scene.player.move(-1, 0))
|
||||||
|
mcrfpy.registerPyAction("player_move_down", lambda: scene.player.move(0, 1))
|
||||||
|
mcrfpy.registerPyAction("player_move_right", lambda: scene.player.move(1, 0))
|
||||||
|
|
||||||
|
mcrfpy.registerInputAction(ord('w') - ord('a'), "player_move_up")
|
||||||
|
mcrfpy.registerInputAction(ord('a') - ord('a'), "player_move_left")
|
||||||
|
mcrfpy.registerInputAction(ord('s') - ord('a'), "player_move_down")
|
||||||
|
mcrfpy.registerInputAction(ord('d') - ord('a'), "player_move_right")
|
||||||
|
|
||||||
|
|
||||||
|
def start():
|
||||||
|
global scene
|
||||||
|
#print("TestScene.start called")
|
||||||
|
scene = TestScene()
|
||||||
|
mcrfpy.refreshFov()
|
||||||
|
|
||||||
|
|
||||||
|
scene.updatehints()
|
|
@ -0,0 +1,48 @@
|
||||||
|
class Caption:
|
||||||
|
def __init__(self, text, textsize, color):
|
||||||
|
self.text = text
|
||||||
|
self.textsize = textsize
|
||||||
|
self.color = color
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Caption text={self.text}, textsize={self.textsize}, color={self.color}>"
|
||||||
|
|
||||||
|
class Button:
|
||||||
|
def __init__(self, x, y, w, h, bgcolor, textcolor, text, actioncode):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.w = w
|
||||||
|
self.h = h
|
||||||
|
self.bgcolor = bgcolor
|
||||||
|
self.textcolor = textcolor
|
||||||
|
self.text = text
|
||||||
|
self.actioncode = actioncode
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Button ({self.x}, {self.y}, {self.w}, {self.h}), bgcolor={self.bgcolor}, textcolor={self.textcolor}, actioncode={self.actioncode}>"
|
||||||
|
|
||||||
|
class Sprite:
|
||||||
|
def __init__(self, tex_index, sprite_index, x, y):
|
||||||
|
self.tex_index = tex_index
|
||||||
|
self.sprite_index = sprite_index
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Sprite tex_index={self.tex_index}, self.sprite_index={self.sprite_index}, x={self.x}, y={self.y}>"
|
||||||
|
|
||||||
|
class UIMenu:
|
||||||
|
def __init__(self, title, x, y, w, h, bgcolor, visible=False):
|
||||||
|
self.title = title
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.w = w
|
||||||
|
self.h = h
|
||||||
|
self.bgcolor = bgcolor
|
||||||
|
self.visible = visible
|
||||||
|
self.captions = []
|
||||||
|
self.buttons = []
|
||||||
|
self.sprites = []
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<UIMenu title={repr(self.title)}, x={self.x}, y={self.y}, w={self.w}, h={self.h}, bgcolor={self.bgcolor}, visible={self.visible}, {len(self.captions)} captions, {len(self.buttons)} buttons, {len(self.sprites)} sprites>"
|
|
@ -0,0 +1,37 @@
|
||||||
|
import mcrfpy
|
||||||
|
mcrfpy.createTexture("./assets/test_portraits.png", 32, 8, 8)
|
||||||
|
from random import choice, randint
|
||||||
|
|
||||||
|
box_colors = [
|
||||||
|
(0, 0, 192),
|
||||||
|
(0, 192, 0),
|
||||||
|
(192, 0, 0),
|
||||||
|
(192, 192, 0),
|
||||||
|
(0, 192, 192),
|
||||||
|
(192, 0, 192)
|
||||||
|
]
|
||||||
|
|
||||||
|
text_colors = [
|
||||||
|
(0, 0, 255),
|
||||||
|
(0, 255, 0),
|
||||||
|
(255, 0, 0),
|
||||||
|
(255, 255, 0),
|
||||||
|
(0, 255, 255),
|
||||||
|
(255, 0, 255)
|
||||||
|
]
|
||||||
|
|
||||||
|
test_x = 500
|
||||||
|
test_y = 10
|
||||||
|
for i in range(40):
|
||||||
|
ui_name = f"test{i}"
|
||||||
|
mcrfpy.createMenu(ui_name, test_x, test_y, 400, 200)
|
||||||
|
mcrfpy.createCaption(ui_name, "Hello There", 18, choice(text_colors))
|
||||||
|
mcrfpy.createButton(ui_name, 250, 20, 100, 50, choice(box_colors), (0, 0, 0), "asdf", "testaction")
|
||||||
|
|
||||||
|
mcrfpy.createSprite(ui_name, 0, randint(0, 3), 650, 60, 5.0)
|
||||||
|
|
||||||
|
test_x -= 50
|
||||||
|
test_y += 50
|
||||||
|
if (test_x <= 50):
|
||||||
|
test_x = 500
|
||||||
|
#print(test_x)
|
|
@ -0,0 +1,77 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#rm -R bin/linux
|
||||||
|
mkdir -p bin/linux/lib
|
||||||
|
mkdir -p obj
|
||||||
|
rm obj/*
|
||||||
|
|
||||||
|
# copy shared objects, squish "linux" subdirectory in bin/linux/lib
|
||||||
|
#cp -R lib/linux/* bin/linux/lib
|
||||||
|
|
||||||
|
# copy assets directory (font, sprites, etc)
|
||||||
|
cp -R assets bin/linux
|
||||||
|
|
||||||
|
# copy Python code
|
||||||
|
cp -R src/scripts bin/linux/scripts
|
||||||
|
|
||||||
|
# work from output directory and change every g++ path to relative D:<
|
||||||
|
cd bin/linux
|
||||||
|
|
||||||
|
# prepare object files of engine classes
|
||||||
|
abort_compile()
|
||||||
|
{
|
||||||
|
echo "Compilation failed on $fn.cpp"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Precompile engine classes. Get errors in their file, not where they're included
|
||||||
|
for fn in $(ls ../../src/*.cpp -1 | cut -d/ -f4 | cut -d. -f1)
|
||||||
|
do
|
||||||
|
# Skip combined_poc.cpp, it has a duplicate main
|
||||||
|
if [ "$fn" = "combined_poc" ]; then continue; fi
|
||||||
|
|
||||||
|
echo "Compile $fn.cpp"
|
||||||
|
g++ \
|
||||||
|
-g \
|
||||||
|
-I../../deps_linux \
|
||||||
|
-I../../deps_linux/Python-3.11.1 \
|
||||||
|
-I../../platform/linux \
|
||||||
|
--std=c++2a \
|
||||||
|
-c ../../src/$fn.cpp \
|
||||||
|
-o ../../obj/$fn.o \
|
||||||
|
-lm \
|
||||||
|
-ldl \
|
||||||
|
-lutil \
|
||||||
|
-lpthread \
|
||||||
|
-lpython3.11 \
|
||||||
|
-lsfml-graphics \
|
||||||
|
-lsfml-window \
|
||||||
|
-lsfml-system \
|
||||||
|
-lsfml-audio \
|
||||||
|
-ltcod \
|
||||||
|
|| abort_compile $fn
|
||||||
|
done
|
||||||
|
|
||||||
|
# Final executable
|
||||||
|
# --std= : c++2a vs c++17
|
||||||
|
g++ \
|
||||||
|
-g \
|
||||||
|
--std=c++2a \
|
||||||
|
-I../../deps_linux \
|
||||||
|
-I../../deps_linux/Python-3.11.1 \
|
||||||
|
-I../../platform/linux \
|
||||||
|
../../obj/*.o \
|
||||||
|
-o mcrogueface \
|
||||||
|
-Wl,-rpath lib \
|
||||||
|
-L../../deps_linux \
|
||||||
|
-lm \
|
||||||
|
-ldl \
|
||||||
|
-lutil \
|
||||||
|
-lpthread \
|
||||||
|
-lpython3.11 \
|
||||||
|
-lsfml-graphics \
|
||||||
|
-lsfml-window \
|
||||||
|
-lsfml-system \
|
||||||
|
-lsfml-audio \
|
||||||
|
-ltcod \
|
||||||
|
|