Substantial progress on renderer among other things
This commit is contained in:
parent
5c14525067
commit
45dc6f63ea
61 changed files with 1370 additions and 606 deletions
Game.csProgram.cs
common
gearbox
interpreter
Environment.csLispPrimitives.csLispProcedure.csMathPrimitives.csPrimitiveProcedure.csProcedure.csReadEvalPrintLoop.csSymbol.cs
expression
reader
AtomToken.csEndOfFileToken.csFakeExpression.csLexer.csParenthesisToken.csParser.csParserExceptions.csParserListVisitor.csParserQuoteVisitor.csParserTopLevelVisitor.csSpecialToken.csStack.csStringToken.csSymbolTable.csToken.csTokenVisitor.cs
renderer
35
Game.cs
35
Game.cs
|
@ -1,11 +1,14 @@
|
|||
using KumiScript.Renderer;
|
||||
using SDL2;
|
||||
|
||||
using KumiScript.Renderer;
|
||||
using KumiScript.Gearbox;
|
||||
|
||||
public class EngineWindow
|
||||
{
|
||||
internal ushort width {get; private set;}
|
||||
internal ushort height {get; private set;}
|
||||
internal string title {get; private set;}
|
||||
|
||||
public EngineWindow(ushort horizontalResolution, ushort verticalResolution, string windowTitle)
|
||||
{
|
||||
width = horizontalResolution;
|
||||
|
@ -17,35 +20,21 @@ public class EngineWindow
|
|||
|
||||
if (SDL_image.IMG_Init(SDL_image.IMG_InitFlags.IMG_INIT_PNG) < 0)
|
||||
throw new Exception("SDL2 Image init failed!");
|
||||
|
||||
if (SDL_ttf.TTF_Init() < 0)
|
||||
throw new Exception("SDL2 ttf init failed!");
|
||||
}
|
||||
|
||||
public void show()
|
||||
{
|
||||
SDLWindow window = new SDLWindow(width, height, title);
|
||||
SDLRenderer renderer = new SDLRenderer(window);
|
||||
bool mainLoop = true;
|
||||
SDL.SDL_Event e;
|
||||
|
||||
Scene s = new Scene(renderer);
|
||||
SceneElement background = new SceneElement(new Background("Resources/Backgrounds/test.png", renderer), 0, 0);
|
||||
SceneElement seiba = new SceneElement(new Sprite("Resources/Sprites/test.png", renderer), 0, 0);
|
||||
s.AddElement(background);
|
||||
s.AddElement(seiba);
|
||||
|
||||
while (mainLoop)
|
||||
GameState state = new GameStateMain(renderer);
|
||||
while (!state.IsQuitting())
|
||||
{
|
||||
while (SDL.SDL_PollEvent(out e) > 0)
|
||||
{
|
||||
switch (e.type)
|
||||
{
|
||||
case SDL.SDL_EventType.SDL_QUIT:
|
||||
mainLoop = false;
|
||||
break;
|
||||
}
|
||||
renderer.Clear();
|
||||
s.DrawScene();
|
||||
renderer.SwapBuffers();
|
||||
}
|
||||
state = state.UpdateState();
|
||||
}
|
||||
renderer.Dispose();
|
||||
window.Dispose();
|
||||
}
|
||||
}
|
|
@ -4,11 +4,11 @@ namespace KumiScript {
|
|||
|
||||
class KumiScript {
|
||||
static void Main (string[] args) {
|
||||
Console.WriteLine(System.IO.Directory.GetCurrentDirectory());
|
||||
/*Console.WriteLine(System.IO.Directory.GetCurrentDirectory());
|
||||
EngineWindow engineWindow = new EngineWindow(800, 600, "KumiScript Unicode");
|
||||
engineWindow.show();
|
||||
/*ReadEvalPrintLoop repl = new ReadEvalPrintLoop(Console.OpenStandardInput(), Console.OpenStandardOutput());
|
||||
repl.Loop();*/
|
||||
engineWindow.show();*/
|
||||
ReadEvalPrintLoop repl = new ReadEvalPrintLoop(Console.OpenStandardInput(), Console.OpenStandardOutput());
|
||||
repl.Loop();
|
||||
}
|
||||
}
|
||||
}
|
166
common/FastLinkedList.cs
Normal file
166
common/FastLinkedList.cs
Normal file
|
@ -0,0 +1,166 @@
|
|||
namespace KumiScript.Common
|
||||
{
|
||||
public class FastLinkedList<T>
|
||||
{
|
||||
ListNode<T>? _first;
|
||||
ListNode<T>? _last;
|
||||
uint _length;
|
||||
public FastLinkedList()
|
||||
{
|
||||
_length = 0;
|
||||
}
|
||||
|
||||
public void InsertLast(T addend)
|
||||
{
|
||||
ListNode<T> n = new ListNode<T>(addend);
|
||||
if (_length == 0)
|
||||
{
|
||||
_first = n;
|
||||
_last = n;
|
||||
_length = 1;
|
||||
return;
|
||||
}
|
||||
_last!.SetNext(n);
|
||||
n.SetPrev(_last);
|
||||
_last = n;
|
||||
_length++;
|
||||
return;
|
||||
}
|
||||
|
||||
public void InsertFirst(T addend)
|
||||
{
|
||||
ListNode<T> n = new ListNode<T>(addend);
|
||||
if (_length == 0)
|
||||
{
|
||||
_first = n;
|
||||
_last = n;
|
||||
_length = 1;
|
||||
return;
|
||||
}
|
||||
_first!.SetPrev(n);
|
||||
n.SetNext(_first);
|
||||
_first = n;
|
||||
_length++;
|
||||
return;
|
||||
}
|
||||
|
||||
private ListNode<T>? FindNth(uint index)
|
||||
{
|
||||
if (index > _length - 1)
|
||||
return null;
|
||||
|
||||
if (index - 1 == _length)
|
||||
return _last;
|
||||
|
||||
ListNode<T>? ni = _first;
|
||||
if (ni is null)
|
||||
return null;
|
||||
|
||||
for (uint i = 0; i < index; i++)
|
||||
{
|
||||
ni = ni!.GetNext();
|
||||
}
|
||||
return ni;
|
||||
}
|
||||
|
||||
public void InsertAfter(uint index, T value)
|
||||
{
|
||||
ListNode<T> nn = new ListNode<T>(value);
|
||||
ListNode<T>? ni = FindNth(index);
|
||||
|
||||
}
|
||||
|
||||
public T? Find(IEqualityComparer<T> eq, T other)
|
||||
{
|
||||
ListNode<T>? n = _first;
|
||||
if (n is null)
|
||||
return default;
|
||||
|
||||
do
|
||||
{
|
||||
T nv = n.GetValue();
|
||||
if (eq.Equals(nv, other))
|
||||
{
|
||||
return nv;
|
||||
}
|
||||
n = n.GetNext();
|
||||
} while (n is not null);
|
||||
return default;
|
||||
}
|
||||
|
||||
public T? GetFirst()
|
||||
{
|
||||
if (_first is null)
|
||||
return default;
|
||||
|
||||
return _first.GetValue();
|
||||
}
|
||||
|
||||
public T? GetLast()
|
||||
{
|
||||
if (_last is null)
|
||||
return default;
|
||||
|
||||
return _last.GetValue();
|
||||
}
|
||||
|
||||
public uint GetLength()
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
}
|
||||
|
||||
internal class ListNode<T>
|
||||
{
|
||||
ListNode<T>? _next;
|
||||
ListNode<T>? _prev;
|
||||
T _value;
|
||||
|
||||
internal ListNode(T value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
internal T GetValue()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
internal void SetValue(T value)
|
||||
{
|
||||
_value = value;
|
||||
return;
|
||||
}
|
||||
|
||||
internal void SetNext(ListNode<T> next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
internal void SetPrev(ListNode<T> prev)
|
||||
{
|
||||
_prev = prev;
|
||||
}
|
||||
|
||||
internal bool HasNext()
|
||||
{
|
||||
return _next is not null;
|
||||
}
|
||||
|
||||
internal bool HasPrev()
|
||||
{
|
||||
return _prev is not null;
|
||||
}
|
||||
|
||||
internal ListNode<T>? GetNext()
|
||||
{
|
||||
return _next;
|
||||
}
|
||||
|
||||
internal ListNode<T>? GetPrev()
|
||||
{
|
||||
return _prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
9
gearbox/GameState.cs
Normal file
9
gearbox/GameState.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace KumiScript.Gearbox
|
||||
{
|
||||
public abstract class GameState
|
||||
{
|
||||
public abstract GameState UpdateState();
|
||||
public abstract void AcceptMessage(StateMessage message);
|
||||
public abstract bool IsQuitting();
|
||||
}
|
||||
}
|
118
gearbox/GameStateMain.cs
Normal file
118
gearbox/GameStateMain.cs
Normal file
|
@ -0,0 +1,118 @@
|
|||
using SDL2;
|
||||
|
||||
using KumiScript.Renderer;
|
||||
using TextBox = KumiScript.Renderer.TextBox;
|
||||
|
||||
namespace KumiScript.Gearbox
|
||||
{
|
||||
public class GameStateMain : GameState
|
||||
{
|
||||
List<Scene> _scenes;
|
||||
Scene _curScene;
|
||||
List<Sprite> _sprites;
|
||||
List<Background> _backgrounds;
|
||||
List<ManagedFont> _fonts;
|
||||
GraphicalUserInterface _graphicalUI;
|
||||
TextBox _bigBox;
|
||||
SDLRenderer _renderer;
|
||||
SDL.SDL_Event e;
|
||||
ulong _tA;
|
||||
ulong _tB;
|
||||
float _delta;
|
||||
|
||||
public GameStateMain(SDLRenderer renderer)
|
||||
{
|
||||
_renderer = renderer;
|
||||
_curScene = new Scene();
|
||||
_scenes = new List<Scene>
|
||||
{
|
||||
_curScene
|
||||
};
|
||||
Sprite seiba = new Sprite("Resources/Sprites/test.png", renderer);
|
||||
_sprites = new List<Sprite> {
|
||||
seiba
|
||||
};
|
||||
Background background = new Background("Resources/Backgrounds/test.png", renderer);
|
||||
_backgrounds = new List<Background>
|
||||
{
|
||||
background
|
||||
};
|
||||
_curScene.AddElement(background);
|
||||
_curScene.AddElement(seiba);
|
||||
_graphicalUI = new GraphicalUserInterface();
|
||||
SDL.SDL_Color color;
|
||||
color.r = 255;
|
||||
color.g = 255;
|
||||
color.b = 255;
|
||||
color.a = 0;
|
||||
ManagedFont font = new ManagedFont("Resources/Fonts/DejaVuSerif.ttf", 36, color, renderer, 256); //ascii
|
||||
_fonts = new List<ManagedFont> {
|
||||
font
|
||||
};
|
||||
Text hello = new Text("Hello, world!", font);
|
||||
Text lorem = new Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", font);
|
||||
_bigBox = new TextBox("Resources/Interface/bigbox.png", renderer, 36, true);
|
||||
_bigBox.AddText(hello);
|
||||
_bigBox.BreakLine();
|
||||
_bigBox.AddText(lorem);
|
||||
_graphicalUI.AddElement(_bigBox);
|
||||
_tA = SDL.SDL_GetPerformanceCounter();
|
||||
_tB = SDL.SDL_GetPerformanceCounter();
|
||||
_delta = 0;
|
||||
}
|
||||
public override void AcceptMessage(StateMessage message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool IsQuitting()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override GameState UpdateState()
|
||||
{
|
||||
_tA = SDL.SDL_GetPerformanceCounter();
|
||||
while (SDL.SDL_PollEvent(out e) > 0)
|
||||
{
|
||||
switch (e.type)
|
||||
{
|
||||
case SDL.SDL_EventType.SDL_QUIT:
|
||||
CleanUp();
|
||||
return new GameStateQuitting();
|
||||
case SDL.SDL_EventType.SDL_KEYUP:
|
||||
switch (e.key.keysym.sym)
|
||||
{
|
||||
case SDL.SDL_Keycode.SDLK_RETURN:
|
||||
_bigBox.UpdateState();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
_tB = _tA;
|
||||
_renderer.Clear();
|
||||
_curScene.DrawScene();
|
||||
_graphicalUI.DrawInterface();
|
||||
_renderer.SwapBuffers();
|
||||
_tB = SDL.SDL_GetPerformanceCounter();
|
||||
_delta = (_tB - _tA) / SDL.SDL_GetPerformanceFrequency() * 1000.0f;
|
||||
SDL.SDL_Delay((uint) (1000/60 - _delta));
|
||||
return this;
|
||||
}
|
||||
|
||||
private void CleanUp()
|
||||
{
|
||||
foreach (Sprite s in _sprites)
|
||||
s.Dispose();
|
||||
|
||||
foreach(Background b in _backgrounds)
|
||||
b.Dispose();
|
||||
|
||||
foreach(ManagedFont f in _fonts)
|
||||
f.Dispose();
|
||||
|
||||
_graphicalUI.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
23
gearbox/GameStateQuitting.cs
Normal file
23
gearbox/GameStateQuitting.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
namespace KumiScript.Gearbox
|
||||
{
|
||||
public class GameStateQuitting : GameState
|
||||
{
|
||||
public GameStateQuitting()
|
||||
{
|
||||
}
|
||||
public override void AcceptMessage(StateMessage message)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override bool IsQuitting()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override GameState UpdateState()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
7
gearbox/StateMessage.cs
Normal file
7
gearbox/StateMessage.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace KumiScript.Gearbox
|
||||
{
|
||||
public abstract class StateMessage
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace KumiScript.Interpreter
|
||||
{
|
||||
public class Environment
|
||||
|
@ -8,11 +6,11 @@ namespace KumiScript.Interpreter
|
|||
readonly Dictionary<Symbol, Expression> _bindings;
|
||||
public Environment()
|
||||
{
|
||||
_bindings = new Dictionary<Symbol, Expression>(SymbolComparer.GetInstance());
|
||||
_bindings = new Dictionary<Symbol, Expression>(ReferenceEqualityComparer.Instance);
|
||||
}
|
||||
public Environment(Environment outer)
|
||||
{
|
||||
_bindings = new Dictionary<Symbol, Expression>(SymbolComparer.GetInstance());
|
||||
_bindings = new Dictionary<Symbol, Expression>(ReferenceEqualityComparer.Instance);
|
||||
_outer = outer;
|
||||
}
|
||||
|
||||
|
@ -40,8 +38,7 @@ namespace KumiScript.Interpreter
|
|||
{
|
||||
if (_bindings.ContainsKey(symbol))
|
||||
{
|
||||
_bindings.Remove(symbol);
|
||||
_bindings.Add(symbol, value);
|
||||
_bindings[symbol] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -51,33 +48,4 @@ namespace KumiScript.Interpreter
|
|||
_outer.RedefineSymbol(symbol, value);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SymbolComparer : IEqualityComparer<Symbol>
|
||||
{
|
||||
private static SymbolComparer? _instance;
|
||||
private SymbolComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public static SymbolComparer GetInstance()
|
||||
{
|
||||
if (_instance is null)
|
||||
_instance = new SymbolComparer();
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public bool Equals(Symbol? x, Symbol? y)
|
||||
{
|
||||
if (x is not Symbol || y is not Symbol)
|
||||
return false;
|
||||
|
||||
return x.Equals(y);
|
||||
}
|
||||
|
||||
public int GetHashCode([DisallowNull] Symbol obj)
|
||||
{
|
||||
return obj.ToString().GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,26 @@
|
|||
using KumiScript.Reader;
|
||||
|
||||
namespace KumiScript.Interpreter
|
||||
{
|
||||
public class LispPrimitives
|
||||
{
|
||||
public static Expression Lambda(ListExpression args, Environment env)
|
||||
public static Expression Lambda(Expression args, Environment env)
|
||||
{
|
||||
Expression car = args.Car();
|
||||
ListExpression rest = args.Cdr();
|
||||
Expression rest = args.Cdr();
|
||||
|
||||
ListExpression? head = car as ListExpression;
|
||||
if (head is null)
|
||||
throw new InterpreterInvalidDefinitionException();
|
||||
|
||||
List<Expression> headl = head.GetMembers();
|
||||
List<Expression> headl = car.GetMembers();
|
||||
List<Symbol> arg_names = new List<Symbol>();
|
||||
for (int i = 0; i < headl.Count; i++)
|
||||
{
|
||||
SymbolExpression? argi = headl[i] as SymbolExpression;
|
||||
if (argi is null)
|
||||
throw new InterpreterInvalidDefinitionException();
|
||||
|
||||
arg_names.Add(argi.GetSymbol());
|
||||
arg_names.Add(headl[i].GetSymbol());
|
||||
}
|
||||
|
||||
Expression body = rest.Car();
|
||||
return new ProcedureExpression(new LispProcedure(arg_names, body, env));
|
||||
}
|
||||
|
||||
public static Expression Quote(ListExpression args, Environment env)
|
||||
public static Expression Quote(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.GetMembers();
|
||||
if (argl.Count != 1)
|
||||
|
@ -35,78 +29,60 @@ namespace KumiScript.Interpreter
|
|||
return argl[0];
|
||||
}
|
||||
|
||||
public static Expression Define(ListExpression args, Environment env)
|
||||
public static Expression Define(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.GetMembers();
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
SymbolExpression? binding = argl[0] as SymbolExpression;
|
||||
if (binding is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
Expression? binding = argl[0];
|
||||
Symbol name = binding.GetSymbol();
|
||||
Expression definition = argl[1].Eval(env);
|
||||
env.AddSymbol(name, definition);
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
public static Expression Car(ListExpression args, Environment env)
|
||||
public static Expression Car(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 1)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
ListExpression? list = argl[0] as ListExpression;
|
||||
if (list is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
return list.Car();
|
||||
|
||||
return argl[0].Car();
|
||||
}
|
||||
|
||||
public static ListExpression Cdr(ListExpression args, Environment env)
|
||||
public static Expression Cdr(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 1)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
ListExpression? list = argl[0] as ListExpression;
|
||||
if (list is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
return list.Cdr();
|
||||
|
||||
return argl[0].Cdr();
|
||||
}
|
||||
|
||||
public static ProperListExpression Cons(ListExpression args, Environment env)
|
||||
public static ProperListExpression Cons(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
Expression car = argl[0];
|
||||
ListExpression? cdr = argl[1] as ListExpression;
|
||||
if (cdr is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
Expression cdr = argl[1];
|
||||
return cdr.Cons(car);
|
||||
}
|
||||
|
||||
public static Expression Quit(ListExpression args, Environment env)
|
||||
public static Expression Quit(Expression args, Environment env)
|
||||
{
|
||||
System.Environment.Exit(0);
|
||||
return new SymbolExpression(new Symbol("bye"));
|
||||
}
|
||||
|
||||
public static Expression Cond(ListExpression args, Environment env)
|
||||
public static Expression Cond(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.GetMembers();
|
||||
for (int i = 0; i < argl.Count; i ++)
|
||||
{
|
||||
ProperListExpression? conditional = argl[i] as ProperListExpression;
|
||||
if (conditional is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
Expression conditional = argl[i];
|
||||
Expression antecedent = conditional.Car();
|
||||
Expression consequent = conditional.Cdr().Car();
|
||||
if (antecedent.Eval(env) != NilExpression.GetInstance())
|
||||
|
@ -115,7 +91,7 @@ namespace KumiScript.Interpreter
|
|||
return NilExpression.GetInstance();
|
||||
}
|
||||
|
||||
public static Expression Eq(ListExpression args, Environment env)
|
||||
public static Expression Eq(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 2)
|
||||
|
@ -127,24 +103,19 @@ namespace KumiScript.Interpreter
|
|||
return NilExpression.GetInstance();
|
||||
}
|
||||
|
||||
public static Expression Set(ListExpression args, Environment env)
|
||||
public static Expression Set(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.GetMembers();
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
SymbolExpression? binding = argl[0] as SymbolExpression;
|
||||
if (binding is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
Symbol name = binding.GetSymbol();
|
||||
Symbol name = argl[0].GetSymbol();
|
||||
Expression definition = argl[1].Eval(env);
|
||||
env.RedefineSymbol(name, definition);
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
public static Expression For(ListExpression args, Environment env)
|
||||
public static Expression For(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.GetMembers();
|
||||
if (argl.Count != 4)
|
||||
|
@ -163,19 +134,18 @@ namespace KumiScript.Interpreter
|
|||
return result;
|
||||
}
|
||||
|
||||
public static Expression Progn(ListExpression args, Environment env)
|
||||
public static Expression Progn(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.GetMembers();
|
||||
Expression result = NilExpression.GetInstance();
|
||||
|
||||
foreach (Expression expr in argl)
|
||||
{
|
||||
result = expr.Eval(env);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Expression Prog1(ListExpression args, Environment env)
|
||||
public static Expression Prog1(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.GetMembers();
|
||||
Expression result = argl.Count > 0 ? argl[0] : NilExpression.GetInstance();
|
||||
|
@ -186,7 +156,7 @@ namespace KumiScript.Interpreter
|
|||
return result;
|
||||
}
|
||||
|
||||
public static Expression Not(ListExpression args, Environment env)
|
||||
public static Expression Not(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 1)
|
||||
|
@ -195,26 +165,18 @@ namespace KumiScript.Interpreter
|
|||
return argl[0] != NilExpression.GetInstance() ? NilExpression.GetInstance() : TrueExpression.GetInstance();
|
||||
}
|
||||
|
||||
public static Expression Nth(ListExpression args, Environment env)
|
||||
public static Expression Nth(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
IntegerExpression? arg0 = argl[0] as IntegerExpression;
|
||||
if (arg0 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
ListExpression? arg1 = argl[1] as ListExpression;
|
||||
if (arg1 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
int n = arg0.GetValueAsInt();
|
||||
List<Expression> arg1l = arg1.GetMembers();
|
||||
int n = (int) argl[0].GetValueAsFloat();
|
||||
List<Expression> arg1l = argl[1].GetMembers();
|
||||
return n >= 0 && n < arg1l.Count ? arg1l[n] : NilExpression.GetInstance();
|
||||
}
|
||||
|
||||
public static Expression While(ListExpression args, Environment env)
|
||||
public static Expression While(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.GetMembers();
|
||||
if (argl.Count != 2)
|
||||
|
@ -234,22 +196,22 @@ namespace KumiScript.Interpreter
|
|||
public static Environment RegisterPrimitives()
|
||||
{
|
||||
Environment result = new Environment();
|
||||
result.AddSymbol(new Symbol("lambda"), new ProcedureExpression(new PrimitiveProcedure(Lambda)));
|
||||
result.AddSymbol(new Symbol("quote"), new ProcedureExpression(new PrimitiveProcedure(Quote)));
|
||||
result.AddSymbol(new Symbol("define"), new ProcedureExpression(new PrimitiveProcedure(Define)));
|
||||
result.AddSymbol(new Symbol("car"), new ProcedureExpression(new PrimitiveProcedure(Car)));
|
||||
result.AddSymbol(new Symbol("cdr"), new ProcedureExpression(new PrimitiveProcedure(Cdr)));
|
||||
result.AddSymbol(new Symbol("cons"), new ProcedureExpression(new PrimitiveProcedure(Cons)));
|
||||
result.AddSymbol(new Symbol("quit"), new ProcedureExpression(new PrimitiveProcedure(Quit)));
|
||||
result.AddSymbol(new Symbol("cond"), new ProcedureExpression(new PrimitiveProcedure(Cond)));
|
||||
result.AddSymbol(new Symbol("eq"), new ProcedureExpression(new PrimitiveProcedure(Eq)));
|
||||
result.AddSymbol(new Symbol("set!"), new ProcedureExpression(new PrimitiveProcedure(Set)));
|
||||
result.AddSymbol(new Symbol("for"), new ProcedureExpression(new PrimitiveProcedure(For)));
|
||||
result.AddSymbol(new Symbol("progn"), new ProcedureExpression(new PrimitiveProcedure(Progn)));
|
||||
result.AddSymbol(new Symbol("not"), new ProcedureExpression(new PrimitiveProcedure(Not)));
|
||||
result.AddSymbol(new Symbol("prog1"), new ProcedureExpression(new PrimitiveProcedure(Prog1)));
|
||||
result.AddSymbol(new Symbol("nth"), new ProcedureExpression(new PrimitiveProcedure(Nth)));
|
||||
result.AddSymbol(new Symbol("while"), new ProcedureExpression(new PrimitiveProcedure(While)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("lambda"), new ProcedureExpression(new PrimitiveProcedure(Lambda)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("quote"), new ProcedureExpression(new PrimitiveProcedure(Quote)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("define"), new ProcedureExpression(new PrimitiveProcedure(Define)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("car"), new ProcedureExpression(new PrimitiveProcedure(Car)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("cdr"), new ProcedureExpression(new PrimitiveProcedure(Cdr)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("cons"), new ProcedureExpression(new PrimitiveProcedure(Cons)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("quit"), new ProcedureExpression(new PrimitiveProcedure(Quit)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("cond"), new ProcedureExpression(new PrimitiveProcedure(Cond)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("eq"), new ProcedureExpression(new PrimitiveProcedure(Eq)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("set!"), new ProcedureExpression(new PrimitiveProcedure(Set)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("for"), new ProcedureExpression(new PrimitiveProcedure(For)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("progn"), new ProcedureExpression(new PrimitiveProcedure(Progn)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("not"), new ProcedureExpression(new PrimitiveProcedure(Not)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("prog1"), new ProcedureExpression(new PrimitiveProcedure(Prog1)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("nth"), new ProcedureExpression(new PrimitiveProcedure(Nth)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("while"), new ProcedureExpression(new PrimitiveProcedure(While)));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace KumiScript.Interpreter
|
|||
_closureEnv = closureEnv;
|
||||
}
|
||||
|
||||
public override Expression ApplyWithArgs(ListExpression args, Environment env)
|
||||
public override Expression ApplyWithArgs(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> evaluatedArgs = args.EvalMembers(env);
|
||||
if (_parameters.Count != evaluatedArgs.Count)
|
||||
|
@ -40,5 +40,10 @@ namespace KumiScript.Interpreter
|
|||
{
|
||||
return string.Concat("λ(", string.Join(' ', _parameters), ")");
|
||||
}
|
||||
|
||||
public List<Symbol> GetParameters()
|
||||
{
|
||||
return _parameters;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,211 +1,127 @@
|
|||
using System.Reflection.Metadata.Ecma335;
|
||||
using KumiScript.Reader;
|
||||
|
||||
namespace KumiScript.Interpreter
|
||||
{
|
||||
public class MathPrimitives
|
||||
{
|
||||
public static NumberExpression Plus(ListExpression args, Environment env)
|
||||
public static NumberExpression Plus(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
decimal acc = 0;
|
||||
for (int i = 0; i < argl.Count; i++)
|
||||
{
|
||||
NumberExpression? argin = argl[i] as NumberExpression;
|
||||
if (argin is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
acc += argin.GetValueAsFloat();
|
||||
acc += argl[i].GetValueAsFloat();
|
||||
}
|
||||
|
||||
return NumberFactory.NormalizeFloat(acc);
|
||||
return new NumberExpression(acc);
|
||||
}
|
||||
|
||||
public static NumberExpression Minus(ListExpression args, Environment env)
|
||||
public static NumberExpression Minus(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count == 0)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
NumberExpression? argn0 = argl[0] as NumberExpression;
|
||||
if (argn0 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
decimal acc = argn0.GetValueAsFloat();
|
||||
decimal acc = argl[0].GetValueAsFloat();
|
||||
if (argl.Count == 1)
|
||||
return NumberFactory.NormalizeFloat(1 - acc);
|
||||
return new NumberExpression(1 - acc);
|
||||
|
||||
for (int i = 1; i < argl.Count; i++)
|
||||
{
|
||||
NumberExpression? argin = argl[i] as NumberExpression;
|
||||
if (argin is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
acc -= argin.GetValueAsFloat();
|
||||
acc -= argl[i].GetValueAsFloat();
|
||||
}
|
||||
return NumberFactory.NormalizeFloat(acc);
|
||||
return new NumberExpression(acc);
|
||||
}
|
||||
|
||||
public static NumberExpression Times(ListExpression args, Environment env)
|
||||
public static NumberExpression Times(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count < 2)
|
||||
throw new InterpreterInvalidInvocationException();
|
||||
|
||||
NumberExpression? arg0 = argl[0] as NumberExpression;
|
||||
if (arg0 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
decimal f = arg0.GetValueAsFloat();
|
||||
decimal f = argl[0].GetValueAsFloat();
|
||||
for (int i = 1; i < argl.Count; i++)
|
||||
{
|
||||
NumberExpression? argn = argl[i] as NumberExpression;
|
||||
if (argn is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
f *= argn.GetValueAsFloat();
|
||||
f *= argl[i].GetValueAsFloat();
|
||||
}
|
||||
return NumberFactory.NormalizeFloat(f);
|
||||
return new NumberExpression(f);
|
||||
}
|
||||
|
||||
public static NumberExpression DividedBy(ListExpression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
NumberExpression? arg0 = argl[0] as NumberExpression;
|
||||
if (arg0 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
NumberExpression? arg1 = argl[1] as NumberExpression;
|
||||
if (arg1 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
return NumberFactory.NormalizeFloat(arg0.GetValueAsFloat() / arg1.GetValueAsFloat());
|
||||
}
|
||||
|
||||
public static NumberExpression Modulus(ListExpression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
NumberExpression? arg0 = argl[0] as NumberExpression;
|
||||
if (arg0 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
NumberExpression? arg1 = argl[1] as NumberExpression;
|
||||
if (arg1 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
return NumberFactory.NormalizeFloat(arg0.GetValueAsFloat() % arg1.GetValueAsFloat());
|
||||
}
|
||||
|
||||
public static Expression GreaterThan(ListExpression args, Environment env)
|
||||
public static NumberExpression DividedBy(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
NumberExpression? arg0 = argl[0] as NumberExpression;
|
||||
if (arg0 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
NumberExpression? arg1 = argl[1] as NumberExpression;
|
||||
if (arg1 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
return arg0.GetValueAsFloat() > arg1.GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance();
|
||||
return new NumberExpression(argl[0].GetValueAsFloat() / argl[1].GetValueAsFloat());
|
||||
}
|
||||
public static Expression LessThan(ListExpression args, Environment env)
|
||||
|
||||
public static NumberExpression Modulus(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
NumberExpression? arg0 = argl[0] as NumberExpression;
|
||||
if (arg0 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
NumberExpression? arg1 = argl[1] as NumberExpression;
|
||||
if (arg1 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
return arg0.GetValueAsFloat() < arg1.GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance();
|
||||
return new NumberExpression(argl[0].GetValueAsFloat() % argl[1].GetValueAsFloat());
|
||||
}
|
||||
|
||||
public static Expression LessThanEquals(ListExpression args, Environment env)
|
||||
public static Expression GreaterThan(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
NumberExpression? arg0 = argl[0] as NumberExpression;
|
||||
if (arg0 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
NumberExpression? arg1 = argl[1] as NumberExpression;
|
||||
if (arg1 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
return arg0.GetValueAsFloat() <= arg1.GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance();
|
||||
return argl[0].GetValueAsFloat() > argl[1].GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance();
|
||||
}
|
||||
|
||||
public static Expression GreaterThanEquals(ListExpression args, Environment env)
|
||||
public static Expression LessThan(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
NumberExpression? arg0 = argl[0] as NumberExpression;
|
||||
if (arg0 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
NumberExpression? arg1 = argl[1] as NumberExpression;
|
||||
if (arg1 is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
return arg0.GetValueAsFloat() >= arg1.GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance();
|
||||
return argl[0].GetValueAsFloat() < argl[1].GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance();
|
||||
}
|
||||
|
||||
public static Expression PlusPlus(ListExpression args, Environment env)
|
||||
public static Expression LessThanEquals(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
return argl[0].GetValueAsFloat() <= argl[1].GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance();
|
||||
}
|
||||
|
||||
public static Expression GreaterThanEquals(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.EvalMembers(env);
|
||||
if (argl.Count != 2)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
return argl[0].GetValueAsFloat() >= argl[1].GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance();
|
||||
}
|
||||
|
||||
public static Expression PlusPlus(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.GetMembers();
|
||||
if (argl.Count != 1)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
SymbolExpression? binding = argl[0] as SymbolExpression;
|
||||
if (binding is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
Symbol name = binding.GetSymbol();
|
||||
Symbol name = argl[0].GetSymbol();
|
||||
Expression val = env.Lookup(name);
|
||||
NumberExpression? num = val as NumberExpression;
|
||||
if (num is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
NumberExpression nump = NumberFactory.NormalizeFloat(num.GetValueAsFloat() + 1);
|
||||
NumberExpression nump = new NumberExpression(val.GetValueAsFloat() + 1);
|
||||
env.RedefineSymbol(name, nump);
|
||||
return nump;
|
||||
}
|
||||
|
||||
public static Expression MinusMinus(ListExpression args, Environment env)
|
||||
public static Expression MinusMinus(Expression args, Environment env)
|
||||
{
|
||||
List<Expression> argl = args.GetMembers();
|
||||
if (argl.Count != 1)
|
||||
throw new InterpreterInvalidApplicationException();
|
||||
|
||||
SymbolExpression? binding = argl[0] as SymbolExpression;
|
||||
if (binding is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
Symbol name = binding.GetSymbol();
|
||||
Symbol name = argl[0].GetSymbol();
|
||||
Expression val = env.Lookup(name);
|
||||
NumberExpression? num = val as NumberExpression;
|
||||
if (num is null)
|
||||
throw new InterpreterTypingException();
|
||||
|
||||
NumberExpression nump = NumberFactory.NormalizeFloat(num.GetValueAsFloat() - 1);
|
||||
NumberExpression nump = new NumberExpression(val.GetValueAsFloat() - 1);
|
||||
env.RedefineSymbol(name, nump);
|
||||
return nump;
|
||||
}
|
||||
|
@ -213,17 +129,17 @@ namespace KumiScript.Interpreter
|
|||
public static Environment RegisterPrimitives(Environment outer)
|
||||
{
|
||||
Environment result = new Environment(outer);
|
||||
result.AddSymbol(new Symbol("+"), new ProcedureExpression(new PrimitiveProcedure(Plus)));
|
||||
result.AddSymbol(new Symbol("-"), new ProcedureExpression(new PrimitiveProcedure(Minus)));
|
||||
result.AddSymbol(new Symbol("*"), new ProcedureExpression(new PrimitiveProcedure(Times)));
|
||||
result.AddSymbol(new Symbol("/"), new ProcedureExpression(new PrimitiveProcedure(DividedBy)));
|
||||
result.AddSymbol(new Symbol("%"), new ProcedureExpression(new PrimitiveProcedure(Modulus)));
|
||||
result.AddSymbol(new Symbol(">"), new ProcedureExpression(new PrimitiveProcedure(GreaterThan)));
|
||||
result.AddSymbol(new Symbol("<"), new ProcedureExpression(new PrimitiveProcedure(LessThan)));
|
||||
result.AddSymbol(new Symbol("<="), new ProcedureExpression(new PrimitiveProcedure(LessThanEquals)));
|
||||
result.AddSymbol(new Symbol(">="), new ProcedureExpression(new PrimitiveProcedure(GreaterThanEquals)));
|
||||
result.AddSymbol(new Symbol("++!"), new ProcedureExpression(new PrimitiveProcedure(PlusPlus)));
|
||||
result.AddSymbol(new Symbol("--!"), new ProcedureExpression(new PrimitiveProcedure(MinusMinus)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("+"), new ProcedureExpression(new PrimitiveProcedure(Plus)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("-"), new ProcedureExpression(new PrimitiveProcedure(Minus)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("*"), new ProcedureExpression(new PrimitiveProcedure(Times)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("/"), new ProcedureExpression(new PrimitiveProcedure(DividedBy)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("%"), new ProcedureExpression(new PrimitiveProcedure(Modulus)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString(">"), new ProcedureExpression(new PrimitiveProcedure(GreaterThan)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("<"), new ProcedureExpression(new PrimitiveProcedure(LessThan)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("<="), new ProcedureExpression(new PrimitiveProcedure(LessThanEquals)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString(">="), new ProcedureExpression(new PrimitiveProcedure(GreaterThanEquals)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("++!"), new ProcedureExpression(new PrimitiveProcedure(PlusPlus)));
|
||||
result.AddSymbol(SymbolTable.GetInstance().FromString("--!"), new ProcedureExpression(new PrimitiveProcedure(MinusMinus)));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@ namespace KumiScript.Interpreter
|
|||
{
|
||||
public class PrimitiveProcedure : Procedure
|
||||
{
|
||||
public delegate Expression PrimitiveDelegate(ListExpression args, Environment env);
|
||||
public delegate Expression PrimitiveDelegate(Expression args, Environment env);
|
||||
readonly PrimitiveDelegate _function;
|
||||
public PrimitiveProcedure(PrimitiveDelegate function)
|
||||
{
|
||||
_function = function;
|
||||
}
|
||||
|
||||
public override Expression ApplyWithArgs(ListExpression args, Environment env)
|
||||
public override Expression ApplyWithArgs(Expression args, Environment env)
|
||||
{
|
||||
return _function(args, env);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace KumiScript.Interpreter
|
|||
{
|
||||
}
|
||||
|
||||
public abstract Expression ApplyWithArgs(ListExpression args, Environment env);
|
||||
public abstract Expression ApplyWithArgs(Expression args, Environment env);
|
||||
public abstract bool IsPrimitive();
|
||||
}
|
||||
}
|
|
@ -24,9 +24,9 @@ namespace KumiScript.Interpreter
|
|||
Expression expr = parser.NextTopLevelExpression();
|
||||
try
|
||||
{
|
||||
Expression result = expr.Eval(top);
|
||||
streamWriter.Write(string.Format("{0}\n", result.ToString()));
|
||||
streamWriter.Flush();
|
||||
Expression result = expr.Eval(top);
|
||||
streamWriter.Write(string.Format("{0}\n", result.ToString()));
|
||||
streamWriter.Flush();
|
||||
} catch (Exception ex) {
|
||||
if (ex is InterpreterInvalidApplicationException
|
||||
or InterpreterInvalidDefinitionException
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace KumiScript.Interpreter
|
|||
|
||||
public bool Equals(Symbol s)
|
||||
{
|
||||
return s.ToString() == _name;
|
||||
return ReferenceEquals(this, s);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
|
|
@ -1,12 +1,70 @@
|
|||
namespace KumiScript.Interpreter
|
||||
{
|
||||
public abstract class Expression
|
||||
public class Expression
|
||||
{
|
||||
public Expression()
|
||||
public virtual Expression Eval(Environment env)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public abstract Expression Eval(Environment env);
|
||||
public abstract bool Equals(Expression expr);
|
||||
public virtual decimal GetValueAsFloat()
|
||||
{
|
||||
throw new InterpreterTypingException();
|
||||
}
|
||||
|
||||
public virtual Expression Car()
|
||||
{
|
||||
throw new InterpreterTypingException();
|
||||
}
|
||||
|
||||
public virtual Expression Cdr()
|
||||
{
|
||||
throw new InterpreterTypingException();
|
||||
}
|
||||
|
||||
public virtual ProperListExpression Cons(Expression expr)
|
||||
{
|
||||
throw new InterpreterTypingException();
|
||||
}
|
||||
|
||||
public virtual ProperListExpression AppendToList(Expression expr)
|
||||
{
|
||||
List<Expression> el = new List<Expression>(2)
|
||||
{
|
||||
this,
|
||||
expr
|
||||
};
|
||||
return new ProperListExpression(el);
|
||||
}
|
||||
|
||||
public virtual List<Expression> EvalMembers(Environment env)
|
||||
{
|
||||
throw new InterpreterTypingException();
|
||||
}
|
||||
|
||||
public virtual List<Expression> GetMembers()
|
||||
{
|
||||
throw new InterpreterTypingException();
|
||||
}
|
||||
|
||||
public virtual Symbol GetSymbol()
|
||||
{
|
||||
throw new InterpreterTypingException();
|
||||
}
|
||||
|
||||
public virtual Expression Apply(Expression operand, Environment env)
|
||||
{
|
||||
throw new InterpreterTypingException();
|
||||
}
|
||||
|
||||
public virtual bool IsPrimitive()
|
||||
{
|
||||
throw new InterpreterTypingException();
|
||||
}
|
||||
|
||||
public virtual bool Equals (Expression expr)
|
||||
{
|
||||
return ReferenceEquals(this, expr);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
using System.Numerics;
|
||||
|
||||
namespace KumiScript.Interpreter
|
||||
{
|
||||
public class FloatExpression : NumberExpression
|
||||
{
|
||||
readonly decimal _value;
|
||||
public FloatExpression(decimal f)
|
||||
{
|
||||
_value = f;
|
||||
}
|
||||
|
||||
public override bool Equals(Expression expr)
|
||||
{
|
||||
NumberExpression? nexpr = expr as NumberExpression;
|
||||
if (nexpr is null)
|
||||
return false;
|
||||
|
||||
return nexpr.GetValueAsFloat() == _value;
|
||||
}
|
||||
|
||||
public override Expression Eval(Environment env)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
public override decimal GetValueAsFloat()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
public override int GetValueAsInt()
|
||||
{
|
||||
return (int) _value;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return _value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
using System.Numerics;
|
||||
|
||||
namespace KumiScript.Interpreter
|
||||
{
|
||||
public class IntegerExpression : NumberExpression
|
||||
{
|
||||
readonly int _value;
|
||||
public IntegerExpression(int n)
|
||||
{
|
||||
_value = n;
|
||||
}
|
||||
|
||||
public override bool Equals(Expression expr)
|
||||
{
|
||||
NumberExpression? nexpr = expr as NumberExpression;
|
||||
if (nexpr is null)
|
||||
return false;
|
||||
|
||||
return nexpr.GetValueAsFloat() == _value;
|
||||
}
|
||||
|
||||
public override Expression Eval(Environment env)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public override decimal GetValueAsFloat()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
public override int GetValueAsInt()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return _value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
namespace KumiScript.Interpreter
|
||||
{
|
||||
public abstract class ListExpression : Expression
|
||||
{
|
||||
public ListExpression()
|
||||
{
|
||||
}
|
||||
|
||||
public abstract Expression Car();
|
||||
public abstract ListExpression Cdr();
|
||||
public abstract ProperListExpression Cons(Expression expr);
|
||||
public abstract List<Expression> EvalMembers(Environment env);
|
||||
public abstract List<Expression> GetMembers();
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ namespace KumiScript.Interpreter
|
|||
{
|
||||
public class ListFactory
|
||||
{
|
||||
public static ListExpression MakeList(List<Expression> expressions)
|
||||
public static Expression MakeList(List<Expression> expressions)
|
||||
{
|
||||
if (expressions.Any())
|
||||
return new ProperListExpression(expressions);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace KumiScript.Interpreter
|
||||
{
|
||||
public class NilExpression : ListExpression
|
||||
public class NilExpression : Expression
|
||||
{
|
||||
private static NilExpression? _instance;
|
||||
private NilExpression()
|
||||
|
@ -20,7 +20,7 @@ namespace KumiScript.Interpreter
|
|||
return this;
|
||||
}
|
||||
|
||||
public override ListExpression Cdr()
|
||||
public override Expression Cdr()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
@ -30,16 +30,6 @@ namespace KumiScript.Interpreter
|
|||
return new ProperListExpression(new List<Expression> {expr});
|
||||
}
|
||||
|
||||
public override bool Equals(Expression expr)
|
||||
{
|
||||
return expr is NilExpression;
|
||||
}
|
||||
|
||||
public override Expression Eval(Environment env)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public override List<Expression> EvalMembers(Environment env)
|
||||
{
|
||||
return new List<Expression>();
|
||||
|
|
|
@ -1,12 +1,35 @@
|
|||
namespace KumiScript.Interpreter
|
||||
{
|
||||
public abstract class NumberExpression : Expression
|
||||
public class NumberExpression : Expression
|
||||
{
|
||||
public NumberExpression()
|
||||
decimal _value;
|
||||
|
||||
public NumberExpression(decimal value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public abstract decimal GetValueAsFloat();
|
||||
public abstract int GetValueAsInt();
|
||||
public override decimal GetValueAsFloat()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return _value.ToString();
|
||||
}
|
||||
|
||||
public override bool Equals(Expression expr)
|
||||
{
|
||||
try
|
||||
{
|
||||
decimal d = expr.GetValueAsFloat();
|
||||
return d == _value;
|
||||
}
|
||||
catch (InterpreterTypingException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
namespace KumiScript.Interpreter
|
||||
{
|
||||
public class NumberFactory
|
||||
{
|
||||
public static NumberExpression NormalizeFloat(decimal f)
|
||||
{
|
||||
//TODO: Handle overflows
|
||||
int i = (int) f;
|
||||
if (i == f)
|
||||
return new IntegerExpression(i);
|
||||
|
||||
return new FloatExpression(f);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@ namespace KumiScript.Interpreter
|
|||
return this;
|
||||
}
|
||||
|
||||
public Expression Apply(ListExpression args, Environment env)
|
||||
public override Expression Apply(Expression args, Environment env)
|
||||
{
|
||||
return _proc.ApplyWithArgs(args, env);
|
||||
}
|
||||
|
@ -34,18 +34,9 @@ namespace KumiScript.Interpreter
|
|||
return string.Format("#Procedure<{0}>", _proc.ToString());
|
||||
}
|
||||
|
||||
public override bool Equals(Expression expr)
|
||||
public override bool IsPrimitive()
|
||||
{
|
||||
ProcedureExpression? pe = expr as ProcedureExpression;
|
||||
if (pe is null)
|
||||
return false;
|
||||
|
||||
return _proc.Equals(pe._proc);
|
||||
}
|
||||
|
||||
public Procedure GetProcedure()
|
||||
{
|
||||
return _proc;
|
||||
return _proc.IsPrimitive();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace KumiScript.Interpreter
|
||||
{
|
||||
public class ProperListExpression : ListExpression
|
||||
public class ProperListExpression : Expression
|
||||
{
|
||||
readonly List<Expression> _values;
|
||||
public ProperListExpression(List<Expression> expressions)
|
||||
|
@ -10,11 +10,8 @@ namespace KumiScript.Interpreter
|
|||
|
||||
public override Expression Eval(Environment env)
|
||||
{
|
||||
ProcedureExpression? rator = Car().Eval(env) as ProcedureExpression;
|
||||
if (rator is null)
|
||||
throw new InterpreterInvalidInvocationException();
|
||||
|
||||
ListExpression rand = Cdr();
|
||||
Expression rator = Car().Eval(env);
|
||||
Expression rand = Cdr();
|
||||
return rator.Apply(rand, env);
|
||||
}
|
||||
|
||||
|
@ -34,24 +31,18 @@ namespace KumiScript.Interpreter
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Concat("(",
|
||||
String.Join(' ', (object[]) _values.ToArray()),
|
||||
return string.Concat("(",
|
||||
string.Join(' ', (object[]) _values.ToArray()),
|
||||
")");
|
||||
}
|
||||
|
||||
public override Expression Car()
|
||||
{
|
||||
if (_values.Count == 0)
|
||||
return this;
|
||||
|
||||
return _values.First();
|
||||
}
|
||||
|
||||
public override ListExpression Cdr()
|
||||
public override Expression Cdr()
|
||||
{
|
||||
if (_values.Count == 0)
|
||||
return this;
|
||||
|
||||
List<Expression> rest = new List<Expression>(_values);
|
||||
rest.RemoveAt(0);
|
||||
return ListFactory.MakeList(rest);
|
||||
|
@ -64,13 +55,11 @@ namespace KumiScript.Interpreter
|
|||
return new ProperListExpression(consd);
|
||||
}
|
||||
|
||||
public override bool Equals(Expression expr)
|
||||
public override ProperListExpression AppendToList(Expression expr)
|
||||
{
|
||||
ProperListExpression? lexpr = expr as ProperListExpression;
|
||||
if (lexpr is null)
|
||||
return false;
|
||||
|
||||
return lexpr.GetMembers().SequenceEqual(_values);
|
||||
List<Expression> appended = new List<Expression>(_values);
|
||||
appended.Append(expr);
|
||||
return new ProperListExpression(appended);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,23 +8,9 @@ namespace KumiScript.Interpreter
|
|||
_value = str;
|
||||
}
|
||||
|
||||
public override bool Equals(Expression expr)
|
||||
{
|
||||
StringExpression? se = expr as StringExpression;
|
||||
if (se is null)
|
||||
return false;
|
||||
|
||||
return _value == se._value;
|
||||
}
|
||||
|
||||
public override Expression Eval(Environment env)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return _value;
|
||||
return "\"" + _value + "\"";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,21 +8,12 @@ namespace KumiScript.Interpreter
|
|||
_value = s;
|
||||
}
|
||||
|
||||
public override bool Equals(Expression expr)
|
||||
{
|
||||
SymbolExpression? sy = expr as SymbolExpression;
|
||||
if (sy is null)
|
||||
return false;
|
||||
|
||||
return _value.Equals(sy._value);
|
||||
}
|
||||
|
||||
public override Expression Eval(Environment env)
|
||||
{
|
||||
return env.Lookup(_value);
|
||||
}
|
||||
|
||||
public Symbol GetSymbol()
|
||||
public override Symbol GetSymbol()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
@ -31,5 +22,18 @@ namespace KumiScript.Interpreter
|
|||
{
|
||||
return _value.ToString();
|
||||
}
|
||||
|
||||
public override bool Equals(Expression expr)
|
||||
{
|
||||
try
|
||||
{
|
||||
Symbol s = expr.GetSymbol();
|
||||
return s != _value;
|
||||
}
|
||||
catch (InterpreterTypingException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,16 +15,6 @@ namespace KumiScript.Interpreter
|
|||
return _instance;
|
||||
}
|
||||
|
||||
public override bool Equals(Expression expr)
|
||||
{
|
||||
return expr is TrueExpression;
|
||||
}
|
||||
|
||||
public override Expression Eval(Environment env)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "t";
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace KumiScript.Reader
|
|||
{
|
||||
decimal f;
|
||||
if (decimal.TryParse(_value, out f))
|
||||
return NumberFactory.NormalizeFloat(f);
|
||||
return new NumberExpression(f);
|
||||
|
||||
if (_value == "null")
|
||||
return NilExpression.GetInstance();
|
||||
|
@ -27,7 +27,7 @@ namespace KumiScript.Reader
|
|||
if (_value == "t")
|
||||
return TrueExpression.GetInstance();
|
||||
|
||||
return new SymbolExpression(new Symbol(_value));
|
||||
return new SymbolExpression(SymbolTable.GetInstance().FromString(_value));
|
||||
}
|
||||
|
||||
public override string GetValue()
|
22
reader/FakeExpression.cs
Normal file
22
reader/FakeExpression.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using KumiScript.Interpreter;
|
||||
|
||||
namespace KumiScript.Reader
|
||||
{
|
||||
public class FakeExpression : Expression
|
||||
{
|
||||
static FakeExpression? _instance;
|
||||
|
||||
private FakeExpression()
|
||||
{
|
||||
_instance = this;
|
||||
}
|
||||
|
||||
public static FakeExpression GetInstance()
|
||||
{
|
||||
if (_instance is null)
|
||||
return new FakeExpression();
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,17 +28,15 @@ namespace KumiScript.Reader
|
|||
public Expression VisitParen(ParenthesisToken paren)
|
||||
{
|
||||
if (!paren._leftParen)
|
||||
return null; //TODO: some other way of throwing it back
|
||||
return FakeExpression.GetInstance(); //TODO: some other way of throwing it back
|
||||
|
||||
List<Expression> list = new List<Expression>();
|
||||
Expression item = _parser.NextExpressionCC(this);
|
||||
|
||||
while (item is not null)
|
||||
while (!ReferenceEquals(item, FakeExpression.GetInstance()))
|
||||
{
|
||||
list.Add(item);
|
||||
item = _parser.NextExpressionCC(this);
|
||||
}
|
||||
|
||||
return ListFactory.MakeList(list);
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ namespace KumiScript.Reader
|
|||
{
|
||||
List<Expression> quotedAtom = new List<Expression>
|
||||
{
|
||||
new SymbolExpression(new Symbol("quote")),
|
||||
new SymbolExpression(SymbolTable.GetInstance().FromString("quote")),
|
||||
atom.ToExpression()
|
||||
};
|
||||
return new ProperListExpression(quotedAtom);
|
||||
|
@ -33,7 +33,7 @@ namespace KumiScript.Reader
|
|||
List<Expression> list = new List<Expression>();
|
||||
ParserListVisitor listVisitor = new ParserListVisitor(_parser);
|
||||
Expression item = _parser.NextExpressionCC(listVisitor);
|
||||
while (item is not null)
|
||||
while (!ReferenceEquals(item, FakeExpression.GetInstance()))
|
||||
{
|
||||
list.Add(item);
|
||||
item = _parser.NextExpressionCC(listVisitor);
|
||||
|
@ -41,7 +41,7 @@ namespace KumiScript.Reader
|
|||
Expression listExpression = ListFactory.MakeList(list);
|
||||
List<Expression> quotedList = new List<Expression>
|
||||
{
|
||||
new SymbolExpression(new Symbol("quote")),
|
||||
new SymbolExpression(SymbolTable.GetInstance().FromString("quote")),
|
||||
listExpression
|
||||
};
|
||||
return new ProperListExpression(quotedList);
|
||||
|
@ -56,7 +56,7 @@ namespace KumiScript.Reader
|
|||
{
|
||||
List<Expression> quotedString = new List<Expression>
|
||||
{
|
||||
new SymbolExpression(new Symbol("quote")),
|
||||
new SymbolExpression(SymbolTable.GetInstance().FromString("quote")),
|
||||
str.ToExpression()
|
||||
};
|
||||
return new ProperListExpression(quotedString);
|
|
@ -34,7 +34,7 @@ namespace KumiScript.Reader
|
|||
ParserListVisitor listVisitor = new ParserListVisitor(_parser);
|
||||
Expression item = _parser.NextExpressionCC(listVisitor);
|
||||
|
||||
while (item is not null)
|
||||
while (!ReferenceEquals(item, FakeExpression.GetInstance()))
|
||||
{
|
||||
list.Add(item);
|
||||
item = _parser.NextExpressionCC(listVisitor);
|
36
reader/SymbolTable.cs
Normal file
36
reader/SymbolTable.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using KumiScript.Interpreter;
|
||||
|
||||
namespace KumiScript.Reader
|
||||
{
|
||||
public class SymbolTable
|
||||
{
|
||||
static SymbolTable? _instance;
|
||||
readonly Dictionary<string, Symbol> _table;
|
||||
|
||||
private SymbolTable()
|
||||
{
|
||||
_instance = this;
|
||||
_table = new Dictionary<string, Symbol>();
|
||||
}
|
||||
|
||||
public static SymbolTable GetInstance()
|
||||
{
|
||||
if (_instance is null)
|
||||
return new SymbolTable();
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public Symbol FromString(string s)
|
||||
{
|
||||
Symbol? sym;
|
||||
_table.TryGetValue(s, out sym);
|
||||
if (sym is null)
|
||||
{
|
||||
sym = new Symbol(s);
|
||||
_table.Add(s, sym);
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,44 +1,59 @@
|
|||
using KumiScript.Loader;
|
||||
using SDL2;
|
||||
|
||||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class Background : IDrawable
|
||||
public class Background : SceneElement, IDisposable
|
||||
{
|
||||
SDLTexture _texture;
|
||||
SDLRenderer _renderer;
|
||||
Image _image;
|
||||
int _height;
|
||||
int _width;
|
||||
int _anim;
|
||||
int _frame;
|
||||
|
||||
public Background(string path, SDLRenderer renderer)
|
||||
{
|
||||
_texture = new SDLTexture(path, renderer);
|
||||
_renderer = renderer;
|
||||
_image = new Image(path, renderer);
|
||||
KSMetaParser parser = new KSMetaParser(string.Concat(path, ".ksmeta"));
|
||||
_width = parser.GetAttribute("width");
|
||||
_height = parser.GetAttribute("height");
|
||||
_anim = 0;
|
||||
_frame = 0;
|
||||
}
|
||||
|
||||
public void Draw(int x, int y)
|
||||
public void Dispose()
|
||||
{
|
||||
SDL.SDL_RenderCopy(_renderer.id, _image.GetTexture().id, 0, 0);
|
||||
_texture.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
public int GetBitmapHeight()
|
||||
public override void Draw(int x, int y)
|
||||
{
|
||||
return _height;
|
||||
SDL.SDL_Rect destRect = new SDL.SDL_Rect();
|
||||
destRect.x = x;
|
||||
destRect.y = y;
|
||||
destRect.w = 800;
|
||||
destRect.h = 600;
|
||||
|
||||
SDL.SDL_Rect sourceRect = new SDL.SDL_Rect();
|
||||
sourceRect.x = _anim * _width;
|
||||
sourceRect.y = _frame * _height;
|
||||
sourceRect.w = _width;
|
||||
sourceRect.h = _height;
|
||||
|
||||
_texture.Draw(_renderer, sourceRect, destRect);
|
||||
}
|
||||
|
||||
public int GetBitmapWidth()
|
||||
public override int GetBitmapHeight()
|
||||
{
|
||||
return _width;
|
||||
return 600;
|
||||
}
|
||||
|
||||
public int GetXOffset()
|
||||
public override int GetBitmapWidth()
|
||||
{
|
||||
return 0;
|
||||
return 800;
|
||||
}
|
||||
|
||||
public int GetYOffset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
29
renderer/DummyText.cs
Normal file
29
renderer/DummyText.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class DummyText : Text
|
||||
{
|
||||
public DummyText(string text, ManagedFont font) : base(text, font)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Draw(int x, int y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override void DrawWrapping(int x, int y, int maxw, int spacing, int retw, char delim, out int penx, out int peny)
|
||||
{
|
||||
penx = retw;
|
||||
peny = y + spacing;
|
||||
return;
|
||||
}
|
||||
|
||||
public override bool DrawWrappingAnimate(int x, int y, int maxw, int spacing, int retw, char delim, out int penx, out int peny)
|
||||
{
|
||||
penx = retw;
|
||||
peny = y + spacing;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
101
renderer/Glyph.cs
Normal file
101
renderer/Glyph.cs
Normal file
|
@ -0,0 +1,101 @@
|
|||
using SDL2;
|
||||
|
||||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class Glyph : IDisposable
|
||||
{
|
||||
readonly char _char;
|
||||
readonly int _width;
|
||||
readonly int _height;
|
||||
SDLTexture _tex;
|
||||
SDLRenderer _renderer;
|
||||
|
||||
public Glyph(char c, SDLFont font, SDL.SDL_Color clr, SDLRenderer renderer)
|
||||
{
|
||||
_char = c;
|
||||
nint surface = SDL_ttf.TTF_RenderGlyph32_Blended(font.GetHandle(), c, clr);
|
||||
_tex = new SDLTexture(surface, renderer);
|
||||
SDL.SDL_FreeSurface(surface);
|
||||
_tex.QueryTexture(out _, out _, out _width, out _height);
|
||||
_renderer = renderer;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_tex.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
public char GetCharacter()
|
||||
{
|
||||
return _char;
|
||||
}
|
||||
|
||||
public SDLTexture GetTexture()
|
||||
{
|
||||
return _tex;
|
||||
}
|
||||
|
||||
public int GetWidth()
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
|
||||
public void DrawAt(int x, int y)
|
||||
{
|
||||
SDL.SDL_Rect destRect;
|
||||
destRect.x = x;
|
||||
destRect.y = y;
|
||||
destRect.w = _width;
|
||||
destRect.h = _height;
|
||||
|
||||
SDL.SDL_Rect sourceRect;
|
||||
sourceRect.x = 0;
|
||||
sourceRect.y = 0;
|
||||
sourceRect.w = _width;
|
||||
sourceRect.h = _height;
|
||||
|
||||
_tex.Draw(_renderer, sourceRect, destRect);
|
||||
}
|
||||
|
||||
public void DrawAdvancePen(int x, int y, out int pen)
|
||||
{
|
||||
SDL.SDL_Rect destRect;
|
||||
destRect.x = x;
|
||||
destRect.y = y;
|
||||
destRect.w = _width;
|
||||
destRect.h = _height;
|
||||
|
||||
SDL.SDL_Rect sourceRect;
|
||||
sourceRect.x = 0;
|
||||
sourceRect.y = 0;
|
||||
sourceRect.w = _width;
|
||||
sourceRect.h = _height;
|
||||
|
||||
_tex.Draw(_renderer, sourceRect, destRect);
|
||||
pen = x + _width;
|
||||
}
|
||||
|
||||
internal void DrawAdvancePenModAlpha(int x, int y, out int pen, byte v)
|
||||
{
|
||||
_tex.SetAlpha(v);
|
||||
|
||||
SDL.SDL_Rect destRect;
|
||||
destRect.x = x;
|
||||
destRect.y = y;
|
||||
destRect.w = _width;
|
||||
destRect.h = _height;
|
||||
|
||||
SDL.SDL_Rect sourceRect;
|
||||
sourceRect.x = 0;
|
||||
sourceRect.y = 0;
|
||||
sourceRect.w = _width;
|
||||
sourceRect.h = _height;
|
||||
|
||||
_tex.Draw(_renderer, sourceRect, destRect);
|
||||
_tex.SetAlpha(255);
|
||||
pen = x + _width;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
36
renderer/GraphicalUserInterface.cs
Normal file
36
renderer/GraphicalUserInterface.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class GraphicalUserInterface : IDisposable
|
||||
{
|
||||
List<InterfaceElement> _elements;
|
||||
public GraphicalUserInterface()
|
||||
{
|
||||
_elements = new List<InterfaceElement>(16);
|
||||
}
|
||||
|
||||
public void DrawInterface()
|
||||
{
|
||||
foreach (InterfaceElement e in _elements)
|
||||
{
|
||||
e.Draw(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddElement(InterfaceElement e)
|
||||
{
|
||||
_elements.Add(e);
|
||||
return;
|
||||
}
|
||||
|
||||
public bool RemoveElement(InterfaceElement e)
|
||||
{
|
||||
return _elements.Remove(e);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (InterfaceElement e in _elements)
|
||||
e.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,5 @@ namespace KumiScript.Renderer
|
|||
void Draw(int x, int y);
|
||||
int GetBitmapWidth();
|
||||
int GetBitmapHeight();
|
||||
int GetXOffset();
|
||||
int GetYOffset();
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
using SDL2;
|
||||
|
||||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class Image
|
||||
{
|
||||
SDLRenderer _renderer;
|
||||
SDLTexture _texture;
|
||||
|
||||
public Image(string path, SDLRenderer renderer)
|
||||
{
|
||||
_renderer = renderer;
|
||||
_texture = new SDLTexture(path, renderer);
|
||||
}
|
||||
|
||||
public SDLTexture GetTexture()
|
||||
{
|
||||
return _texture;
|
||||
}
|
||||
}
|
||||
}
|
13
renderer/InterfaceElement.cs
Normal file
13
renderer/InterfaceElement.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace KumiScript.Renderer
|
||||
{
|
||||
public abstract class InterfaceElement : IDrawable, IDisposable
|
||||
{
|
||||
public abstract void Click();
|
||||
public abstract void OnMouseover();
|
||||
public abstract void OnMouseout();
|
||||
public abstract void Draw(int x, int y);
|
||||
public abstract int GetBitmapHeight();
|
||||
public abstract int GetBitmapWidth();
|
||||
public abstract void Dispose();
|
||||
}
|
||||
}
|
73
renderer/ManagedFont.cs
Normal file
73
renderer/ManagedFont.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
using SDL2;
|
||||
|
||||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class ManagedFont : IDisposable
|
||||
{
|
||||
SDLFont _font;
|
||||
int _cachesize;
|
||||
SDL.SDL_Color _color;
|
||||
SDLRenderer _renderer;
|
||||
Dictionary<char, Glyph> _glyphs;
|
||||
LinkedList<char> _incidence;
|
||||
|
||||
public ManagedFont(string path, int points, SDL.SDL_Color color, SDLRenderer renderer, int num_cache)
|
||||
{
|
||||
_font = new SDLFont(path, points);
|
||||
_renderer = renderer;
|
||||
_color = color;
|
||||
_glyphs = new Dictionary<char, Glyph>();
|
||||
_incidence = new LinkedList<char>();
|
||||
_cachesize = num_cache;
|
||||
}
|
||||
|
||||
public Glyph GetGlyph(char c)
|
||||
{
|
||||
UpdateFreq(c);
|
||||
Glyph? g;
|
||||
if (!_glyphs.TryGetValue(c, out g))
|
||||
return CacheGlyph(c);
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
private Glyph CacheGlyph(char c)
|
||||
{
|
||||
if (_glyphs.Count >= _cachesize)
|
||||
PurgeCache();
|
||||
|
||||
Glyph g = new Glyph(c, _font, _color, _renderer);
|
||||
_glyphs.Add(c, g);
|
||||
return g;
|
||||
}
|
||||
|
||||
private void UpdateFreq(char c)
|
||||
{
|
||||
_incidence.Remove(c);
|
||||
_incidence.AddFirst(c);
|
||||
return;
|
||||
}
|
||||
|
||||
private void PurgeCache()
|
||||
{
|
||||
for (int i = _cachesize - 1; i > _cachesize * .75; i--)
|
||||
{
|
||||
char c = _incidence.Last();
|
||||
Glyph g = _glyphs[c];
|
||||
_glyphs.Remove(c);
|
||||
g.Dispose();
|
||||
_incidence.RemoveLast();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
List<Glyph> glyphs = _glyphs.Values.ToList();
|
||||
foreach (Glyph g in glyphs)
|
||||
g.Dispose();
|
||||
|
||||
_font.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,11 +2,9 @@ namespace KumiScript.Renderer
|
|||
{
|
||||
public class Scene
|
||||
{
|
||||
SDLRenderer _renderer;
|
||||
List<SceneElement> _elements;
|
||||
public Scene(SDLRenderer renderer)
|
||||
public Scene()
|
||||
{
|
||||
_renderer = renderer;
|
||||
_elements = new List<SceneElement>(16);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,9 @@
|
|||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class SceneElement
|
||||
public abstract class SceneElement : IDrawable
|
||||
{
|
||||
IDrawable _elem;
|
||||
int _x;
|
||||
int _y;
|
||||
public SceneElement(IDrawable elem, int xPos, int yPos)
|
||||
{
|
||||
_elem = elem;
|
||||
_x = xPos;
|
||||
_y = yPos;
|
||||
}
|
||||
|
||||
public void Draw(int sceneX, int sceneY)
|
||||
{
|
||||
_elem.Draw(_x + sceneX, _y + sceneY);
|
||||
return;
|
||||
}
|
||||
public abstract void Draw(int x, int y);
|
||||
public abstract int GetBitmapHeight();
|
||||
public abstract int GetBitmapWidth();
|
||||
}
|
||||
}
|
|
@ -1,56 +1,59 @@
|
|||
using System.Text.Json.Serialization;
|
||||
using KumiScript.Loader;
|
||||
using SDL2;
|
||||
|
||||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class Sprite : IDrawable
|
||||
public class Sprite : SceneElement, IDisposable
|
||||
{
|
||||
readonly SDLRenderer _renderer;
|
||||
readonly Image _image;
|
||||
SDL.SDL_Rect _drawCoords;
|
||||
SDLTexture _texture;
|
||||
SDLRenderer _renderer;
|
||||
readonly int _height;
|
||||
readonly int _width;
|
||||
readonly int _xOffset;
|
||||
readonly int _yOffset;
|
||||
int _anim;
|
||||
int _frame;
|
||||
|
||||
public Sprite(string path, SDLRenderer renderer)
|
||||
{
|
||||
_texture = new SDLTexture(path, renderer);
|
||||
_renderer = renderer;
|
||||
_image = new Image(path, renderer);
|
||||
KSMetaParser parser = new KSMetaParser(string.Concat(path, ".ksmeta"));
|
||||
_height = parser.GetAttribute("height");
|
||||
_width = parser.GetAttribute("width");
|
||||
_xOffset = parser.GetAttribute("xOffset");
|
||||
_yOffset = parser.GetAttribute("yOffset");
|
||||
_drawCoords.w = _width;
|
||||
_drawCoords.h = _height;
|
||||
_height = parser.GetAttribute("height");
|
||||
_anim = 0;
|
||||
_frame = 0;
|
||||
}
|
||||
|
||||
public void Draw(int x, int y)
|
||||
public void Dispose()
|
||||
{
|
||||
_drawCoords.x = x + _xOffset;
|
||||
_drawCoords.y = y + _yOffset;
|
||||
SDL.SDL_RenderCopy(_renderer.id, _image.GetTexture().id, 0, ref _drawCoords);
|
||||
_texture.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
public int GetBitmapHeight()
|
||||
public override void Draw(int x, int y)
|
||||
{
|
||||
SDL.SDL_Rect destRect = new SDL.SDL_Rect();
|
||||
destRect.x = x;
|
||||
destRect.y = y;
|
||||
destRect.w = _width;
|
||||
destRect.h = _height;
|
||||
|
||||
SDL.SDL_Rect sourceRect = new SDL.SDL_Rect();
|
||||
sourceRect.x = _anim * _width;
|
||||
sourceRect.y = _frame * _height;
|
||||
sourceRect.w = _width;
|
||||
sourceRect.h = _height;
|
||||
|
||||
_texture.Draw(_renderer, sourceRect, destRect);
|
||||
}
|
||||
|
||||
public override int GetBitmapHeight()
|
||||
{
|
||||
return _height;
|
||||
}
|
||||
|
||||
public int GetBitmapWidth()
|
||||
public override int GetBitmapWidth()
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
|
||||
public int GetXOffset()
|
||||
{
|
||||
return _xOffset;
|
||||
}
|
||||
|
||||
public int GetYOffset()
|
||||
{
|
||||
return _yOffset;
|
||||
}
|
||||
}
|
||||
}
|
149
renderer/Text.cs
Normal file
149
renderer/Text.cs
Normal file
|
@ -0,0 +1,149 @@
|
|||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class Text : InterfaceElement
|
||||
{
|
||||
readonly string _text;
|
||||
readonly ManagedFont _font;
|
||||
string[]? _words;
|
||||
int _progress;
|
||||
int _animProg;
|
||||
readonly int _charcount;
|
||||
|
||||
public Text(string text, ManagedFont font)
|
||||
{
|
||||
_text = text;
|
||||
_font = font;
|
||||
_progress = 0;
|
||||
_animProg = -24;
|
||||
_charcount = text.Length;
|
||||
}
|
||||
|
||||
public override void Click()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Draw(int x, int y)
|
||||
{
|
||||
foreach (char c in _text)
|
||||
{
|
||||
Glyph g = _font.GetGlyph(c);
|
||||
g.DrawAdvancePen(x, y, out x);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void DrawWrapping(int x, int y, int maxw, int spacing, int retw, char delim, out int penx, out int peny)
|
||||
{
|
||||
if (_words is null)
|
||||
_words = _text.Split(delim);
|
||||
|
||||
int spacew = _font.GetGlyph(delim).GetWidth();
|
||||
penx = x;
|
||||
peny = y;
|
||||
foreach (string word in _words)
|
||||
{
|
||||
int w = 0;
|
||||
Glyph[] gs = new Glyph[word.Length];
|
||||
for (int i = 0; i < word.Length; i++)
|
||||
{
|
||||
gs[i] = _font.GetGlyph(word[i]);
|
||||
w += gs[i].GetWidth();
|
||||
}
|
||||
if (penx + w >= maxw)
|
||||
{
|
||||
penx = retw;
|
||||
peny += spacing;
|
||||
}
|
||||
foreach (Glyph g in gs)
|
||||
g.DrawAdvancePen(penx, peny, out penx);
|
||||
|
||||
penx += spacew;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public virtual bool DrawWrappingAnimate(int x, int y, int maxw, int spacing, int retw, char delim, out int penx, out int peny)
|
||||
{
|
||||
int c = 2;
|
||||
int dist;
|
||||
_animProg += 24;
|
||||
if (_words is null)
|
||||
_words = _text.Split(delim);
|
||||
|
||||
int spacew = _font.GetGlyph(delim).GetWidth();
|
||||
penx = x;
|
||||
peny = y;
|
||||
foreach (string word in _words)
|
||||
{
|
||||
int w = 0;
|
||||
Glyph[] gs = new Glyph[word.Length];
|
||||
for (int i = 0; i < word.Length; i++)
|
||||
{
|
||||
gs[i] = _font.GetGlyph(word[i]);
|
||||
w += gs[i].GetWidth();
|
||||
}
|
||||
if (penx + w >= maxw)
|
||||
{
|
||||
penx = retw;
|
||||
peny += spacing;
|
||||
}
|
||||
foreach (Glyph g in gs)
|
||||
{
|
||||
if (_animProg >= 60)
|
||||
{
|
||||
_animProg = 0;
|
||||
_progress++;
|
||||
}
|
||||
dist = _progress - c;
|
||||
if (dist > 0)
|
||||
{
|
||||
g.DrawAdvancePen(penx, peny, out penx);
|
||||
c++;
|
||||
}
|
||||
else if (dist < -4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
g.DrawAdvancePenModAlpha(penx, peny, out penx, (byte) (255 + dist * 42));
|
||||
c++;
|
||||
}
|
||||
}
|
||||
penx += spacew;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetBitmapHeight()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override int GetBitmapWidth()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void OnMouseout()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override void OnMouseover()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public void ForceProgress()
|
||||
{
|
||||
_progress = _charcount;
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
176
renderer/TextBox.cs
Normal file
176
renderer/TextBox.cs
Normal file
|
@ -0,0 +1,176 @@
|
|||
using KumiScript.Loader;
|
||||
using SDL2;
|
||||
|
||||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class TextBox : InterfaceElement
|
||||
{
|
||||
SDLTexture _texture;
|
||||
readonly SDLRenderer _renderer;
|
||||
int _width;
|
||||
int _height;
|
||||
int _hpadding;
|
||||
int _vpadding;
|
||||
int _linespacing;
|
||||
readonly bool _consecutive;
|
||||
List<Text> _texts;
|
||||
List<Text> _textsQueue;
|
||||
TextBoxState _state;
|
||||
|
||||
private enum TextBoxState
|
||||
{
|
||||
StateRenderLine,
|
||||
StateWaitEnter,
|
||||
StateDone
|
||||
}
|
||||
|
||||
public TextBox(string path, SDLRenderer renderer, bool consecutive)
|
||||
{
|
||||
_texture = new SDLTexture(path, renderer);
|
||||
_renderer = renderer;
|
||||
KSMetaParser parser = new KSMetaParser(string.Concat(path, ".ksmeta"));
|
||||
_width = parser.GetAttribute("width");
|
||||
_height = parser.GetAttribute("height");
|
||||
_hpadding = parser.GetAttribute("hpadding");
|
||||
_vpadding = parser.GetAttribute("vpadding");
|
||||
_linespacing = parser.GetAttribute("linespacing");
|
||||
_texts = new List<Text>(8);
|
||||
_textsQueue = new List<Text>(8);
|
||||
_consecutive = consecutive;
|
||||
if (consecutive)
|
||||
_state = TextBoxState.StateRenderLine;
|
||||
else
|
||||
_state = TextBoxState.StateDone;
|
||||
}
|
||||
|
||||
public TextBox(string path, SDLRenderer renderer, int linespacing, bool consecutive)
|
||||
{
|
||||
_texture = new SDLTexture(path, renderer);
|
||||
_renderer = renderer;
|
||||
KSMetaParser parser = new KSMetaParser(string.Concat(path, ".ksmeta"));
|
||||
_width = parser.GetAttribute("width");
|
||||
_height = parser.GetAttribute("height");
|
||||
_hpadding = parser.GetAttribute("hpadding");
|
||||
_vpadding = parser.GetAttribute("vpadding");
|
||||
_linespacing = linespacing;
|
||||
_texts = new List<Text>(8);
|
||||
_textsQueue = new List<Text>(8);
|
||||
_consecutive = consecutive;
|
||||
if (consecutive)
|
||||
_state = TextBoxState.StateRenderLine;
|
||||
else
|
||||
_state = TextBoxState.StateDone;
|
||||
}
|
||||
|
||||
public override void Click()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_texture.Dispose();
|
||||
}
|
||||
|
||||
public override void Draw(int x, int y)
|
||||
{
|
||||
SDL.SDL_Rect destRect = new SDL.SDL_Rect();
|
||||
destRect.x = x;
|
||||
destRect.y = y;
|
||||
destRect.w = _width;
|
||||
destRect.h = _height;
|
||||
|
||||
SDL.SDL_Rect sourceRect = new SDL.SDL_Rect();
|
||||
sourceRect.x = 0;
|
||||
sourceRect.y = 0;
|
||||
sourceRect.w = _width;
|
||||
sourceRect.h = _height;
|
||||
|
||||
_texture.Draw(_renderer, sourceRect, destRect);
|
||||
int retw = x + _hpadding;
|
||||
int penx = retw;
|
||||
int peny = y + _vpadding;
|
||||
foreach (Text t in _texts)
|
||||
{
|
||||
t.DrawWrapping(penx, peny, _width - _hpadding, _linespacing, retw, ' ', out penx, out peny);
|
||||
}
|
||||
if (_state == TextBoxState.StateRenderLine)
|
||||
{
|
||||
Text t2 = _textsQueue.First();
|
||||
bool done = t2.DrawWrappingAnimate(penx, peny, _width - _hpadding, _linespacing, retw, ' ', out penx, out peny);
|
||||
if (done)
|
||||
{
|
||||
_texts.Add(t2);
|
||||
_textsQueue.RemoveAt(0);
|
||||
_state = _textsQueue.Any() ? TextBoxState.StateWaitEnter : TextBoxState.StateDone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void BreakLine()
|
||||
{
|
||||
AddText(new DummyText("", null));
|
||||
}
|
||||
|
||||
public void AddText(Text t)
|
||||
{
|
||||
if (_consecutive)
|
||||
_textsQueue.Add(t);
|
||||
else
|
||||
_texts.Add(t);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public void UpdateState()
|
||||
{
|
||||
switch(_state)
|
||||
{
|
||||
case TextBoxState.StateRenderLine:
|
||||
SkipLine();
|
||||
return;
|
||||
case TextBoxState.StateWaitEnter:
|
||||
_state = TextBoxState.StateRenderLine;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private void SkipLine()
|
||||
{
|
||||
Text t = _textsQueue.First();
|
||||
t.ForceProgress();
|
||||
return;
|
||||
}
|
||||
|
||||
public void ClearText()
|
||||
{
|
||||
_texts.Clear();
|
||||
}
|
||||
|
||||
public bool IsDone()
|
||||
{
|
||||
return _state == TextBoxState.StateDone;
|
||||
}
|
||||
|
||||
public override int GetBitmapHeight()
|
||||
{
|
||||
return _height;
|
||||
}
|
||||
|
||||
public override int GetBitmapWidth()
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
|
||||
public override void OnMouseout()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override void OnMouseover()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
26
renderer/sdl/SDLFont.cs
Normal file
26
renderer/sdl/SDLFont.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using SDL2;
|
||||
|
||||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class SDLFont : IDisposable
|
||||
{
|
||||
nint _handle;
|
||||
public SDLFont(string path, int points)
|
||||
{
|
||||
_handle = SDL_ttf.TTF_OpenFont(path, points);
|
||||
if (_handle == 0)
|
||||
throw new Exception(SDL_ttf.TTF_GetError());
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
SDL_ttf.TTF_CloseFont(_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
public nint GetHandle()
|
||||
{
|
||||
return _handle;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,12 +2,12 @@ using SDL2;
|
|||
|
||||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class SDLRenderer
|
||||
public class SDLRenderer : IDisposable
|
||||
{
|
||||
internal readonly nint id;
|
||||
internal SDLRenderer(SDLWindow window)
|
||||
{
|
||||
id = SDL.SDL_CreateRenderer(window.Id, -1, SDL.SDL_RendererFlags.SDL_RENDERER_ACCELERATED);
|
||||
id = SDL.SDL_CreateRenderer(window.Id, -1, SDL.SDL_RendererFlags.SDL_RENDERER_ACCELERATED | SDL.SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC);
|
||||
if (id == 0)
|
||||
throw new Exception("Failed to create renderer!");
|
||||
}
|
||||
|
@ -17,6 +17,11 @@ namespace KumiScript.Renderer
|
|||
SDL.SDL_RenderClear(id);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
SDL.SDL_DestroyRenderer(id);
|
||||
}
|
||||
|
||||
public void SwapBuffers()
|
||||
{
|
||||
SDL.SDL_RenderPresent(id);
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace KumiScript.Renderer
|
|||
{
|
||||
public class SDLTexture : IDisposable
|
||||
{
|
||||
internal readonly nint id;
|
||||
readonly nint _id;
|
||||
public SDLTexture(string path, SDLRenderer renderer)
|
||||
{
|
||||
nint surface = SDL_image.IMG_Load(path);
|
||||
|
@ -16,11 +16,39 @@ namespace KumiScript.Renderer
|
|||
throw new Exception(SDL.SDL_GetError());
|
||||
|
||||
SDL.SDL_FreeSurface(surface);
|
||||
id = texture;
|
||||
_id = texture;
|
||||
}
|
||||
|
||||
public SDLTexture(nint surface, SDLRenderer renderer)
|
||||
{
|
||||
nint texture = SDL.SDL_CreateTextureFromSurface(renderer.id, surface);
|
||||
if (texture == 0)
|
||||
throw new Exception(SDL.SDL_GetError());
|
||||
|
||||
_id = texture;
|
||||
}
|
||||
|
||||
public void Draw(SDLRenderer renderer, SDL.SDL_Rect sourceRect, SDL.SDL_Rect destRect)
|
||||
{
|
||||
SDL.SDL_RenderCopy(renderer.id, _id, ref sourceRect, ref destRect);
|
||||
return;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
SDL.SDL_DestroyTexture(id);
|
||||
SDL.SDL_DestroyTexture(_id);
|
||||
return;
|
||||
}
|
||||
|
||||
public void QueryTexture(out uint format, out int access, out int width, out int height)
|
||||
{
|
||||
SDL.SDL_QueryTexture(_id, out format, out access, out width, out height);
|
||||
return;
|
||||
}
|
||||
|
||||
public void SetAlpha(byte alpha)
|
||||
{
|
||||
SDL.SDL_SetTextureAlphaMod(_id, alpha);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ using SDL2;
|
|||
|
||||
namespace KumiScript.Renderer
|
||||
{
|
||||
public class SDLWindow
|
||||
public class SDLWindow : IDisposable
|
||||
{
|
||||
internal readonly nint Id;
|
||||
ushort _width;
|
||||
|
@ -35,5 +35,15 @@ namespace KumiScript.Renderer
|
|||
|
||||
return _renderer;
|
||||
}
|
||||
|
||||
public void SetResizable(bool r)
|
||||
{
|
||||
SDL.SDL_SetWindowResizable(Id, r ? SDL.SDL_bool.SDL_TRUE : SDL.SDL_bool.SDL_FALSE);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
SDL.SDL_DestroyWindow(Id);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue