Started work on gui & multitasking stuff

This commit is contained in:
Ryan Ward 2021-03-10 13:27:04 -05:00
parent 8ad61af59d
commit ea6cdc231c
23 changed files with 1204 additions and 80 deletions

42
DMS/Connection.h Normal file
View File

@ -0,0 +1,42 @@
#pragma once
#include <functional>
#include <list>
namespace multi {
/*
*/
template<class T>
class connection {
// bool = func(void* v)
std::vector<void(*)(T)> funcs;
std::vector<void(*)(void)> _funcs;
public:
int32_t connect(void(*func)(T)) {
funcs.push_back(func);
return funcs.size() - 1;
}
int32_t connect(void(*func)()) {
_funcs.push_back(func);
return (_funcs.size())*-1;
}
void fire(T arg) {
// Calls everything in the funcs and _funcs list
for (auto f : funcs) {
f(arg);
}
fire(); // Get the _funcs list as well
}
void fire() {
// Calls everything in the funcs list only
for (auto f : _funcs) {
f();
}
}
int32_t operator+=(void(*func)(T)) {
return connect(func);
}
int32_t operator+=(void(*func)()) {
return connect(func);
}
};
}

View File

@ -1,37 +1,16 @@
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include "pch.h"
#include "dms.h"
//#include <chrono>
using namespace dms;
//typedef void(*FNPTR)();
//using namespace std::chrono;
//value invokeTest(void* self, dms_state* state, dms_args* args) {
// utils::print(args->args[0].getPrintable());
// return "I work!";
//}
//value concat(void* self, dms_state* state, dms_args* args) {
// std::stringstream str;
// for (size_t i = 0; i < args->size() - 1; i++)
// str << args->args[i].getPrintable();
// return value(str.str());
//}
//void draw(sf::RenderWindow& window) {
// sf::CircleShape shape(60.f);
// shape.setFillColor(sf::Color(150, 50, 250));
//
// // set a 10-pixel wide orange outline
// shape.setOutlineThickness(10.f);
// shape.setOutlineColor(sf::Color(250, 150, 100));
// window.draw(shape);
//}
int main()
{
// TODO fix disp cmd to handle the standard
/*milliseconds ms = duration_cast<milliseconds>(
system_clock::now().time_since_epoch()
);
/*milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
utils::print(ms.count());*/
LineParser parser = LineParser("test.dms");
@ -39,44 +18,430 @@ int main()
// Load audio stuff
dms::audio::init(state);
state->dump();
state->run();
memory* mem = state->getMem();
// create the window
//sf::RenderWindow window(sf::VideoMode(800, 600), "My window");
sf::RenderWindow window(sf::VideoMode(1024, 768, 32), "Background Test");
sf::Texture texture;
texture.loadFromFile("background.jpg");
sf::Sprite sprite;
sf::Vector2u size = texture.getSize();
sprite.setTexture(texture);
sprite.setOrigin(0, 0);
sf::Font font;
font.loadFromFile("font.ttf");
sf::Text text("Hello this is a test|!", font);
text.setCharacterSize(30);
text.setStyle(sf::Text::Bold);
text.setFillColor(sf::Color::Black);
auto test = text.getGlobalBounds();
std::cout << test.left << "," << test.top << "," << test.width << "," << test.height << std::endl;
text.setPosition(11, 768 - 110 - (test.height-test.top));
//std::cout << test << std::endl;
sf::RectangleShape rectangle;
rectangle.setSize(sf::Vector2f(1004, 100));
rectangle.setOutlineColor(sf::Color::Red);
rectangle.setOutlineThickness(1);
rectangle.setPosition(10, 768-110);
//// run the program as long as the window is open
//while (window.isOpen())
//{
// // check all the window's events that were triggered since the last iteration of the loop
// sf::Event event;
// while (window.pollEvent(event))
// {
// // "close requested" event: we close the window
// if (event.type == sf::Event::Closed)
// window.close();
// }
// // clear the window with black color
// window.clear(sf::Color::Black);
// // draw everything here...
// draw(window);
// // end the current frame
// window.display();
//}
/*HINSTANCE hInst = LoadLibrary(L"C:\\Users\\rayam\\Desktop\\test.dll");
if (!hInst) {
std::cout << "\nCould not load the library!";
return EXIT_FAILURE;
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}
FNPTR fn = (FNPTR)GetProcAddress(hInst, "_init");
if (!fn) {
std::cout << "\nCould not load function from library!";
return EXIT_FAILURE;
// clear the window with black color
window.clear(sf::Color::Black);
if (!state->next(mem)) {
// We should clean up some stuff here!
break;
}
fn();*/
// draw everything here...
window.draw(sprite);
window.draw(rectangle);
window.draw(text);
// end the current frame
window.display();
}
}
/*
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <windows.h>
#include "pch.h"
#include <iostream>
struct Box
{
int x1;
int y1;
int x2;
int y2;
};
int win_get_num_video_adapters(void)
{
DISPLAY_DEVICE dd;
int count = 0;
int c = 0;
memset(&dd, 0, sizeof(dd));
dd.cb = sizeof(dd);
while (EnumDisplayDevices(NULL, count, &dd, 0) != false) {
if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
c++;
count++;
}
return c;
}
bool win_get_monitor_info(int adapter, Box* info)
{
DISPLAY_DEVICE dd;
DEVMODE dm;
memset(&dd, 0, sizeof(dd));
dd.cb = sizeof(dd);
if (!EnumDisplayDevices(NULL, adapter, &dd, 0)) {
return false;
}
memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm);
if (!EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) {
return false;
}
// ASSERT(dm.dmFields & DM_PELSHEIGHT);
// ASSERT(dm.dmFields & DM_PELSWIDTH);
// Disabled this assertion for now as it fails under Wine 1.2. //
// ASSERT(dm.dmFields & DM_POSITION); //
info->x1 = dm.dmPosition.x;
info->y1 = dm.dmPosition.y;
info->x2 = info->x1 + dm.dmPelsWidth;
info->y2 = info->y1 + dm.dmPelsHeight;
return true;
}
struct Rect
{
int _x;
int _y;
int _w;
int _h;
};
BOOL CALLBACK MyInfoEnumProc(
HMONITOR hMonitor,
HDC hdcMonitor,
LPRECT lprcMonitor,
LPARAM dwData
)
{
MONITORINFOEX mi;
ZeroMemory(&mi, sizeof(mi));
mi.cbSize = sizeof(mi);
GetMonitorInfo(hMonitor, &mi);
wprintf(L"DisplayDevice: %s\n", mi.szDevice);
return TRUE;
}
sf::View getLetterboxView(sf::View view, int windowWidth, int windowHeight) {
// Compares the aspect ratio of the window to the aspect ratio of the view,
// and sets the view's viewport accordingly in order to archieve a letterbox effect.
// A new view (with a new viewport set) is returned.
float windowRatio = windowWidth / (float)windowHeight;
float viewRatio = view.getSize().x / (float)view.getSize().y;
float sizeX = 1;
float sizeY = 1;
float posX = 0;
float posY = 0;
bool horizontalSpacing = true;
if (windowRatio < viewRatio)
horizontalSpacing = false;
// If horizontalSpacing is true, the black bars will appear on the left and right side.
// Otherwise, the black bars will appear on the top and bottom.
if (horizontalSpacing) {
sizeX = viewRatio / windowRatio;
posX = (1 - sizeX) / 2.f;
}
else {
sizeY = windowRatio / viewRatio;
posY = (1 - sizeY) / 2.f;
}
view.setViewport(sf::FloatRect(posX, posY, sizeX, sizeY));
return view;
}
void getRectMonitor(HWND hwnd, Rect& rect)
{
HMONITOR hMonitor;
MONITORINFO mInfo;
hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
mInfo.cbSize = sizeof(mInfo);
GetMonitorInfo(hMonitor, &mInfo);
rect._x = mInfo.rcMonitor.left;
rect._y = mInfo.rcMonitor.top;
rect._w = mInfo.rcMonitor.right - mInfo.rcMonitor.left;
rect._h = mInfo.rcMonitor.bottom - mInfo.rcMonitor.top;
}
void showMonitorInfo(HWND hwnd)
{
Rect rectMonitor;
getRectMonitor(hwnd, rectMonitor);
std::cout << "--- MONITOR INFOS ---\n";
std::cout << " Position : " << rectMonitor._x << " , " << rectMonitor._y << " \n";
std::cout << " Size : " << rectMonitor._w << " , " << rectMonitor._h << " \n";
std::cout << "----------------------\n";
}
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
int* Count = (int*)dwData;
(*Count)++;
return TRUE;
}
int MonitorCount()
{
int Count = 0;
if (EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&Count))
return Count;
return -1;//signals an error
}
int main()
{
unsigned screenW = 960;
unsigned screenH = 540;
sf::RenderWindow window;
window.create(sf::VideoMode(screenW, screenH), "My window", sf::Style::Default);
HWND hwnd = window.getSystemHandle();
sf::Event event;
sf::Texture texture;
texture.loadFromFile("bg.png");
sf::Sprite sprite(texture);
sf::View view;
view.setSize(screenW, screenH);
view.setCenter(view.getSize().x / 2, view.getSize().y / 2);
view = getLetterboxView(view, screenW, screenH);
sf::CircleShape shape(10.f);
shape.setFillColor(sf::Color::Green);
sf::RectangleShape rectView(sf::Vector2f(screenW, screenH));
rectView.setFillColor(sf::Color(40, 60, 80));
bool isFullScreen = false;
bool keyFull = false;
bool keyTab = false;
bool keyShow = false;
DISPLAY_DEVICE dd;
dd.cb = sizeof(dd);
int deviceIndex = 0;
int monitorIndex = 0;
while (EnumDisplayDevices(0, deviceIndex, &dd, 0))
{
while (EnumDisplayDevices(dd.DeviceName, monitorIndex, &dd, 0))
{
std::cout << dd.DeviceName << ", " << dd.DeviceString << "\n";
++monitorIndex;
}
++deviceIndex;
}
std::cout << "nb Monitor = " << MonitorCount() << "\n";
float x = 10;
window.setFramerateLimit(60);
sf::Vector2i pos = sf::Vector2i(screenW / 2, screenH / 2);
showMonitorInfo(hwnd);
sf::Vector2i savePos;
savePos.x = 0;
savePos.y = 0;
int currentMonitor = 0;
while (window.isOpen())
{
if (!isFullScreen)
{
sf::Vector2i winPos = window.getPosition();
savePos.x = winPos.x;
savePos.y = winPos.y;
}
// on inspecte tous les évènements de la fenêtre qui ont été émis depuis la précédente itération
while (window.pollEvent(event))
{
// évènement "fermeture demandée" : on ferme la fenêtre
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::Resized)
view = getLetterboxView(view, event.size.width, event.size.height);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) window.close();
if (!sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) keyFull = false;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) && !keyFull)
{
keyFull = true;
isFullScreen = !isFullScreen;
if (isFullScreen)
{
std::cout << "FULLSCREEN \n";
Rect rectM;
getRectMonitor(hwnd, rectM);
//showMonitorInfo(hwnd);
std::cout << "rectM = " << rectM._x << " , " << rectM._y;
std::cout << " | " << rectM._w << " , " << rectM._h << "\n";
window.create(sf::VideoMode(rectM._w, rectM._h), "My window", sf::Style::None);
hwnd = window.getSystemHandle();
window.setPosition(sf::Vector2i(rectM._x, rectM._y));
window.setSize(sf::Vector2u(rectM._w, rectM._h));
SetWindowPos(hwnd, HWND_TOPMOST,
0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
SWP_NOMOVE | SWP_NOSIZE);
//window.setFramerateLimit(60);
window.setVerticalSyncEnabled(true);
view = getLetterboxView(view, rectM._w, rectM._h);
window.setView(sf::View(sf::FloatRect(0, 0, rectM._w, rectM._h)));
}
else
{
std::cout << "WINDOWED \n";
window.create(sf::VideoMode(screenW, screenH), "My window", sf::Style::Default);
hwnd = window.getSystemHandle();
window.setPosition(savePos);
window.setFramerateLimit(60);
view = getLetterboxView(view, screenW, screenH);
}
}
if (!sf::Keyboard::isKeyPressed(sf::Keyboard::Tab)) keyTab = false;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Tab) && !keyTab)
{
keyTab = true;
std::cout << "Switch Monitor !\n";
++currentMonitor;
if (currentMonitor > win_get_num_video_adapters() - 1)
currentMonitor = 0;
std::cout << " Current Monitor = " << currentMonitor << "\n";
}
if (!sf::Keyboard::isKeyPressed(sf::Keyboard::S)) keyShow = false;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S) && !keyShow)
{
keyShow = true;
showMonitorInfo(hwnd);
}
float v = 1;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) pos.y += -v;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) pos.y += v;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) pos.x += -v;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) pos.x += v;
x += 1;
if (x > screenW)
x = 0;
//pos = sf::Mouse::getPosition(window);
shape.setPosition(pos.x, pos.y);
sprite.setPosition(x, 0);
window.setView(view);
window.clear();
window.draw(rectView);
window.draw(sprite);
window.draw(shape);
window.display();
}
return 0;
}
*/

View File

@ -190,13 +190,16 @@
<ClCompile Include="sound.cpp" />
<ClCompile Include="utils.cpp" />
<ClCompile Include="value.cpp" />
<ClCompile Include="window.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="character.h" />
<ClInclude Include="comparisons.h" />
<ClInclude Include="Connection.h" />
<ClInclude Include="core.h" />
<ClInclude Include="dms_list.h" />
<ClInclude Include="enviroment.h" />
<ClInclude Include="gui.h" />
<ClInclude Include="Handlers.h" />
<ClInclude Include="chunk.h" />
<ClInclude Include="cmd.h" />
@ -214,6 +217,7 @@
<ClInclude Include="token.h" />
<ClInclude Include="utils.h" />
<ClInclude Include="value.h" />
<ClInclude Include="window.h" />
<ClInclude Include="wrapper.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -43,12 +43,15 @@
<Filter Include="Header Files\DMS\objects">
<UniqueIdentifier>{978b41cd-27e4-4b8c-874e-3b6e927b3d4d}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\DMS\platformdep">
<UniqueIdentifier>{39dc0943-16ca-48a6-b04e-04ba994cfb8d}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\DMS\platformdep">
<UniqueIdentifier>{ef57bfaf-35f9-4b3e-8642-7ee96fb82139}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\multi">
<UniqueIdentifier>{b3c47fc7-ce47-46c5-86b4-827acf0bcbbb}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\DMS\libraries">
<UniqueIdentifier>{584d8d2d-e56e-4a89-a1fe-08a13c3d08a9}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cmd.cpp">
@ -117,6 +120,9 @@
<ClCompile Include="sound.cpp">
<Filter>Source Files\DMS\platformdep</Filter>
</ClCompile>
<ClCompile Include="window.cpp">
<Filter>Source Files\DMS\platformdep</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="value.h">
@ -185,8 +191,17 @@
<ClInclude Include="pch.h">
<Filter>Header Files\DMS</Filter>
</ClInclude>
<ClInclude Include="Connection.h">
<Filter>Header Files\multi</Filter>
</ClInclude>
<ClInclude Include="gui.h">
<Filter>Header Files\DMS\libraries</Filter>
</ClInclude>
<ClInclude Include="sound.h">
<Filter>Header Files\DMS\platformdep</Filter>
<Filter>Header Files\DMS\libraries</Filter>
</ClInclude>
<ClInclude Include="window.h">
<Filter>Header Files\DMS\libraries</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -940,7 +940,13 @@ namespace dms {
if (stream->match(cbracketo)) {
size_t last_line = stream->last().line_num;
std::vector<token> t = stream->next(cbracketo, cbracketc); // Consume and get tokens
if (t.size() == 1) {
t.pop_back();
t.push_back(token{tokens::newline});
}
else {
t.pop_back();
}
tokenstream tempstream(&t);
if (notBalanced(t, last_line, stream, "{", "}"))
return false;

View File

@ -457,9 +457,7 @@ namespace dms {
for (size_t i = 0; i < tokens.size() - 1; i++) {//The lase symbol is parac since that was the consume condition
if (tokens[i].type == tokens::name) {
// We got a name which is refering to a variable so lets build one
value v;
v.type = datatypes::variable; // Special type, it writes data to the string portion, but is interperted as a lookup
v.getString() = tokens[i].name;
value v(tokens[i].name, datatypes::variable);
args.push(v);
}
else if (tokens[i].type == tokens::seperator) {
@ -475,6 +473,10 @@ namespace dms {
}
// If all went well the 'args' now has all of tha params for the method we will be working with
current_chunk->params = args;
for (size_t i = 0; i < args.size(); i++) {
current_chunk->cmds.back()->args.push(args.args[i]);
}
// Thats should be all we need to do
if (stream->peek().type != tokens::bracketc) {
state->push_error(errors::error{ errors::badtoken, "Incomplete function block declaration! Expected ']' to close the block!",true,line,current_chunk });

BIN
DMS/background.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@ -17,7 +17,7 @@ namespace dms {
CHOI, // Done
BLCK, //
CHAR, // Done
WHLE,
WHLE, // Scraped
FUNC, // Done
IFFF, // Done
KNOT, // Done
@ -29,9 +29,9 @@ namespace dms {
JMPZ, // Scraped see [COMP]
INST, // Done
ERRO,
GOTO,
GOTO, // Done
JUMP, // Done
RETN,
RETN, // Done
EXIT, // Done
DEBG,
DSPD, // Todo
@ -48,7 +48,7 @@ namespace dms {
LIST, // Done
LINE, // Done
HALT, // Todo
FILE,
FILE, // Done
GC,
ASID, // Done
OFUN // Done

View File

@ -37,6 +37,7 @@ namespace dms {
errors::error err;
character* speaker = nullptr;
dms_state();
void dump(std::string fn = "dump.bin");
void push_error(errors::error err);
@ -68,6 +69,7 @@ namespace dms {
void pushMem();
void popMem();
bool run();
bool next(memory* mem);
bool run(std::string ent,memory* mem);
bool run(std::string instance);
bool error(std::string);
@ -77,6 +79,17 @@ namespace dms {
private:
// From what I gathered
//std::mutex memory_mutex;
// Next links
codes::op n_code;
cmd* n_c = nullptr;
bool n_halt = false;
size_t n_pos = 0;
size_t n_max = 0;
std::vector<cmd*> n_cmds;
size_t n_ln = 0;
std::string n_temp;
//
void pushMem(memory&);
bool stop = false;
bool init_init = false;

View File

@ -646,4 +646,509 @@ namespace dms {
return true;
}
bool dms_state::next(memory* mem) {
if (n_halt || stop)
return false;
if (!n_cmds.size())
init(chunks["$INIT"], n_pos, n_max, n_cmds);
n_c = n_cmds[n_pos++];
n_code = n_c->opcode;
//debug("(",pos,")> ",*c);
//wait();
switch (n_code)
{
// Handle flags here
case ENTR:
// When reading code from a file the flags are compiled and we need to load them
entry = n_c->args.args[0].getPrintable();
break;
case ENAB:
enable(n_c->args.args[0].getPrintable());
break;
case DISA:
disable(n_c->args.args[0].getPrintable());
break;
case codes::FILE:
cur_file = n_c->args.args[0].getPrintable();
case LOAD:
// Nothing needs to be done here
break;
case VERN:
Sversion = n_c->args.args[0].n;
// Version X.xx
// X: Will not guarantee compatibality. Code breaking changes should be expected especially on lower versions
// xx: Will not break compatibality. They may add features as it goes up the ranks, but those changes do not break older code. If they do they will increase the X part and not the xx part
if (Sversion > Iversion) {
push_error(errors::error{ errors::incompatible_version ,"This script was made for a later version of this interperter!" });
return false;
}
else if ((int)Iversion > (int)(Sversion)) {
push_warning(errors::error{ errors::incompatible_version ,"This script was made for an older version of this interperter, some features might not work!" });
}
break;
case USIN:
// How we add modules into the code. This is the code that actually loads that data!
break;
// Flags handled
case EXIT:
if (n_c->args.args.size()) {
exitcode = (int)n_c->args.args[0].n;
}
return true;
break;
case KNOT:
{
value cmp = n_c->args.args[0];
if (cmp.resolve(this).type == datatypes::boolean || cmp.resolve(this).isNil()) {
if (!cmp.resolve(this).b || cmp.resolve(this).isNil()) {
if (!assign(cmp, value(true))) {
return false;
}
}
else {
if (!assign(cmp, value(false))) {
return false;
}
}
}
else {
if (!assign(cmp, value(false))) {
return false;
}
}
break;
}
case IFFF:
{
value cmp = n_c->args.args[0].resolve(this);
value gt = n_c->args.args[1].resolve(this);
if (cmp.type == datatypes::boolean || cmp.isNil()) {
if (!cmp.b || cmp.isNil()) {
n_pos = seek(gt.getPrintable(), n_cmds, LABL, n_pos);
}
}
break;
}
case GOTO:
{
value labl = n_c->args.args[0];
if (isEnabled("forwardlabels")) {
size_t nnpos = seek(labl.resolve(this).getPrintable(), n_cmds, LABL, n_pos); // Seek from next pos (pos++) to end of cmds
if (!nnpos) {
// This could be a method, it could, but it isn't. We jump to searching from the beginning of the block
goto seek_from_1;
}
else {
n_pos = nnpos;
}
break;
}
seek_from_1:
size_t nnpos = seek(labl.resolve(this).getPrintable(), n_cmds, LABL, 0);
if (!nnpos) {
push_error(errors::error{ errors::choice_unknown ,utils::concat("Unknown label '",labl.resolve(this).getPrintable(),"'!") });
return false;
}
else {
n_pos = nnpos;
}
}
break;
case RETN:
{
value ret = n_c->args.args[0].resolve(this);
//c->args.args[0]->nuke(); // Lets clean this up
return_stack.push(ret);
return true; // We did it, let's return this
}
break;
case OFUN:
{
if (n_c->args.args[0].resolve(this).type == datatypes::custom) {
auto cust = n_c->args.args[0].resolve(this);
auto fname = n_c->args.args[1].getString();
auto assn = n_c->args.args[2];
dms_args args;
for (int i = 3; i < n_c->args.args.size(); i++) {
args.push(n_c->args.args[i]);
}
if (inv_map.count(cust.ctype)) {
Invoker* inv = inv_map[cust.ctype];
auto ret = inv->Invoke(fname, cust.c, this, &args);
if (assn.type != datatypes::nil) {
if (!assign(assn, ret)) {
return false;
}
}
}
else {
error("Custom object not assoiated with any functions!");
}
}
else {
std::string obj = n_c->args.args[0].getPrintable();
if (obj == "nil") {
obj = n_c->args.args[0].getPrintable();
}
std::string funcname = n_c->args.args[1].getPrintable();
value assn = n_c->args.args[2];
dms_args args;
for (int i = 3; i < n_c->args.args.size(); i++) {
args.push(n_c->args.args[i]);
}
value ret;
if (characterExists(obj)) {
ret = getCharacter(obj)->Invoke(funcname, this, &args);
}
else if (environmentExists(obj)) {
ret = getEnvironment(obj)->Invoke(funcname, this, &args);
}
if (ret.type == datatypes::error)
return false;
if (assn.type != datatypes::nil) {
if (!assign(assn, ret)) {
return false;
}
}
}
}
break;
case FUNC:
{
std::string funcname = n_c->args.args[0].getPrintable();
value assn = n_c->args.args[1];
dms_args args;
value ret;
for (int i = 2; i < n_c->args.args.size(); i++) {
args.push(n_c->args.args[i]);
}
// If we have a block made function we don't invoke like normal
if (functionExists(funcname)) {
call_stack.push(funcname);
ret = invoker.Invoke("$BlockInvoke$", this, &args);
}
else {
ret = invoker.Invoke(funcname, this, &args);
}
if (ret.type == datatypes::error)
return false;
if (assn.type != datatypes::nil) {
if (!assign(assn, ret)) {
return false;
}
}
}
break;
case ASID:
{
value env = n_c->args.args[1];
value indx = n_c->args.args[2].resolve(this);
value assn = n_c->args.args[3].resolve(this);
if (env.type == datatypes::block && blockExists(env.getString())) { // If this is a block let's handle this
enviroment* e = nullptr;
if (environments.count(env.getString())) {
e = environments[env.getString()];
}
else if (characters.count(env.getString())) {
e = characters[env.getString()];
}
e->values[indx.getString()] = assn;
}
else if (env.type == datatypes::env) {
if (indx.type == datatypes::number) {
env.e->pushValue(assn);
}
else {
push_error(errors::error{ errors::invalid_type ,concat("Expected a number value got ",datatype[indx.type]) });
return false;
}
}
else if (env.type == datatypes::custom) {
//env.c->NewIndex(indx, assn);
//if(!assign( assn, env->c->Index(indx));
// Call the method within the custom data
}
break;
}
case ADD:
{
value assn = n_c->args.args[0];
value o1 = n_c->args.args[1];
value o2 = n_c->args.args[2];
value ret = o1.resolve(this) + o2.resolve(this);
if (!assign(assn, ret)) {
return false;
}
}
break;
case SUB:
{
value assn = n_c->args.args[0];
value o1 = n_c->args.args[1];
value o2 = n_c->args.args[2];
value ret = o1.resolve(this) - o2.resolve(this);
if (!assign(assn, ret)) {
return false;
}
}
break;
case MUL:
{
value assn = n_c->args.args[0];
value o1 = n_c->args.args[1];
value o2 = n_c->args.args[2];
value ret = o1.resolve(this) * o2.resolve(this);
if (!assign(assn, ret)) {
return false;
}
}
break;
case DIV:
{
value assn = n_c->args.args[0];
value o1 = n_c->args.args[1];
value o2 = n_c->args.args[2];
value ret = o1.resolve(this) / o2.resolve(this);
if (!assign(assn, ret)) {
return false;
}
}
break;
case POW:
{
value assn = n_c->args.args[0];
value o1 = n_c->args.args[1];
value o2 = n_c->args.args[2];
value ret = pow(o1.resolve(this).n, o2.resolve(this).n);
if (!assign(assn, ret)) {
return false;
}
}
break;
case MOD:
{
value assn = n_c->args.args[0];
value o1 = n_c->args.args[1];
value o2 = n_c->args.args[2];
value ret = std::fmod(o1.resolve(this).n, o2.resolve(this).n);
if (!assign(assn, ret)) {
return false;
}
}
break;
case INDX:
{
value assn = n_c->args.args[0];
value env = n_c->args.args[1];
value indx = n_c->args.args[2].resolve(this);
if (env.type == datatypes::block && blockExists(env.getString())) { // If this is a block let's handle this
enviroment* e = nullptr;
if (environments.count(env.getString())) {
e = environments[env.getString()];
}
else if (characters.count(env.getString())) {
e = characters[env.getString()];
}
if (!assign(assn, e->values[indx.getPrintable()])) {
return false;
}
}
else if (env.type == datatypes::env) {
if (indx.type == datatypes::number) {
if (!assign(assn, env.e->getValue(indx))) {
return false;
}
}
else {
push_error(errors::error{ errors::invalid_type ,concat("Expected a number value got ",datatype[indx.type]) });
return false;
}
}
else if (env.type == datatypes::custom) {
//if(!assign( assn, env.c->Index(indx))) {
// return false;
//}
// Call the method within the custom data
}
}
break;
case LIST:
//We need to create an enviroment value then set that
{
dms_list* env = new dms_list;
// Inject the size of the list
env->hpart["$size"] = n_c->args.args[1];
value val = new value;
val.set(env);
if (!assign(n_c->args.args[0], val)) {
return false;
}
}
break;
case INST:
{
value list = (*mem)[n_c->args.args[0].getPrintable()];
list.e->pushValue(n_c->args.args[1]);
}
break;
case COMP:
{
comp cmp = (comp)n_c->args.args[0].i;
value assn = n_c->args.args[1];
value left = n_c->args.args[2].resolve(this);
value right = n_c->args.args[3].resolve(this);
switch (cmp) {
case comp::eq: {
if (!assign(assn, left == right)) {
return false;
}
break;
}
case comp::gt: {
if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; }
if (!assign(assn, left > right)) {
return false;
}
break;
}
case comp::gteq: {
if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; }
if (!assign(assn, left >= right)) {
return false;
}
break;
}
case comp::lt: {
if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; }
if (!assign(assn, left < right)) {
return false;
}
break;
}
case comp::lteq: {
if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; }
if (!assign(assn, left <= right)) {
return false;
}
break;
}
case comp::nteq: {
if (!assign(assn, left != right)) {
return false;
}
break;
}
}
}
break;
case HALT:
//wait();
//sleep(700);
std::cout << std::endl;
break;
case WAIT:
sleep((int)(n_c->args.args[0].n * 1000));
break;
case DSPD:
if (speaker == nullptr) {
push_error(errors::error{ errors::unknown ,utils::concat("A call to set speaker speed, but a speaker has not been defined!") });
return false;
}
else {
speaker->spd = n_c->args.args[0].n;
}
break;
case SSPK:
//Because we are using void* we must cast our pointers
if (characterExists(n_c->args.args[0].getString())) {
speaker = getCharacter(n_c->args.args[0].getString());
if (!handler->handleSpeaker(this, speaker))
return false;
}
else {
push_error(errors::error{ errors::disp_unknown,concat("Unknown character '",n_c->args.args[0].getString(),"'!") });
return false;
}
break;
case APND:
if (!handler->handleMessageAppend(this, n_c->args.args[0].resolve(this).getPrintable()))
return false;
break;
case CHAR:
{
std::string cha = n_c->args.args[0].getString();
getCharacter(cha);
break;
}
case DISP:
{
if (!handler->handleMessageDisplay(this, n_c->args.args[0].resolve(this).getPrintable()))
return false;
}
break;
case ASGN:
if (!assign(n_c->args.args[0], n_c->args.args[1])) {
return false;
}
break;
case LINE:
cur_line = (size_t)n_c->args.args[0].i;
break;
case NOOP:
break;
case CHOI:
//Because we are using void* we must cast our pointers
{
std::vector<std::string> args;
std::string prompt = n_c->args.args[0].getString();
std::string fn = n_c->args.args[1].getString();
for (size_t i = 2; i < n_c->args.args.size(); i++)
args.push_back(n_c->args.args[i].resolve(this).getString());
size_t npos = handler->handleChoice(this, prompt, args);
size_t nnpos = seek(concat("CHOI_", fn, "_", npos), n_cmds, LABL, n_pos);
if (!nnpos) {
push_error(errors::error{ errors::choice_unknown ,utils::concat("Unknown choice!") });
return false;
}
else {
n_pos = nnpos;
}
}
break;
case JUMP:
// Value assert resolves the data so a variable must eventually equal a string
if (utils::valueassert(n_c->args, this, datatypes::string)) {
std::string block = n_c->args.args[0].resolve(this).getString();
if (chunks[block] == NULL) {
push_error(errors::error{ errors::non_existing_block ,utils::concat("Attempted to Jump to a non existing block [",block,"]") });
return false;
}
else if (chunks[block]->type != bt_block) {
push_error(errors::error{ errors::non_existing_block ,utils::concat("Attempted to Jump to a non standard block [",block,"] type: ",getBlockType(chunks[block]->type)) });
return false;
}
else {
init(chunks[block], n_pos, n_max, n_cmds);
}
}
else {
//utils::print(c->args.args[0].type);
datatypes set = n_c->args.args[0].resolve(this).type;
//utils::print("> ",set);
push_error(errors::error{ errors::invalid_arguments, utils::concat("String expected got ",datatype[set]), true, n_ln });
return false;
}
break;
default:
break;
}
if (n_pos == n_max) {
// How did we get here? The end of a block?
return false;
}
return true;
}
}

Binary file not shown.

Binary file not shown.

BIN
DMS/font.ttf Normal file

Binary file not shown.

BIN
DMS/font2.ttf Normal file

Binary file not shown.

142
DMS/gui.h Normal file
View File

@ -0,0 +1,142 @@
#pragma once
#include "window.h"
#include "pch.h"
#include "dms_state.h"
namespace gui {
using namespace std;
using namespace dms;
int __ElementCount = 0;
void init(dms_state* state) {
// While very unlikely it is possible multiple windows to be created! It might be a good idea to support it sometime down the line
window::OnWindowCreated += [](sf::RenderWindow* window) {
};
}
/*
textbox
textbutton
textlabel
frame
imagelabel
imagebutton
anim/sprite
video
*/
enum class gui_types{frame,text,text,image,sprite,video};
struct Dim {
float x;
float y;
Dim() {x = 0;y = 0;}
Dim(const Dim &d) { x = d.x; y = d.y;}
Dim(float x, float y) { this->x = x; this->y = y;}
inline void Set(Dim d) {x = d.x; y = d.y;}
inline void Set(float x, float y) { this->x = x; this->y = y;}
};
struct DualDim {
Dim Position;
Dim Size;
DualDim() {Position.x = 0;Position.y = 0;Size.x = 0;Size.y = 0;}
DualDim(const DualDim& d) { Position = d.Position; Size = d.Size;}
DualDim(Dim pos, Dim size) { Position = pos; Size = size;}
DualDim(float x, float y, float x2, float y2) { Position.x = x; Position.y = y; Size.x = x2; Size.y = y2; }
inline void Set(DualDim d){ Position = d.Position; Size = d.Size;}
inline void Set(Dim pos, Dim size) {Position.x = pos.x;Position.y = pos.y;Size.x = size.x;Size.y = size.y;}
inline void Set(float x, float y, float x2, float y2) { Position.x = x; Position.y = y; Size.x = x2; Size.y = y2;}
};
struct MouseStats {
float x;
float y;
float dx;
float dy;
char button;
MouseStats(Dim pos, char b) {
x = pos.x;
y = pos.y;
button = b;
}
MouseStats(float xx, float yy, char b) {
x = xx;
y = yy;
button = b;
}
MouseStats(float xx, float yy, float dxx, float dyy) {
x = xx;
y = yy;
dx = dxx;
dy = dyy;
button = 0;
}
};
struct Keyboard {
//
};
struct guibase {
//Connections and objects to inheret
multi::connection<MouseStats> OnPressed;
multi::connection<MouseStats> OnReleased;
multi::connection<MouseStats> OnPressedOuter;
multi::connection<MouseStats> OnReleasedOuter;
multi::connection<MouseStats> OnMousedMoved;
multi::connection<MouseStats> WhileHovering;
multi::connection<MouseStats> OnMouseEnter;
multi::connection<MouseStats> OnMouseExit;
multi::connection<gui*> OnUpdate;
};
class gui : guibase {
public:
gui_types Type;
DualDim Offset;
DualDim Scale;
DualDim Absolute;
vector<gui> Children;
bool Visible = true;
//map<string, gui*> Named;
gui() {__ElementCount++;}
gui(DualDim offset, DualDim scale) { Offset = offset; Scale = scale;}
gui(float x,float y,float w,float h,float sx,float sy,float sw,float sh){Offset.Position.x = x;Offset.Position.y = y;Offset.Size.x = w;Offset.Size.y = h;Scale.Position.x = sx;Scale.Position.y = sy;Scale.Size.x = sw;Scale.Size.y = sh;}
void SetDualDim(DualDim offset,DualDim scale) {Offset = offset;Scale = scale;}
virtual void Draw() {
return; // Override this.
}
inline vector<gui>& GetChildren() {return Children;}
inline void GetAllChildren(vector<gui*>& ref) {
auto temp = GetChildren();
for (int i = 0; i < temp.size(); i++) {
ref.push_back(&temp[i]);
temp[i].GetAllChildren(ref);
}
}
inline vector<gui*> GetAllChildren() {
auto temp = GetChildren();
vector<gui*> everything;
everything.reserve(__ElementCount); // Reserve all the current elements that exist
for (int i = 0; i < temp.size(); i++) {
everything.push_back(&temp[i]);
temp[i].GetAllChildren(everything);
}
return everything;
}
};
// Draw Everything
gui _Root;
void Draw() {
auto childs = _Root.GetAllChildren();
for (int i = 0; i < childs.size(); i++) {
childs[i]->Draw();
}
}
}

View File

@ -1,4 +1,5 @@
#pragma once
#include <thread>
#include <iostream>
#include <chrono>
#include <vector>

View File

@ -1,5 +1,4 @@
#pragma once
#include "pch.h"
#include <SFML/Audio.hpp>
#include "dms_state.h"
namespace dms::audio {

View File

@ -17,17 +17,11 @@ music2 = loadMusic("test.ogg")
[main]
// Let's extend the base feature set
music.setPitch(.7)
print(music.getStatus())
music.play()
print(music.getStatus())
print("Type: " + type(music2))
while(music.getStatus()!="stopped"){
wait 1
}
print("Done")
music.setVolume(5)
while(music.getStatus()!="stopped"){}
print("Sound finished!")
// a = 0
// while (true){
// asm {
@ -53,7 +47,7 @@ music2 = loadMusic("test.ogg")
}
}
[player:function(song)]
[player:function(song,food)]
choice "What you wanna do?" {
"play/resume" {
song.play()

22
DMS/window.cpp Normal file
View File

@ -0,0 +1,22 @@
#include "pch.h"
#include "window.h"
namespace dms::window {
Invoker* inv = new Invoker;
void init(dms_state* state) {
/*
inv->registerFunction("getStatus", getStatus);
state->assoiateType("audiostream",inv);
state->invoker.registerFunction("loadMusic", loadMusic);
*/
}
value newWindow(void* self, dms_state* state, dms_args* args) {
if (dms::utils::valueassert(*args, state, datatypes::number, datatypes::number, datatypes::number)) {
}
else if (dms::utils::valueassert(*args, state, datatypes::int64, datatypes::int64, datatypes::int64)) {
}
sf::RenderWindow window(sf::VideoMode(1024, 768, 32), "Background Test");
}
}

14
DMS/window.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "dms_state.h"
#include "utils.h"
#include <stdio.h>
#include "Connection.h"
namespace dms::window {
multi::connection<sf::RenderWindow*> OnWindowCreated;
void init(dms_state*);
bool windowIsReady = false;
std::vector<sf::RenderWindow*> windows;
value newWindow(void*, dms_state*, dms_args*);
}

BIN
background.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
test.ogg Normal file

Binary file not shown.

BIN
test2.ogg Normal file

Binary file not shown.