Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bec2e913c0 | ||
|
|
1252ed7879 | ||
|
|
c9650aada7 | ||
|
|
6f32d3f2fe | ||
|
|
51b1b34d03 | ||
|
|
997cf5efe0 | ||
|
|
b2bd75c2b1 | ||
|
|
394bbda32f | ||
|
|
f13f8bd524 | ||
|
|
9f75d6c763 | ||
|
|
5af185f917 | ||
|
|
e102c0c6f6 | ||
|
|
7678c00d25 | ||
|
|
9723c19514 | ||
|
|
42d1711bfb | ||
|
|
14b448d8fb | ||
|
|
a53b53e864 | ||
|
|
e51953445b | ||
|
|
64c3285fbc | ||
|
|
24b7ee9f16 | ||
|
|
4775435df4 | ||
|
|
23cfdb1273 | ||
|
|
e215485293 | ||
|
|
816aca30ac | ||
|
|
52d7eb5eab | ||
|
|
b16d6fa43f | ||
|
|
858ce9f7b1 | ||
|
|
4923eb1ab8 | ||
|
|
2ab09b47bf | ||
|
|
6ff4bdcc11 | ||
|
|
69f568cc7a | ||
|
|
97e4dde563 | ||
|
|
5385718e91 | ||
|
|
19a1ae222a | ||
|
|
9782ef2938 | ||
|
|
08f583e994 | ||
|
|
b3cb93612d | ||
|
|
45bbf230a5 | ||
|
|
401eb1d960 | ||
|
|
926ad3ec0d | ||
|
|
575589e5a3 | ||
|
|
b0adb417a0 | ||
|
|
1b5a2d92af | ||
|
|
97e01ab714 | ||
|
|
bc21e746fb | ||
|
|
047288ea3d | ||
|
|
179690f177 | ||
|
|
2db942f47d | ||
|
|
581b83fe54 | ||
|
|
3f4a8709b5 | ||
|
|
56c20c4a36 | ||
|
|
a30b4b7ff8 | ||
|
|
acb25132e4 | ||
|
|
d3203c7790 | ||
|
|
a0910191da | ||
|
|
303d387c20 | ||
|
|
0963b80234 | ||
|
|
3f326a46f0 | ||
|
|
ef036716b7 | ||
|
|
84b67e99b1 | ||
|
|
6cf36a852f | ||
|
|
d3d6fd0fbf | ||
|
|
7a381b87c5 | ||
|
|
5741266dfb | ||
|
|
0678bd79f4 | ||
|
|
5119332adb | ||
|
|
273d0faa44 | ||
|
|
eea524f106 | ||
|
|
a811a743b8 | ||
|
|
977b7cbf37 | ||
|
|
09875f5d49 | ||
|
|
a51d6e2b29 | ||
|
|
97ab41580a | ||
|
|
986800332c | ||
|
|
fef6a6f824 | ||
|
|
daf14dc4fc | ||
|
|
e4e280da4f | ||
|
|
4e6c392d44 | ||
|
|
18ed74615a | ||
|
|
6349423329 | ||
|
|
f650256986 | ||
|
|
3e5165361e | ||
|
|
846d81b60e | ||
|
|
5d6c6b0e0f | ||
|
|
e7acf05cc4 | ||
|
|
663ed8c465 | ||
|
|
50cd9efd86 |
No files matched your search
@@ -3,3 +3,4 @@
|
||||
/test/tmp/
|
||||
/coverage/
|
||||
/jes
|
||||
/jestest
|
||||
+11
-2
@@ -1,6 +1,15 @@
|
||||
[submodule "libs/googletest"]
|
||||
path = libs/googletest
|
||||
url = git://github.com/google/googletest
|
||||
url = https://github.com/google/googletest
|
||||
[submodule "libs/glcxx"]
|
||||
path = libs/glcxx
|
||||
url = git://github.com/holtrop/glcxx.git
|
||||
url = https://github.com/holtrop/glcxx.git
|
||||
[submodule "libs/DerelictGL3"]
|
||||
path = libs/DerelictGL3
|
||||
url = https://github.com/DerelictOrg/DerelictGL3
|
||||
[submodule "libs/DerelictGLFW3"]
|
||||
path = libs/DerelictGLFW3
|
||||
url = https://github.com/DerelictOrg/DerelictGLFW3
|
||||
[submodule "libs/DerelictUtil"]
|
||||
path = libs/DerelictUtil
|
||||
url = https://github.com/DerelictOrg/DerelictUtil
|
||||
@@ -5,3 +5,12 @@ all:
|
||||
.PHONY: clean
|
||||
clean:
|
||||
./rscons clean
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
./rscons build
|
||||
./jestest
|
||||
|
||||
.PHONY: icon
|
||||
icon:
|
||||
./scripts/icon.rb
|
||||
+14
-33
@@ -1,39 +1,20 @@
|
||||
project_name "jes"
|
||||
|
||||
configure do
|
||||
check_c_compiler
|
||||
check_cxx_compiler
|
||||
check_d_compiler
|
||||
check_c_header "getopt.h"
|
||||
check_c_header "X11/Xlib.h"
|
||||
check_cfg package: "freetype2"
|
||||
check_lib "GL"
|
||||
check_lib "dl"
|
||||
check_lib "X11"
|
||||
check_lib "GLX"
|
||||
check_cfg package: "freetype2"
|
||||
check_program "convert"
|
||||
end
|
||||
|
||||
build do
|
||||
Environment.new do |env|
|
||||
env["CPPDEFINES"] += %w[
|
||||
APPNAME="jes"
|
||||
VERSION="0.0.1"
|
||||
GLCXX_GL_INCLUDE="gl3w.h"
|
||||
PLATFORM_LINUX
|
||||
JTK_X
|
||||
]
|
||||
env["CPPPATH"] += glob("src/**", "libs/glcxx/include")
|
||||
env["CCFLAGS"] += %w[
|
||||
-Wall
|
||||
-O2
|
||||
-Wno-switch
|
||||
]
|
||||
env["CXXFLAGS"] += %w[
|
||||
-std=gnu++14
|
||||
]
|
||||
sources = glob("src/**/*.{c,cc,cxx}", "libs/glcxx/src/glcxx/*")
|
||||
env.Program("jes", sources)
|
||||
env.InstallDirectory("${prefix}/bin")
|
||||
env.Install("${prefix}/bin", "jes")
|
||||
env.Install("${prefix}/share", "share")
|
||||
end
|
||||
main_env = env do |env|
|
||||
env["sources"] = glob("src/**/*.{c,d}", "libs/Derelict*/**/*.d")
|
||||
env["CCFLAGS"] += %w[-Wall]
|
||||
env["D_IMPORT_PATH"] += glob("src", "libs/Derelict*/source")
|
||||
env["DFLAGS"] += %w[-Wall]
|
||||
env["LIBS"] += %w[X11 GLX]
|
||||
env.Program("jes", "${sources}")
|
||||
end
|
||||
main_env.clone do |env|
|
||||
env["DFLAGS"] += %w[-g -funittest]
|
||||
env.Program("jestest", "${sources}")
|
||||
end
|
||||
Submodule
+1
Submodule libs/DerelictGL3 added at e1197a6c5f.
Submodule
+1
Submodule libs/DerelictGLFW3 added at 09b9680cc8.
Submodule
+1
Submodule libs/DerelictUtil added at 8dda33953e.
@@ -1,6 +1,31 @@
|
||||
#!/usr/bin/env ruby
|
||||
script = File.join(File.dirname(__FILE__), ".rscons-2.0.1-64b37e4eb6b5edaabc2d8658995d4996.rb")
|
||||
unless File.exists?(script)
|
||||
|
||||
# Copyright (c) 2013-2022 Josh Holtrop
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
script = File.join(File.dirname(__FILE__), ".rscons-3.2.0-9c72a96ad688d44c0d39ece9d99800e7.rb")
|
||||
unless File.exist?(script)
|
||||
if File.read(__FILE__, mode: "rb") =~ /^#==>(.*)/
|
||||
require "zlib"
|
||||
require "base64"
|
||||
@@ -16,6 +41,6 @@ unless File.exists?(script)
|
||||
end
|
||||
load script
|
||||
if __FILE__ == $0
|
||||
Rscons::Cli.run(ARGV)
|
||||
Rscons::Cli.new.run(ARGV)
|
||||
end
|
||||
#==>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 truncated
|
||||
#==>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 truncated
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require "fileutils"
|
||||
|
||||
ICON = "share/jes/icons/jes-32x32.png"
|
||||
OUTFILE = "src/jes/gui/icon.d"
|
||||
|
||||
system(*%W[convert #{ICON} bgra:icon.bgra])
|
||||
icon_bgra = File.binread("icon.bgra")
|
||||
FileUtils.rm_f("icon.bgra")
|
||||
|
||||
File.open(OUTFILE, "wb") do |fh|
|
||||
fh.puts "module jes.gui.icon;"
|
||||
fh.puts
|
||||
fh.puts "const ubyte[] icon_32x32_bgra = ["
|
||||
icon_bgra.bytes.each_slice(8) do |bytes|
|
||||
fh.puts " #{bytes.map {|b| sprintf("0x%02xu,", b)}.join(" ")}"
|
||||
end
|
||||
fh.puts "];"
|
||||
end
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,16 +0,0 @@
|
||||
#ifndef CHANGEOPERATION_H
|
||||
#define CHANGEOPERATION_H
|
||||
|
||||
#include "ChangeUnit.h"
|
||||
#include <list>
|
||||
#include <stdlib.h>
|
||||
|
||||
class ChangeOperation
|
||||
{
|
||||
public:
|
||||
size_t parent;
|
||||
std::list<ChangeUnit> changes;
|
||||
std::list<size_t> children;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef CHANGEUNIT_H
|
||||
#define CHANGEUNIT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
class ChangeUnit
|
||||
{
|
||||
public:
|
||||
size_t change_buffer_offset;
|
||||
size_t length;
|
||||
size_t buffer_position;
|
||||
bool insert;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,244 +0,0 @@
|
||||
#include "Encoding.h"
|
||||
|
||||
static inline bool
|
||||
check_continuation_bytes(const uint8_t ** buffer,
|
||||
uint8_t continuation_bytes_to_check)
|
||||
{
|
||||
for (uint8_t i = 0; i < continuation_bytes_to_check; i++)
|
||||
{
|
||||
if ((**buffer & 0xC0u) != 0x80u)
|
||||
return false;
|
||||
(*buffer)++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Encoding::Type Encoding::detect_encoding(const uint8_t * buffer, size_t length)
|
||||
{
|
||||
for (size_t i = 0u; i < length; i++)
|
||||
{
|
||||
const uint8_t c = *buffer;
|
||||
uint8_t continuation_bytes_to_check;
|
||||
if ((c & 0x80u) == 0u)
|
||||
{
|
||||
buffer++;
|
||||
continue;
|
||||
}
|
||||
else if ((c & 0xE0u) == 0xC0u)
|
||||
{
|
||||
continuation_bytes_to_check = 1u;
|
||||
}
|
||||
else if ((c & 0xF0u) == 0xE0u)
|
||||
{
|
||||
continuation_bytes_to_check = 2u;
|
||||
}
|
||||
else if ((c & 0xF8u) == 0xF0u)
|
||||
{
|
||||
continuation_bytes_to_check = 3u;
|
||||
}
|
||||
else if ((c & 0xFCu) == 0xF8u)
|
||||
{
|
||||
continuation_bytes_to_check = 4u;
|
||||
}
|
||||
else if ((c & 0xFEu) == 0xFCu)
|
||||
{
|
||||
continuation_bytes_to_check = 5u;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CP_1252;
|
||||
}
|
||||
buffer++;
|
||||
if (((i + continuation_bytes_to_check) < length) &&
|
||||
check_continuation_bytes(&buffer, continuation_bytes_to_check))
|
||||
{
|
||||
i += continuation_bytes_to_check;
|
||||
continue;
|
||||
}
|
||||
return CP_1252;
|
||||
}
|
||||
|
||||
return UTF_8;
|
||||
}
|
||||
|
||||
uint8_t Encoding::num_bytes_in_code_point(Type type, const uint8_t * encoded)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UTF_8:
|
||||
{
|
||||
if ((*encoded & 0x80u) == 0u)
|
||||
return 1u;
|
||||
encoded++;
|
||||
uint8_t n = 1u;
|
||||
while ((*encoded++ & 0xC0u) == 0x80u)
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
break;
|
||||
case CP_1252:
|
||||
return 1u;
|
||||
}
|
||||
return 0u;
|
||||
}
|
||||
|
||||
const uint8_t * Encoding::beginning_of_code_point(Type type, const uint8_t * encoded)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UTF_8:
|
||||
while ((*encoded & 0xC0u) == 0x80u)
|
||||
encoded--;
|
||||
return encoded;
|
||||
case CP_1252:
|
||||
return encoded;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t Encoding::decode(Type type, const uint8_t * encoded, uint8_t * encoded_size)
|
||||
{
|
||||
uint32_t result = 0u;
|
||||
uint8_t size = 0u;
|
||||
switch (type)
|
||||
{
|
||||
case UTF_8:
|
||||
{
|
||||
const uint_fast8_t c = *encoded;
|
||||
if ((c & 0x80u) == 0u)
|
||||
{
|
||||
result = c;
|
||||
size = 1u;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint_fast8_t following_bytes = 0u;
|
||||
if ((c & 0xE0u) == 0xC0u)
|
||||
{
|
||||
result = c & 0x1Fu;
|
||||
following_bytes = 1u;
|
||||
}
|
||||
else if ((c & 0xF0u) == 0xE0u)
|
||||
{
|
||||
result = c & 0x0Fu;
|
||||
following_bytes = 2u;
|
||||
}
|
||||
else if ((c & 0xF8u) == 0xF0u)
|
||||
{
|
||||
result = c & 0x07u;
|
||||
following_bytes = 3u;
|
||||
}
|
||||
else if ((c & 0xFCu) == 0xF8u)
|
||||
{
|
||||
result = c & 0x03u;
|
||||
following_bytes = 4u;
|
||||
}
|
||||
else if ((c & 0xFEu) == 0xFCu)
|
||||
{
|
||||
result = c & 0x01u;
|
||||
following_bytes = 5u;
|
||||
}
|
||||
size = following_bytes + 1u;
|
||||
while (following_bytes-- > 0u)
|
||||
{
|
||||
encoded++;
|
||||
result <<= 6u;
|
||||
result |= *encoded & 0x3Fu;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CP_1252:
|
||||
/* TODO: map byte to code point */
|
||||
result = *encoded;
|
||||
size = 1u;
|
||||
break;
|
||||
}
|
||||
|
||||
if (encoded_size != nullptr)
|
||||
{
|
||||
*encoded_size = size;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t Encoding::num_bytes_to_encode_code_point(uint32_t code_point, Type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UTF_8:
|
||||
if (code_point <= 0x7Fu)
|
||||
{
|
||||
return 1u;
|
||||
}
|
||||
else if (code_point <= 0x7FFu)
|
||||
{
|
||||
return 2u;
|
||||
}
|
||||
else if (code_point <= 0xFFFFu)
|
||||
{
|
||||
return 3u;
|
||||
}
|
||||
else if (code_point <= 0x1FFFFFu)
|
||||
{
|
||||
return 4u;
|
||||
}
|
||||
else if (code_point <= 0x3FFFFFFu)
|
||||
{
|
||||
return 5u;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 6u;
|
||||
}
|
||||
break;
|
||||
case CP_1252:
|
||||
if (code_point <= 0xFFu)
|
||||
{
|
||||
return 1u;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
uint8_t Encoding::encode(uint32_t code_point, Type type, uint8_t * buffer)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UTF_8:
|
||||
{
|
||||
uint8_t size = num_bytes_to_encode_code_point(code_point, type);
|
||||
if (size == 1u)
|
||||
{
|
||||
*buffer = code_point;
|
||||
}
|
||||
else if (size > 1u)
|
||||
{
|
||||
*buffer = (0xFFu << (8u - size)) | (code_point >> (6u * (size - 1u)));
|
||||
for (uint8_t i = 0u, end = size - 1u; i < end; i++)
|
||||
{
|
||||
buffer[end - i] = 0x80u | (code_point >> (6u * i) & 0x3Fu);
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
break;
|
||||
case CP_1252:
|
||||
if (code_point <= 0xFFu)
|
||||
{
|
||||
*buffer = code_point;
|
||||
return 1u;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0u;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#ifndef ENCODING_H
|
||||
#define ENCODING_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
class Encoding
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
UTF_8,
|
||||
CP_1252,
|
||||
};
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
MAX_CODE_POINT_SIZE = 8u,
|
||||
};
|
||||
|
||||
static Type detect_encoding(const uint8_t * buffer, size_t length);
|
||||
static uint8_t num_bytes_in_code_point(Type type, const uint8_t * encoded);
|
||||
static const uint8_t * beginning_of_code_point(Type type, const uint8_t * encoded);
|
||||
static uint32_t decode(Type type, const uint8_t * encoded, uint8_t * encoded_size = nullptr);
|
||||
static uint8_t num_bytes_to_encode_code_point(uint32_t code_point, Type type);
|
||||
static uint8_t encode(uint32_t code_point, Type type, uint8_t * buffer);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,123 +0,0 @@
|
||||
#include "File.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define JES_O_BINARY O_BINARY
|
||||
#else
|
||||
#define JES_O_BINARY 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Open a file.
|
||||
*
|
||||
* @param[in] filename The filename.
|
||||
* @param[in] writing Whether to open for writing.
|
||||
*/
|
||||
bool File::open(const char * filename, bool writing)
|
||||
{
|
||||
int fd;
|
||||
if (writing)
|
||||
{
|
||||
/* TODO: handle mode */
|
||||
fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC | JES_O_BINARY, 0644);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = ::open(filename, O_RDONLY | JES_O_BINARY);
|
||||
}
|
||||
if (fd < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_fd = fd;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the file.
|
||||
*/
|
||||
void File::close()
|
||||
{
|
||||
if (m_fd >= 0)
|
||||
{
|
||||
::close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file's size.
|
||||
*
|
||||
* This function will reset the file position to the beginning of the file.
|
||||
*
|
||||
* @return The file's size, or -1 on error.
|
||||
*/
|
||||
size_t File::get_size()
|
||||
{
|
||||
if (m_fd >= 0)
|
||||
{
|
||||
off_t o = lseek(m_fd, 0, SEEK_END);
|
||||
lseek(m_fd, 0, SEEK_SET);
|
||||
return o;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from the file.
|
||||
*
|
||||
* @param[in] buf Memory buffer to read into. Must be large enough to hold
|
||||
* size bytes.
|
||||
* @param[in] size Number of bytes to read.
|
||||
*
|
||||
* @retval false The file failed to read.
|
||||
* @retval true The file was read successfully.
|
||||
*/
|
||||
bool File::read(uint8_t * buf, size_t size)
|
||||
{
|
||||
size_t n_bytes_read = 0u;
|
||||
for (;;)
|
||||
{
|
||||
off_t rd_size = ::read(m_fd, &buf[n_bytes_read], size - n_bytes_read);
|
||||
if (rd_size <= 0)
|
||||
break;
|
||||
n_bytes_read += (size_t)rd_size;
|
||||
if (n_bytes_read >= size)
|
||||
break;
|
||||
}
|
||||
if (n_bytes_read != size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool File::write(const uint8_t * buf, size_t size)
|
||||
{
|
||||
if (size <= 0)
|
||||
return true;
|
||||
|
||||
size_t n_bytes_written = 0u;
|
||||
for (;;)
|
||||
{
|
||||
off_t write_size = ::write(m_fd, &buf[n_bytes_written], size - n_bytes_written);
|
||||
if (write_size <= 0)
|
||||
break;
|
||||
n_bytes_written += (size_t)write_size;
|
||||
if (n_bytes_written >= size)
|
||||
break;
|
||||
}
|
||||
|
||||
if (n_bytes_written != size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef FILE_H
|
||||
#define FILE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "Span.h"
|
||||
|
||||
class File
|
||||
{
|
||||
public:
|
||||
File() : m_fd(-1) {}
|
||||
~File() { close(); }
|
||||
bool open(const char * filename, bool writing = false);
|
||||
void close();
|
||||
size_t get_size();
|
||||
bool read(uint8_t * buf, size_t size);
|
||||
bool write(const uint8_t * buf, size_t size);
|
||||
bool write(const Span & span)
|
||||
{
|
||||
return write(span.start, span.length);
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_fd;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,129 +0,0 @@
|
||||
#include "GapBuffer.h"
|
||||
#include "System.h"
|
||||
#include <string.h>
|
||||
|
||||
GapBuffer::GapBuffer()
|
||||
{
|
||||
int num_pages = (64u * 1024u + System::page_size - 1u) >> System::page_size_log;
|
||||
m_buffer = (uint8_t *)System::alloc_pages(num_pages);
|
||||
m_buffer_size = System::page_size;
|
||||
m_size = 0u;
|
||||
m_gap_position = 0u;
|
||||
}
|
||||
|
||||
GapBuffer::GapBuffer(uint8_t * buffer, size_t buffer_size, size_t size)
|
||||
{
|
||||
m_buffer = buffer;
|
||||
m_buffer_size = buffer_size;
|
||||
m_size = size;
|
||||
m_gap_position = size;
|
||||
}
|
||||
|
||||
GapBuffer::~GapBuffer()
|
||||
{
|
||||
System::free_pages(m_buffer, m_buffer_size >> System::page_size_log);
|
||||
}
|
||||
|
||||
void GapBuffer::insert(size_t position, const uint8_t * data, size_t length)
|
||||
{
|
||||
ensure_free(length);
|
||||
move_gap(position);
|
||||
memcpy(&m_buffer[m_gap_position], data, length);
|
||||
m_gap_position += length;
|
||||
m_size += length;
|
||||
}
|
||||
|
||||
void GapBuffer::erase(size_t position, size_t length)
|
||||
{
|
||||
if ((position < m_size) && ((position + length) <= m_size))
|
||||
{
|
||||
if ((position + length) == m_gap_position)
|
||||
{
|
||||
m_gap_position -= length;
|
||||
m_size -= length;
|
||||
}
|
||||
else
|
||||
{
|
||||
move_gap(position);
|
||||
m_size -= length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GapBuffer::clear()
|
||||
{
|
||||
m_size = 0u;
|
||||
m_gap_position = 0u;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_TESTING
|
||||
std::string GapBuffer::get_string()
|
||||
{
|
||||
compact();
|
||||
return std::string((char *)m_buffer, m_size);
|
||||
}
|
||||
|
||||
void GapBuffer::set_string(const std::string & s)
|
||||
{
|
||||
clear();
|
||||
insert(0u, (const uint8_t *)s.c_str(), s.size());
|
||||
}
|
||||
#endif
|
||||
|
||||
void GapBuffer::ensure_free(size_t length)
|
||||
{
|
||||
if (gap_size() < length)
|
||||
{
|
||||
/* We're out of space. Allocate more and move data. */
|
||||
size_t new_size = (m_buffer_size + (128u * 1024u)) & System::page_base_mask;
|
||||
size_t new_num_pages = new_size >> System::page_size_log;
|
||||
uint8_t * new_buffer = (uint8_t *)System::alloc_pages(new_num_pages);
|
||||
memcpy(new_buffer, m_buffer, m_gap_position);
|
||||
memcpy(&new_buffer[m_gap_position], &m_buffer[m_gap_position + gap_size()], m_size - m_gap_position);
|
||||
|
||||
/* Free the old buffer */
|
||||
System::free_pages(m_buffer, m_buffer_size >> System::page_size_log);
|
||||
|
||||
m_buffer = new_buffer;
|
||||
m_buffer_size = new_size;
|
||||
m_gap_position = m_size;
|
||||
}
|
||||
}
|
||||
|
||||
void GapBuffer::move_gap(size_t position)
|
||||
{
|
||||
if (position != m_gap_position)
|
||||
{
|
||||
if (position < m_gap_position)
|
||||
{
|
||||
memmove(&m_buffer[position + gap_size()], &m_buffer[position], m_gap_position - position);
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(&m_buffer[m_gap_position], &m_buffer[m_gap_position + gap_size()], position - m_gap_position);
|
||||
}
|
||||
m_gap_position = position;
|
||||
}
|
||||
}
|
||||
|
||||
void GapBuffer::copy_to(size_t source_position, size_t length, GapBuffer & other, size_t destination_position)
|
||||
{
|
||||
if ((source_position < m_size) &&
|
||||
(length > 0u) &&
|
||||
((source_position + length) <= m_size))
|
||||
{
|
||||
if ((m_gap_position <= source_position) ||
|
||||
(m_gap_position >= (source_position + length)))
|
||||
{
|
||||
/* The gap is before or after the range of data to copy. */
|
||||
other.insert(destination_position, address(source_position), length);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The gap is in the middle of the range of data to copy. */
|
||||
size_t pre_gap_size = m_gap_position - source_position;
|
||||
other.insert(destination_position, address(source_position), pre_gap_size);
|
||||
other.insert(destination_position + pre_gap_size, address(source_position + pre_gap_size), length - pre_gap_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
#ifndef GAPBUFFER_H
|
||||
#define GAPBUFFER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef ENABLE_TESTING
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
class GapBuffer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a new GapBuffer object.
|
||||
*
|
||||
* The GapBuffer will allocate its own memory.
|
||||
*/
|
||||
GapBuffer();
|
||||
|
||||
/**
|
||||
* Create a GapBuffer object that points to preallocated memory.
|
||||
*
|
||||
* The GapBuffer object will take over ownership of the allocated memory.
|
||||
*
|
||||
* @param buffer
|
||||
* Pointer to buffer allocated by System::alloc_pages().
|
||||
* @param buffer_size
|
||||
* Size of the buffer allocated by System::alloc_pages().
|
||||
* @param size
|
||||
* Size of the data in the buffer.
|
||||
*/
|
||||
GapBuffer(uint8_t * buffer, size_t buffer_size, size_t size);
|
||||
|
||||
/**
|
||||
* Destroy the GapBuffer object and free its memory.
|
||||
*/
|
||||
~GapBuffer();
|
||||
|
||||
/**
|
||||
* Insert data into the gap buffer at the given position.
|
||||
*
|
||||
* @param position
|
||||
* Position in the gap buffer to insert the code point at.
|
||||
* @param data
|
||||
* Pointer to the data to insert.
|
||||
* @param length
|
||||
* Length of the data to insert.
|
||||
*/
|
||||
void insert(size_t position, const uint8_t * data, size_t length);
|
||||
|
||||
/**
|
||||
* Erase data from the gap buffer.
|
||||
*
|
||||
* @param position
|
||||
* Position in the gap buffer to erase data from.
|
||||
* @param length
|
||||
* Length of the data to erase.
|
||||
*/
|
||||
void erase(size_t position, size_t length);
|
||||
|
||||
/**
|
||||
* Erase all data from the gap buffer.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Get the size of the data stored within the buffer.
|
||||
*/
|
||||
size_t size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the memory address of a buffer location.
|
||||
*
|
||||
* @param offset
|
||||
* The index into the gap buffer data.
|
||||
*/
|
||||
uint8_t * address(size_t offset) const
|
||||
{
|
||||
if (offset < m_gap_position)
|
||||
{
|
||||
return &m_buffer[offset];
|
||||
}
|
||||
else
|
||||
{
|
||||
return &m_buffer[offset + gap_size()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move buffer gap to the end of the buffer so the contents are congruent
|
||||
* at the beginning of the buffer.
|
||||
*/
|
||||
void compact()
|
||||
{
|
||||
move_gap(m_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a range of data from this GapBuffer to another.
|
||||
*
|
||||
* @param source_position
|
||||
* Position in the gap buffer containing the data to copy.
|
||||
* @param length
|
||||
* Length of the data to copy.
|
||||
* @param other
|
||||
* Destination GapBuffer to copy the data into.
|
||||
* @param destination_position
|
||||
* Position in the destination GapBuffer to copy the data to.
|
||||
*/
|
||||
void copy_to(size_t source_position, size_t length, GapBuffer & other, size_t destination_position);
|
||||
|
||||
#ifdef ENABLE_TESTING
|
||||
/**
|
||||
* Get the contents of the gap buffer as a string.
|
||||
*
|
||||
* This makes a copy of the entire buffer in a std::string. This method is
|
||||
* intended for use by unit tests.
|
||||
*/
|
||||
std::string get_string();
|
||||
|
||||
/**
|
||||
* Replace the buffer contents with a string.
|
||||
*/
|
||||
void set_string(const std::string & s);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/** Address of the allocated memory buffer. */
|
||||
uint8_t * m_buffer;
|
||||
|
||||
/** Size of the allocated memory buffer. */
|
||||
size_t m_buffer_size;
|
||||
|
||||
/** Size of the data stored in the buffer. */
|
||||
size_t m_size;
|
||||
|
||||
/** Index of the gap in the memory buffer. */
|
||||
size_t m_gap_position;
|
||||
|
||||
/**
|
||||
* Get the gap size.
|
||||
*/
|
||||
size_t gap_size() const
|
||||
{
|
||||
return m_buffer_size - m_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that there is enough free space in the gap, and if not, grow the
|
||||
* gap and move data.
|
||||
*
|
||||
* @param length
|
||||
* The number of bytes that must be free.
|
||||
*/
|
||||
void ensure_free(size_t length);
|
||||
|
||||
/**
|
||||
* Move the gap buffer gap position to the requested position.
|
||||
*
|
||||
* @param position
|
||||
* New gap position. Must be <= m_size.
|
||||
*/
|
||||
void move_gap(size_t position);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
#include "LineEndings.h"
|
||||
|
||||
static uint8_t lf[] = "\n";
|
||||
static uint8_t crlf[] = "\r\n";
|
||||
static uint8_t cr[] = "\r";
|
||||
|
||||
const Span LineEndings::spans[] = {
|
||||
Span(lf, 1u),
|
||||
Span(crlf, 2u),
|
||||
Span(cr, 1u),
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef LINEENDINGS_H
|
||||
#define LINEENDINGS_H
|
||||
|
||||
#include "Span.h"
|
||||
|
||||
class LineEndings
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
LF,
|
||||
CRLF,
|
||||
CR,
|
||||
COUNT,
|
||||
};
|
||||
|
||||
static const Span spans[COUNT];
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
#ifndef PAGEDBUFFER_H
|
||||
#define PAGEDBUFFER_H
|
||||
|
||||
#include "System.h"
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
template <typename T>
|
||||
class PagedBuffer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a PagedBuffer.
|
||||
*/
|
||||
PagedBuffer<T>()
|
||||
{
|
||||
m_n_per_page = System::page_size / sizeof(T);
|
||||
m_size = 0u;
|
||||
}
|
||||
|
||||
~PagedBuffer<T>()
|
||||
{
|
||||
for (auto it : m_pages)
|
||||
{
|
||||
System::free_pages(it, 1);
|
||||
}
|
||||
}
|
||||
|
||||
const T & operator[](unsigned int index) const
|
||||
{
|
||||
while (index >= (m_pages.size() * m_n_per_page))
|
||||
{
|
||||
grow();
|
||||
}
|
||||
return m_pages[page_index(index)][index_in_page(index)];
|
||||
}
|
||||
|
||||
T & operator[](unsigned int index)
|
||||
{
|
||||
while (index >= (m_pages.size() * m_n_per_page))
|
||||
{
|
||||
grow();
|
||||
}
|
||||
return m_pages[page_index(index)][index_in_page(index)];
|
||||
}
|
||||
|
||||
size_t size() { return m_size; }
|
||||
|
||||
protected:
|
||||
unsigned int page_index(unsigned int index)
|
||||
{
|
||||
return index / m_n_per_page;
|
||||
}
|
||||
|
||||
unsigned int index_in_page(unsigned int index)
|
||||
{
|
||||
return index % m_n_per_page;
|
||||
}
|
||||
|
||||
void grow()
|
||||
{
|
||||
m_pages.push_back((T *)System::alloc_pages(1));
|
||||
m_size += m_n_per_page;
|
||||
}
|
||||
|
||||
std::vector<T *> m_pages;
|
||||
unsigned long m_size;
|
||||
unsigned int m_n_per_page;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
#include "Timer.h"
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static long get_usec()
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec * 1000000 + tv.tv_usec;
|
||||
}
|
||||
|
||||
Timer::Timer()
|
||||
{
|
||||
m_start_time = 0;
|
||||
m_elapsed = 0;
|
||||
start();
|
||||
}
|
||||
|
||||
void Timer::start()
|
||||
{
|
||||
m_start_time = get_usec();
|
||||
}
|
||||
|
||||
void Timer::stop()
|
||||
{
|
||||
m_elapsed = get_usec() - m_start_time;
|
||||
}
|
||||
|
||||
void Timer::print()
|
||||
{
|
||||
printf("Elapsed: %ldus\n", m_elapsed);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
Timer();
|
||||
void start();
|
||||
void stop();
|
||||
void print();
|
||||
|
||||
long get_elapsed() { return m_elapsed; }
|
||||
|
||||
protected:
|
||||
long m_start_time;
|
||||
long m_elapsed;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
module gltk.array;
|
||||
import derelict.opengl;
|
||||
|
||||
class Array
|
||||
{
|
||||
private GLuint m_id;
|
||||
|
||||
this()
|
||||
{
|
||||
m_id = 0u;
|
||||
glGenVertexArrays(1, &m_id);
|
||||
if (m_id == 0u)
|
||||
{
|
||||
throw new Exception("Failed to allocate an OpenGL array");
|
||||
}
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
glDeleteVertexArrays(1, &m_id);
|
||||
}
|
||||
|
||||
void bind()
|
||||
{
|
||||
glBindVertexArray(m_id);
|
||||
}
|
||||
|
||||
@property GLuint id()
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
module gltk.buffer;
|
||||
import derelict.opengl;
|
||||
|
||||
class Buffer
|
||||
{
|
||||
private GLuint m_id;
|
||||
|
||||
private GLenum m_target;
|
||||
|
||||
this(GLenum target)
|
||||
{
|
||||
m_id = 0u;
|
||||
glGenBuffers(1, &m_id);
|
||||
if (m_id == 0u)
|
||||
{
|
||||
throw new Exception("Failed to allocate an OpenGL buffer");
|
||||
}
|
||||
m_target = target;
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
glDeleteBuffers(1, &m_id);
|
||||
}
|
||||
|
||||
void bind()
|
||||
{
|
||||
glBindBuffer(m_target, m_id);
|
||||
}
|
||||
|
||||
@property GLuint id()
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void set_buffer_data(GLenum usage, const void * ptr, size_t size)
|
||||
{
|
||||
bind();
|
||||
glBufferData(m_target, size, ptr, usage);
|
||||
}
|
||||
|
||||
void set_buffer_data(T)(GLenum usage, T[] arr)
|
||||
{
|
||||
bind();
|
||||
glBufferData(m_target, arr.length * arr[0].sizeof, arr.ptr, usage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module gltk;
|
||||
|
||||
public import gltk.array;
|
||||
public import gltk.buffer;
|
||||
public import gltk.program;
|
||||
public import gltk.shader;
|
||||
public import gltk.texture;
|
||||
@@ -0,0 +1,181 @@
|
||||
module gltk.program;
|
||||
import gltk.shader;
|
||||
import derelict.opengl;
|
||||
import std.string;
|
||||
|
||||
class Program(uniforms...)
|
||||
{
|
||||
/* The number of template parameters must be a multiple of 2. */
|
||||
static assert((uniforms.length % 2) == 0);
|
||||
|
||||
private GLuint m_id;
|
||||
|
||||
static foreach (i, v; uniforms)
|
||||
{
|
||||
static if ((i % 2) == 0)
|
||||
{
|
||||
mixin("private GLint m_uniform_" ~ v ~ ";");
|
||||
}
|
||||
}
|
||||
|
||||
this(Args...)(Args args)
|
||||
{
|
||||
m_id = glCreateProgram();
|
||||
if (m_id == 0u)
|
||||
{
|
||||
throw new Exception("Failed to allocate an OpenGL program");
|
||||
}
|
||||
static if (args.length > 0u)
|
||||
{
|
||||
build(args);
|
||||
}
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
glDeleteProgram(m_id);
|
||||
}
|
||||
|
||||
void attach_shader(Shader shader) const
|
||||
{
|
||||
glAttachShader(m_id, shader.id);
|
||||
}
|
||||
|
||||
void bind_attrib_location(string name, uint index) const
|
||||
{
|
||||
glBindAttribLocation(m_id, index, name.toStringz());
|
||||
}
|
||||
|
||||
void link()
|
||||
{
|
||||
glLinkProgram(m_id);
|
||||
|
||||
GLint link_status;
|
||||
glGetProgramiv(m_id, GL_LINK_STATUS, &link_status);
|
||||
if (link_status != GL_TRUE)
|
||||
{
|
||||
string message = "Failed to link program";
|
||||
GLint log_length = 0;
|
||||
glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
|
||||
if (log_length > 0)
|
||||
{
|
||||
char[] log = new char[log_length];
|
||||
glGetProgramInfoLog(m_id, log_length, &log_length, log.ptr);
|
||||
message ~= "\n";
|
||||
message ~= log;
|
||||
message ~= "\n";
|
||||
}
|
||||
throw new Exception(message);
|
||||
}
|
||||
|
||||
static foreach(i, v; uniforms)
|
||||
{
|
||||
static if ((i % 2) == 0)
|
||||
{
|
||||
mixin("m_uniform_" ~ v ~ " = glGetUniformLocation(m_id, \"" ~ v ~ "\");");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLint get_uniform_location(string uniform_name) const
|
||||
{
|
||||
return glGetUniformLocation(m_id, uniform_name.toStringz());
|
||||
}
|
||||
|
||||
void get_uniform_locations(Args...)(string uniform_name, GLint * uniform_location, Args args) const
|
||||
{
|
||||
*uniform_location = get_uniform_location(uniform_name);
|
||||
static if (args.length > 0u)
|
||||
{
|
||||
get_uniform_locations(args);
|
||||
}
|
||||
}
|
||||
|
||||
@property GLuint id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void use() const
|
||||
{
|
||||
glUseProgram(m_id);
|
||||
}
|
||||
|
||||
private static string uniform_param_decl_list(string spec)
|
||||
{
|
||||
int count = spec[0] - '0';
|
||||
string type;
|
||||
if (spec[1] == 'i')
|
||||
{
|
||||
type = "GLint";
|
||||
}
|
||||
else if (spec[1..2] == "ui")
|
||||
{
|
||||
type = "GLuint";
|
||||
}
|
||||
else if (spec[1] == 'f')
|
||||
{
|
||||
type = "GLfloat";
|
||||
}
|
||||
assert(type != "");
|
||||
if (spec[$ - 1] == 'v')
|
||||
{
|
||||
return "uint count, const " ~ type ~ " * v";
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] decls;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
decls ~= type ~ " v" ~ cast(char)('0' + i);
|
||||
}
|
||||
return decls.join(", ");
|
||||
}
|
||||
}
|
||||
|
||||
private static string uniform_param_list(string spec)
|
||||
{
|
||||
int count = spec[0] - '0';
|
||||
if (spec[$ - 1] == 'v')
|
||||
{
|
||||
return "count, v";
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] vees;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
vees ~= "v" ~ cast(char)('0' + i);
|
||||
}
|
||||
return vees.join(", ");
|
||||
}
|
||||
}
|
||||
|
||||
static foreach (i, v; uniforms)
|
||||
{
|
||||
static if ((i % 2) == 0)
|
||||
{
|
||||
mixin("void set_" ~ v ~ "(" ~ uniform_param_decl_list(uniforms[i + 1]) ~ ")" ~
|
||||
"{" ~
|
||||
" glUniform" ~ uniforms[i + 1] ~ "(m_uniform_" ~ v ~ ", " ~ uniform_param_list(uniforms[i + 1]) ~ ");" ~
|
||||
"}");
|
||||
}
|
||||
}
|
||||
|
||||
private void build(Args...)(Shader s, Args args)
|
||||
{
|
||||
attach_shader(s);
|
||||
build(args);
|
||||
}
|
||||
|
||||
private void build(Args...)(string attrib_name, uint index, Args args)
|
||||
{
|
||||
bind_attrib_location(attrib_name, index);
|
||||
build(args);
|
||||
}
|
||||
|
||||
private void build()
|
||||
{
|
||||
link();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
module gltk.shader;
|
||||
import derelict.opengl;
|
||||
static import std.file;
|
||||
|
||||
class Shader
|
||||
{
|
||||
private GLuint m_id;
|
||||
|
||||
private GLenum m_shader_type;
|
||||
|
||||
this(GLenum shader_type)
|
||||
{
|
||||
m_shader_type = shader_type;
|
||||
m_id = glCreateShader(shader_type);
|
||||
if (m_id == 0u)
|
||||
{
|
||||
throw new Exception("Failed to allocate an OpenGL shader");
|
||||
}
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
glDeleteShader(m_id);
|
||||
}
|
||||
|
||||
void set_source(const char * source, int length = -1)
|
||||
{
|
||||
GLint status;
|
||||
|
||||
GLint gllength = length;
|
||||
glShaderSource(m_id, 1, &source, &gllength);
|
||||
|
||||
glCompileShader(m_id);
|
||||
|
||||
glGetShaderiv(m_id, GL_COMPILE_STATUS, &status);
|
||||
if (status == GL_TRUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string message = "Error compiling ";
|
||||
switch (m_shader_type)
|
||||
{
|
||||
case GL_VERTEX_SHADER:
|
||||
message ~= "vertex";
|
||||
break;
|
||||
case GL_FRAGMENT_SHADER:
|
||||
message ~= "fragment";
|
||||
break;
|
||||
default:
|
||||
message ~= "unknown";
|
||||
break;
|
||||
}
|
||||
message ~= " shader";
|
||||
|
||||
GLint log_length;
|
||||
glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
|
||||
if (log_length > 0)
|
||||
{
|
||||
char[] log = new char[log_length];
|
||||
glGetShaderInfoLog(m_id, log_length, &log_length, log.ptr);
|
||||
message ~= "\nShader Log:\n";
|
||||
message ~= log;
|
||||
message ~= "\n";
|
||||
}
|
||||
glDeleteShader(m_id);
|
||||
throw new Exception(message);
|
||||
}
|
||||
|
||||
void set_source_from_file(string filename)
|
||||
{
|
||||
const(char)[] file_data = cast(const(char)[])std.file.read(filename);
|
||||
set_source(file_data.ptr, cast(int)file_data.length);
|
||||
}
|
||||
|
||||
@property GLuint id()
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
module gltk.texture;
|
||||
import derelict.opengl;
|
||||
|
||||
class Texture
|
||||
{
|
||||
private GLuint m_id;
|
||||
|
||||
this()
|
||||
{
|
||||
m_id = 0u;
|
||||
glGenTextures(1, &m_id);
|
||||
if (m_id == 0u)
|
||||
{
|
||||
throw new Exception("Failed to allocate an OpenGL texture");
|
||||
}
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
glDeleteTextures(1, &m_id);
|
||||
}
|
||||
|
||||
void bind(GLenum target) const
|
||||
{
|
||||
glBindTexture(target, m_id);
|
||||
}
|
||||
|
||||
@property GLuint id()
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
static uint next_power_of_2(uint n)
|
||||
{
|
||||
n--;
|
||||
n |= n >> 1u;
|
||||
n |= n >> 2u;
|
||||
n |= n >> 4u;
|
||||
n |= n >> 8u;
|
||||
n |= n >> 16u;
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
@@ -1,91 +0,0 @@
|
||||
#include "Font.h"
|
||||
|
||||
#define round_up_26_6(val) (((val) + 63) >> 6u)
|
||||
|
||||
static FT_Library ft_library_handle;
|
||||
static bool ft_initialized;
|
||||
|
||||
bool Initialize_FreeType()
|
||||
{
|
||||
if (ft_initialized)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (FT_Init_FreeType(&ft_library_handle) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ft_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Font::load(const char * fname, int size)
|
||||
{
|
||||
if (!Initialize_FreeType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FT_New_Face(ft_library_handle, fname, 0, &m_face) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FT_Set_Pixel_Sizes(m_face, 0, size);
|
||||
|
||||
return preload_glyphs();
|
||||
}
|
||||
|
||||
bool Font::preload_glyphs()
|
||||
{
|
||||
static const char preload_glyph_list[] = "HMgjqxy_|^";
|
||||
|
||||
int max_top = -9999;
|
||||
int min_bottom = 9999;
|
||||
m_advance = 0;
|
||||
|
||||
for (size_t i = 0u; i < sizeof(preload_glyph_list) - 1u; i++)
|
||||
{
|
||||
std::shared_ptr<Glyph> g = get_glyph(preload_glyph_list[i]);
|
||||
if (g == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (m_face->glyph->bitmap_top > max_top)
|
||||
{
|
||||
max_top = m_face->glyph->bitmap_top;
|
||||
}
|
||||
int bitmap_bottom = m_face->glyph->bitmap_top - m_face->glyph->bitmap.rows;
|
||||
if (bitmap_bottom < min_bottom)
|
||||
{
|
||||
min_bottom = bitmap_bottom;
|
||||
}
|
||||
if (g->get_advance() > m_advance)
|
||||
{
|
||||
m_advance = g->get_advance();
|
||||
}
|
||||
}
|
||||
|
||||
m_line_height = round_up_26_6(m_face->size->metrics.height);
|
||||
m_baseline_offset = (m_line_height - (max_top - min_bottom)) / 2 - min_bottom;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<Glyph> Font::get_glyph(FT_ULong character)
|
||||
{
|
||||
auto it = m_glyphs.find(character);
|
||||
if (it != m_glyphs.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
std::shared_ptr<Glyph> glyph = std::make_shared<Glyph>();
|
||||
if (!glyph->load(m_face, character))
|
||||
{
|
||||
glyph = nullptr;
|
||||
}
|
||||
m_glyphs[character] = glyph;
|
||||
return glyph;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef FONT_H
|
||||
#define FONT_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include "Glyph.h"
|
||||
|
||||
class Font
|
||||
{
|
||||
public:
|
||||
bool load(const char * fname, int size);
|
||||
std::shared_ptr<Glyph> get_glyph(FT_ULong character);
|
||||
int get_advance() { return m_advance; }
|
||||
int get_line_height() { return m_line_height; }
|
||||
int get_baseline_offset() { return m_baseline_offset; }
|
||||
|
||||
protected:
|
||||
bool preload_glyphs();
|
||||
|
||||
FT_Face m_face;
|
||||
std::unordered_map<FT_ULong, std::shared_ptr<Glyph>> m_glyphs;
|
||||
int m_advance;
|
||||
int m_line_height;
|
||||
int m_baseline_offset;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,52 +0,0 @@
|
||||
#include "Glyph.h"
|
||||
|
||||
#define round_up_26_6(val) (((val) + 63) >> 6u)
|
||||
|
||||
bool Glyph::load(FT_Face face, FT_ULong char_code)
|
||||
{
|
||||
if (FT_Load_Char(face, char_code, FT_LOAD_RENDER) != 0)
|
||||
return false;
|
||||
|
||||
m_texture = glcxx::Texture::create();
|
||||
m_texture->bind(GL_TEXTURE_2D);
|
||||
int width = face->glyph->bitmap.width;
|
||||
int rounded_width = glcxx::Texture::next_power_of_2(width);
|
||||
int height = face->glyph->bitmap.rows;
|
||||
int rounded_height = glcxx::Texture::next_power_of_2(height);
|
||||
m_advance = round_up_26_6(face->glyph->advance.x);
|
||||
uint8_t * texture = new uint8_t[rounded_width * rounded_height];
|
||||
memset(texture, 0, rounded_width * rounded_height);
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
memcpy(&texture[rounded_width * i],
|
||||
&face->glyph->bitmap.buffer[width * (height - i - 1)],
|
||||
width);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, rounded_width, rounded_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texture);
|
||||
delete[] texture;
|
||||
|
||||
m_array = glcxx::Array::create();
|
||||
m_array->bind();
|
||||
|
||||
int left = face->glyph->bitmap_left;
|
||||
int top = face->glyph->bitmap_top;
|
||||
float s_max = width / (float)rounded_width;
|
||||
float t_max = height / (float)rounded_height;
|
||||
m_buffer = glcxx::Buffer::create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, {
|
||||
(GLfloat)left, (GLfloat)(top - height), 0.0, 0.0,
|
||||
(GLfloat)(left + width), (GLfloat)(top - height), s_max, 0.0,
|
||||
(GLfloat)left, (GLfloat)top, 0.0, t_max,
|
||||
(GLfloat)(left + width), (GLfloat)top, s_max, t_max,
|
||||
});
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef GLYPH_H
|
||||
#define GLYPH_H
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include "glcxx.hpp"
|
||||
|
||||
class Glyph
|
||||
{
|
||||
public:
|
||||
bool load(FT_Face face, FT_ULong char_code);
|
||||
int get_advance() { return m_advance; }
|
||||
void render()
|
||||
{
|
||||
m_array->bind();
|
||||
m_texture->bind(GL_TEXTURE_2D);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_advance;
|
||||
std::shared_ptr<glcxx::Texture> m_texture;
|
||||
std::shared_ptr<glcxx::Buffer> m_buffer;
|
||||
std::shared_ptr<glcxx::Array> m_array;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef PANE_H
|
||||
#define PANE_H
|
||||
|
||||
class Pane
|
||||
{
|
||||
public:
|
||||
Pane()
|
||||
{
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
}
|
||||
|
||||
virtual void move(int x, int y)
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
virtual void resize(int width, int height)
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
int win_x(int offset)
|
||||
{
|
||||
return m_x + offset;
|
||||
}
|
||||
|
||||
int win_y(int offset)
|
||||
{
|
||||
return m_y + offset;
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_x;
|
||||
int m_y;
|
||||
int m_width;
|
||||
int m_height;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,17 +0,0 @@
|
||||
#include "FlatShader.h"
|
||||
#include "Runtime.h"
|
||||
|
||||
FlatShader::FlatShader()
|
||||
{
|
||||
std::string v_path = Runtime::find(Runtime::SHADER, "flat.v");
|
||||
std::string f_path = Runtime::find(Runtime::SHADER, "flat.f");
|
||||
|
||||
m_program = glcxx::Program::create(
|
||||
glcxx::Shader::create_from_file(GL_VERTEX_SHADER, v_path.c_str()),
|
||||
glcxx::Shader::create_from_file(GL_FRAGMENT_SHADER, f_path.c_str()),
|
||||
"coords", 0);
|
||||
|
||||
m_uniforms.viewport_size = m_program->get_uniform_location("viewport_size");
|
||||
m_uniforms.position = m_program->get_uniform_location("position");
|
||||
m_uniforms.color = m_program->get_uniform_location("color");
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
#ifndef FLATSHADER_H
|
||||
#define FLATSHADER_H
|
||||
|
||||
#include "glcxx.hpp"
|
||||
#include <memory>
|
||||
|
||||
class FlatShader
|
||||
{
|
||||
public:
|
||||
FlatShader();
|
||||
|
||||
void use() { m_program->use(); }
|
||||
|
||||
void set_viewport_size(int width, int height)
|
||||
{
|
||||
glUniform2i(m_uniforms.viewport_size, width, height);
|
||||
}
|
||||
|
||||
void set_color(float r, float g, float b, float a)
|
||||
{
|
||||
glUniform4f(m_uniforms.color, r, g, b, a);
|
||||
}
|
||||
|
||||
void set_position(int x, int y)
|
||||
{
|
||||
glUniform2i(m_uniforms.position, x, y);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::shared_ptr<glcxx::Program> m_program;
|
||||
|
||||
struct
|
||||
{
|
||||
GLint viewport_size;
|
||||
GLint color;
|
||||
GLint position;
|
||||
} m_uniforms;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,51 +0,0 @@
|
||||
#include "GL.h"
|
||||
|
||||
GL::GL()
|
||||
{
|
||||
m_shaders.text = std::make_shared<TextShader>();
|
||||
m_shaders.text->use();
|
||||
m_shaders.text->set_texture(0);
|
||||
m_shaders.text->set_color(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
m_shaders.rect = std::make_shared<RectShader>();
|
||||
|
||||
GLint rect_coords[] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
1, 1,
|
||||
0, 1};
|
||||
m_rect_array = glcxx::Array::create();
|
||||
m_rect_array->bind();
|
||||
m_rect_buffer = glcxx::Buffer::create(GL_ARRAY_BUFFER, GL_STATIC_DRAW,
|
||||
rect_coords, sizeof(rect_coords));
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, 0);
|
||||
}
|
||||
|
||||
void GL::draw_rect(int x, int y, int width, int height,
|
||||
float r, float g, float b, float a)
|
||||
{
|
||||
m_rect_array->bind();
|
||||
m_shaders.rect->use();
|
||||
m_shaders.rect->set_color(r, g, b, a);
|
||||
m_shaders.rect->set_position(x, y);
|
||||
m_shaders.rect->set_size(width, height);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
|
||||
void GL::draw_character(int x, int y, uint32_t character, Font & font,
|
||||
float r, float g, float b, float a)
|
||||
{
|
||||
m_shaders.text->use();
|
||||
m_shaders.text->set_color(r, g, b, a);
|
||||
m_shaders.text->set_position(x, y + font.get_baseline_offset());
|
||||
font.get_glyph(character)->render();
|
||||
}
|
||||
|
||||
void GL::resize(int width, int height)
|
||||
{
|
||||
m_shaders.text->use();
|
||||
m_shaders.text->set_viewport_size(width, height);
|
||||
m_shaders.rect->use();
|
||||
m_shaders.rect->set_viewport_size(width, height);
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
#ifndef GL_H
|
||||
#define GL_H
|
||||
|
||||
#include "glcxx.hpp"
|
||||
#include "TextShader.h"
|
||||
#include "FlatShader.h"
|
||||
#include "RectShader.h"
|
||||
#include "Font.h"
|
||||
#include <memory>
|
||||
|
||||
class GL
|
||||
{
|
||||
public:
|
||||
GL();
|
||||
|
||||
void draw_rect(int x, int y, int width, int height,
|
||||
float r, float g, float b, float a);
|
||||
void draw_character(int x, int y, uint32_t character, Font & font,
|
||||
float r, float g, float b, float a);
|
||||
void resize(int width, int height);
|
||||
|
||||
protected:
|
||||
struct
|
||||
{
|
||||
std::shared_ptr<TextShader> text;
|
||||
std::shared_ptr<FlatShader> flat;
|
||||
std::shared_ptr<RectShader> rect;
|
||||
} m_shaders;
|
||||
|
||||
std::shared_ptr<glcxx::Array> m_rect_array;
|
||||
std::shared_ptr<glcxx::Buffer> m_rect_buffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,18 +0,0 @@
|
||||
#include "RectShader.h"
|
||||
#include "Runtime.h"
|
||||
|
||||
RectShader::RectShader()
|
||||
{
|
||||
std::string v_path = Runtime::find(Runtime::SHADER, "rect.v");
|
||||
std::string f_path = Runtime::find(Runtime::SHADER, "rect.f");
|
||||
|
||||
m_program = glcxx::Program::create(
|
||||
glcxx::Shader::create_from_file(GL_VERTEX_SHADER, v_path.c_str()),
|
||||
glcxx::Shader::create_from_file(GL_FRAGMENT_SHADER, f_path.c_str()),
|
||||
"coords", 0);
|
||||
|
||||
m_uniforms.viewport_size = m_program->get_uniform_location("viewport_size");
|
||||
m_uniforms.color = m_program->get_uniform_location("color");
|
||||
m_uniforms.position = m_program->get_uniform_location("position");
|
||||
m_uniforms.size = m_program->get_uniform_location("size");
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
#ifndef RECTSHADER_H
|
||||
#define RECTSHADER_H
|
||||
|
||||
#include "glcxx.hpp"
|
||||
#include <memory>
|
||||
|
||||
class RectShader
|
||||
{
|
||||
public:
|
||||
RectShader();
|
||||
|
||||
void use() { m_program->use(); }
|
||||
|
||||
void set_viewport_size(int width, int height)
|
||||
{
|
||||
glUniform2i(m_uniforms.viewport_size, width, height);
|
||||
}
|
||||
|
||||
void set_color(float r, float g, float b, float a)
|
||||
{
|
||||
glUniform4f(m_uniforms.color, r, g, b, a);
|
||||
}
|
||||
|
||||
void set_position(int x, int y)
|
||||
{
|
||||
glUniform2i(m_uniforms.position, x, y);
|
||||
}
|
||||
|
||||
void set_size(int x, int y)
|
||||
{
|
||||
glUniform2i(m_uniforms.size, x, y);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::shared_ptr<glcxx::Program> m_program;
|
||||
|
||||
struct
|
||||
{
|
||||
GLint viewport_size;
|
||||
GLint color;
|
||||
GLint position;
|
||||
GLint size;
|
||||
} m_uniforms;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,18 +0,0 @@
|
||||
#include "TextShader.h"
|
||||
#include "Runtime.h"
|
||||
|
||||
TextShader::TextShader()
|
||||
{
|
||||
std::string v_path = Runtime::find(Runtime::SHADER, "text.v");
|
||||
std::string f_path = Runtime::find(Runtime::SHADER, "text.f");
|
||||
|
||||
m_program = glcxx::Program::create(
|
||||
glcxx::Shader::create_from_file(GL_VERTEX_SHADER, v_path.c_str()),
|
||||
glcxx::Shader::create_from_file(GL_FRAGMENT_SHADER, f_path.c_str()),
|
||||
"coords", 0);
|
||||
|
||||
m_uniforms.viewport_size = m_program->get_uniform_location("viewport_size");
|
||||
m_uniforms.texture = m_program->get_uniform_location("texture");
|
||||
m_uniforms.color = m_program->get_uniform_location("color");
|
||||
m_uniforms.position = m_program->get_uniform_location("position");
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
#ifndef TEXTSHADER_H
|
||||
#define TEXTSHADER_H
|
||||
|
||||
#include "glcxx.hpp"
|
||||
#include <memory>
|
||||
|
||||
class TextShader
|
||||
{
|
||||
public:
|
||||
TextShader();
|
||||
|
||||
void use() { m_program->use(); }
|
||||
|
||||
void set_viewport_size(int width, int height)
|
||||
{
|
||||
glUniform2i(m_uniforms.viewport_size, width, height);
|
||||
}
|
||||
|
||||
void set_texture(int texture)
|
||||
{
|
||||
glUniform1i(m_uniforms.texture, texture);
|
||||
}
|
||||
|
||||
void set_color(float r, float g, float b, float a)
|
||||
{
|
||||
glUniform4f(m_uniforms.color, r, g, b, a);
|
||||
}
|
||||
|
||||
void set_position(int x, int y)
|
||||
{
|
||||
glUniform2i(m_uniforms.position, x, y);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::shared_ptr<glcxx::Program> m_program;
|
||||
|
||||
struct
|
||||
{
|
||||
GLint viewport_size;
|
||||
GLint texture;
|
||||
GLint color;
|
||||
GLint position;
|
||||
} m_uniforms;
|
||||
};
|
||||
|
||||
#endif
|
||||
-1339
File diff suppressed because it is too large.
Load diff
-1235
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,99 +0,0 @@
|
||||
#include "jes_icon-32x32.h"
|
||||
|
||||
/* GIMP RGB C-Source image dump (jes_icon-32x32.c) */
|
||||
|
||||
const uint8_t jes_icon_32x32[] = {
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\377\063\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\063\377\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000PPP\377\377\377\040\040\040\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\063\377\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000PPP\377\377\377\040\040\040\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\063\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\377\063\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\310\310\310\377\377\377"
|
||||
"\377\377\377\377\377\377\040\040\040\000\000\000\000\000\000\000\000\000***\261\261\261\361\361"
|
||||
"\361\365\365\365\265\265\265\"\"\"\000\000\000\000\000\000\000\000\000\000\000\000;;;\300\300\300"
|
||||
"\360\360\360\347\347\347\240\240\240\033\033\033\000\000\000\000\000\000\377\063\377\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000PPP\377\377\377\040\040\040\000\000\000\000\000"
|
||||
"\000&&&\360\360\360\252\252\252\035\035\035\030\030\030\247\247\247\334\334\334\005"
|
||||
"\005\005\000\000\000\000\000\000\022\022\022\360\360\360\221\221\221\022\022\022\025\025\025[[[\177"
|
||||
"\177\177\000\000\000\000\000\000\377\063\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"PPP\377\377\377\040\040\040\000\000\000\000\000\000\252\252\252\344\344\344\010\010\010\000\000"
|
||||
"\000\000\000\000\017\017\017\366\366\366```\000\000\000\000\000\000@@@\377\377\377\064\064\064\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\063\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000PPP\377\377\377\040\040\040\000\000\000\000\000\000\357\357\357\236\236\236"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\320\320\320\222\222\222\000\000\000\000\000\000\034\034\034\372"
|
||||
"\372\372\277\277\277JJJ\017\017\017\000\000\000\000\000\000\000\000\000\000\000\000\377\063\377\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000PPP\377\377\377\040\040\040\000\000\000\000\000\000"
|
||||
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\255\255\255\000\000\000\000\000\000\000\000\000LLL\310\310\310\375\375\375\376"
|
||||
"\376\376\307\307\307\061\061\061\000\000\000\000\000\000\377\063\377\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000PPP\377\377\377\040\040\040\000\000\000\000\000\000\360\360\360\211"
|
||||
"\211\211\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\013\013\013RRR\342\342\342\334\334\334\000\000\000\000\000\000\377\063\377\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000PPP\377\377\377\040\040\040\000\000\000\000\000\000\255\255"
|
||||
"\255\312\312\312\001\001\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000vvv\372\372\372\003\003\003\000\000\000\377\063\377\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000PPP\377\377\377\040\040\040\000\000\000\000\000\000***\363"
|
||||
"\363\363\232\232\232\"\"\"\013\013\013\065\065\065\230\230\230TTT\000\000\000\000\000\000M"
|
||||
"MM\227\227\227\063\063\063\012\012\012)))\320\320\320\266\266\266\000\000\000\000\000\000\377"
|
||||
"\063\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000PPP\377\377\377\040\040\040"
|
||||
"\000\000\000\000\000\000\000\000\000+++\255\255\255\355\355\355\365\365\365\312\312\312iii"
|
||||
"\007\007\007\000\000\000\000\000\000\006\006\006hhh\314\314\314\365\365\365\343\343\343\230\230\230"
|
||||
"\023\023\023\000\000\000\000\000\000\377\063\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000^^^\377\377\377\016\016\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\377\063\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\016\016\274\274"
|
||||
"\274\316\316\316\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\377\063\377\000\000\000\000\000\000\000\000\000\000\000\000\214\214\214\377\377\377\371\371\371"
|
||||
"\306\306\306+++\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\377\063\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\063\377\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\063\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef JES_ICON_32X32_H
|
||||
#define JES_ICON_32X32_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern const uint8_t jes_icon_32x32[];
|
||||
|
||||
#endif
|
||||
@@ -1,59 +0,0 @@
|
||||
#include "Jtk.h"
|
||||
|
||||
#ifdef JTK_X
|
||||
|
||||
#include <GL/glx.h>
|
||||
#include <stdio.h>
|
||||
|
||||
Display * g_display;
|
||||
XVisualInfo * g_vi;
|
||||
XSetWindowAttributes g_swa;
|
||||
GLXContext g_context;
|
||||
|
||||
/**
|
||||
* Initialize the Jtk subsystem.
|
||||
*
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
bool Jtk_Init()
|
||||
{
|
||||
static int glx_attribute_list[] = {
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None,
|
||||
};
|
||||
|
||||
g_display = XOpenDisplay(NULL);
|
||||
if (g_display == NULL)
|
||||
{
|
||||
fprintf(stderr, "XOpenDisplay() failure\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
g_vi = glXChooseVisual(g_display, DefaultScreen(g_display),
|
||||
glx_attribute_list);
|
||||
if (g_vi == NULL)
|
||||
{
|
||||
fprintf(stderr, "glXChooseVisual() failure\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
g_context = glXCreateContext(g_display, g_vi, NULL, True);
|
||||
if (g_context == NULL)
|
||||
{
|
||||
fprintf(stderr, "glXCreateContext() failure\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
Colormap colormap = XCreateColormap(g_display,
|
||||
RootWindow(g_display, g_vi->screen), g_vi->visual, AllocNone);
|
||||
g_swa.colormap = colormap;
|
||||
g_swa.border_pixel = 0;
|
||||
g_swa.event_mask = StructureNotifyMask |
|
||||
KeyPressMask | KeyReleaseMask |
|
||||
ButtonPressMask | ButtonReleaseMask;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef JTK_H
|
||||
#define JTK_H
|
||||
|
||||
#include "Jtk_event.h"
|
||||
#include "keys.h"
|
||||
#include "Jtk_time.h"
|
||||
#include "Jtk_timer.h"
|
||||
#include "Jtk_window.h"
|
||||
|
||||
bool Jtk_Init();
|
||||
|
||||
#endif
|
||||
@@ -1,482 +0,0 @@
|
||||
#include "Jtk.h"
|
||||
|
||||
#ifdef JTK_X
|
||||
|
||||
#include <GL/glx.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "Jtk_internal.h"
|
||||
#include <unordered_map>
|
||||
|
||||
/** Do not wait longer than 100ms */
|
||||
#define MAX_WAIT_TIME 100000u
|
||||
|
||||
static std::unordered_map<unsigned int, size_t> g_repeating_keys;
|
||||
static std::unordered_map<size_t, unsigned int> g_key_repeat_timers;
|
||||
|
||||
#if 0
|
||||
static void StopKeyRepeat(unsigned int x_keycode)
|
||||
{
|
||||
auto it = g_repeating_keys.find(x_keycode);
|
||||
if (it != g_repeating_keys.end())
|
||||
{
|
||||
size_t timer_id = it->second;
|
||||
Jtk_RemoveTimer(timer_id);
|
||||
g_repeating_keys.erase(x_keycode);
|
||||
g_key_repeat_timers.erase(timer_id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static unsigned int GetXState()
|
||||
{
|
||||
Window win;
|
||||
int i;
|
||||
unsigned int state;
|
||||
XQueryPointer(g_display, RootWindow(g_display, DefaultScreen(g_display)), &win, &win, &i, &i, &i, &i, &state);
|
||||
return state;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t XStateToJtkKeyMods(unsigned int x_state)
|
||||
{
|
||||
uint32_t mods = 0u;
|
||||
/* OR in the modifier states */
|
||||
if (x_state & ShiftMask)
|
||||
{
|
||||
mods |= JES_KEY_MODS_SHIFT;
|
||||
}
|
||||
if (x_state & LockMask)
|
||||
{
|
||||
mods |= JES_KEY_MODS_LOCK;
|
||||
}
|
||||
if (x_state & ControlMask)
|
||||
{
|
||||
mods |= JES_KEY_MODS_CTRL;
|
||||
}
|
||||
return mods;
|
||||
}
|
||||
|
||||
static uint32_t XKeyToJtkKey(unsigned int x_keycode, unsigned int x_state)
|
||||
{
|
||||
XKeyEvent x_key_event;
|
||||
x_key_event.type = KeyPress;
|
||||
x_key_event.display = g_display;
|
||||
/* Turn off the ControlMask bit for looking up keys. We'll handle control
|
||||
* keys ourselves. */
|
||||
x_key_event.state = x_state & ~ControlMask;
|
||||
x_key_event.keycode = x_keycode;
|
||||
char buffer;
|
||||
KeySym keysym;
|
||||
uint32_t key = JES_KEY_UNKNOWN;
|
||||
|
||||
if (XLookupString(&x_key_event, &buffer, 1, &keysym, nullptr) > 0)
|
||||
{
|
||||
if (buffer == '\r')
|
||||
{
|
||||
key = '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
key = buffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (keysym)
|
||||
{
|
||||
case XK_F1: key = JES_KEY_F1; break;
|
||||
case XK_F2: key = JES_KEY_F2; break;
|
||||
case XK_F3: key = JES_KEY_F3; break;
|
||||
case XK_F4: key = JES_KEY_F4; break;
|
||||
case XK_F5: key = JES_KEY_F5; break;
|
||||
case XK_F6: key = JES_KEY_F6; break;
|
||||
case XK_F7: key = JES_KEY_F7; break;
|
||||
case XK_F8: key = JES_KEY_F8; break;
|
||||
case XK_F9: key = JES_KEY_F9; break;
|
||||
case XK_F10: key = JES_KEY_F10; break;
|
||||
case XK_F11: key = JES_KEY_F11; break;
|
||||
case XK_F12: key = JES_KEY_F12; break;
|
||||
case XK_F13: key = JES_KEY_F13; break;
|
||||
case XK_F14: key = JES_KEY_F14; break;
|
||||
case XK_F15: key = JES_KEY_F15; break;
|
||||
case XK_F16: key = JES_KEY_F16; break;
|
||||
case XK_F17: key = JES_KEY_F17; break;
|
||||
case XK_F18: key = JES_KEY_F18; break;
|
||||
case XK_F19: key = JES_KEY_F19; break;
|
||||
case XK_F20: key = JES_KEY_F20; break;
|
||||
case XK_F21: key = JES_KEY_F21; break;
|
||||
case XK_F22: key = JES_KEY_F22; break;
|
||||
case XK_F23: key = JES_KEY_F23; break;
|
||||
case XK_F24: key = JES_KEY_F24; break;
|
||||
case XK_F25: key = JES_KEY_F25; break;
|
||||
case XK_F26: key = JES_KEY_F26; break;
|
||||
case XK_F27: key = JES_KEY_F27; break;
|
||||
case XK_F28: key = JES_KEY_F28; break;
|
||||
case XK_F29: key = JES_KEY_F29; break;
|
||||
case XK_F30: key = JES_KEY_F30; break;
|
||||
case XK_F31: key = JES_KEY_F31; break;
|
||||
|
||||
case XK_Shift_L: key = JES_KEY_SHIFT_L; break;
|
||||
case XK_Shift_R: key = JES_KEY_SHIFT_R; break;
|
||||
case XK_Control_L: key = JES_KEY_CTRL_L; break;
|
||||
case XK_Control_R: key = JES_KEY_CTRL_R; break;
|
||||
case XK_Caps_Lock: key = JES_KEY_CAPS_LOCK; break;
|
||||
case XK_Shift_Lock: key = JES_KEY_SHIFT_LOCK;break;
|
||||
|
||||
case XK_Meta_L: key = JES_KEY_META_L; break;
|
||||
case XK_Meta_R: key = JES_KEY_META_R; break;
|
||||
case XK_Alt_L: key = JES_KEY_ALT_L; break;
|
||||
case XK_Alt_R: key = JES_KEY_ALT_R; break;
|
||||
case XK_Super_L: key = JES_KEY_SUPER_L; break;
|
||||
case XK_Super_R: key = JES_KEY_SUPER_R; break;
|
||||
|
||||
case XK_Home: key = JES_KEY_HOME; break;
|
||||
case XK_Left: key = JES_KEY_LEFT; break;
|
||||
case XK_Up: key = JES_KEY_UP; break;
|
||||
case XK_Right: key = JES_KEY_RIGHT; break;
|
||||
case XK_Down: key = JES_KEY_DOWN; break;
|
||||
case XK_Page_Up: key = JES_KEY_PAGE_UP; break;
|
||||
case XK_Page_Down: key = JES_KEY_PAGE_DOWN; break;
|
||||
case XK_End: key = JES_KEY_END; break;
|
||||
case XK_Begin: key = JES_KEY_BEGIN; break;
|
||||
|
||||
case XK_Select: key = JES_KEY_SELECT; break;
|
||||
case XK_Print: key = JES_KEY_PRINT; break;
|
||||
case XK_Execute: key = JES_KEY_EXECUTE; break;
|
||||
case XK_Insert: key = JES_KEY_INSERT; break;
|
||||
case XK_Undo: key = JES_KEY_UNDO; break;
|
||||
case XK_Redo: key = JES_KEY_REDO; break;
|
||||
case XK_Menu: key = JES_KEY_MENU; break;
|
||||
case XK_Find: key = JES_KEY_FIND; break;
|
||||
case XK_Cancel: key = JES_KEY_CANCEL; break;
|
||||
case XK_Help: key = JES_KEY_HELP; break;
|
||||
case XK_Break: key = JES_KEY_BREAK; break;
|
||||
case XK_Num_Lock: key = JES_KEY_NUM_LOCK; break;
|
||||
|
||||
case XK_KP_Space: key = JES_KEY_KP_SPACE; break;
|
||||
case XK_KP_Tab: key = JES_KEY_KP_TAB; break;
|
||||
case XK_KP_Enter: key = JES_KEY_KP_ENTER; break;
|
||||
case XK_KP_F1: key = JES_KEY_KP_F1; break;
|
||||
case XK_KP_F2: key = JES_KEY_KP_F2; break;
|
||||
case XK_KP_F3: key = JES_KEY_KP_F3; break;
|
||||
case XK_KP_F4: key = JES_KEY_KP_F4; break;
|
||||
case XK_KP_Home: key = JES_KEY_KP_HOME; break;
|
||||
case XK_KP_Left: key = JES_KEY_KP_LEFT; break;
|
||||
case XK_KP_Up: key = JES_KEY_KP_UP; break;
|
||||
case XK_KP_Right: key = JES_KEY_KP_RIGHT; break;
|
||||
case XK_KP_Down: key = JES_KEY_KP_DOWN; break;
|
||||
case XK_KP_Page_Up: key = JES_KEY_KP_PAGE_UP; break;
|
||||
case XK_KP_Page_Down: key = JES_KEY_KP_PAGE_DOWN; break;
|
||||
case XK_KP_End: key = JES_KEY_KP_END; break;
|
||||
case XK_KP_Begin: key = JES_KEY_KP_BEGIN; break;
|
||||
case XK_KP_Insert: key = JES_KEY_KP_INSERT; break;
|
||||
case XK_KP_Delete: key = JES_KEY_KP_DELETE; break;
|
||||
case XK_KP_Equal: key = JES_KEY_KP_EQUAL; break;
|
||||
case XK_KP_Multiply: key = JES_KEY_KP_MULTIPLY; break;
|
||||
case XK_KP_Add: key = JES_KEY_KP_ADD; break;
|
||||
case XK_KP_Separator: key = JES_KEY_KP_SEPARATOR; break;
|
||||
case XK_KP_Subtract: key = JES_KEY_KP_SUBTRACT; break;
|
||||
case XK_KP_Decimal: key = JES_KEY_KP_DECIMAL; break;
|
||||
case XK_KP_Divide: key = JES_KEY_KP_DIVIDE; break;
|
||||
|
||||
case XK_KP_0: key = JES_KEY_KP_0; break;
|
||||
case XK_KP_1: key = JES_KEY_KP_1; break;
|
||||
case XK_KP_2: key = JES_KEY_KP_2; break;
|
||||
case XK_KP_3: key = JES_KEY_KP_3; break;
|
||||
case XK_KP_4: key = JES_KEY_KP_4; break;
|
||||
case XK_KP_5: key = JES_KEY_KP_5; break;
|
||||
case XK_KP_6: key = JES_KEY_KP_6; break;
|
||||
case XK_KP_7: key = JES_KEY_KP_7; break;
|
||||
case XK_KP_8: key = JES_KEY_KP_8; break;
|
||||
case XK_KP_9: key = JES_KEY_KP_9; break;
|
||||
}
|
||||
}
|
||||
|
||||
/* OR in the modifier states */
|
||||
key |= XStateToJtkKeyMods(x_state);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static Bool KeyRepeatCheckIfEvent(Display * display, XEvent * chkev,
|
||||
XPointer arg)
|
||||
{
|
||||
XEvent * release_event = (XEvent *)arg;
|
||||
if (chkev->type == KeyPress &&
|
||||
chkev->xkey.keycode == release_event->xkey.keycode &&
|
||||
chkev->xkey.time - release_event->xkey.time < 2)
|
||||
return True;
|
||||
return False;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this is a repeated key.
|
||||
*/
|
||||
static bool IsRepeatKey(Display * display, XEvent * event)
|
||||
{
|
||||
XEvent dummyev;
|
||||
if (XPending(display))
|
||||
{
|
||||
if (XCheckIfEvent(display, &dummyev, KeyRepeatCheckIfEvent,
|
||||
(XPointer)event) == True)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static Bool MatchKeyPress(Display * display, XEvent * event, XPointer arg)
|
||||
{
|
||||
XEvent * match_event = (XEvent *)arg;
|
||||
return (event->type == match_event->type) &&
|
||||
(event->xkey.window == match_event->xkey.window) &&
|
||||
(event->xkey.state == match_event->xkey.state) &&
|
||||
(event->xkey.keycode == match_event->xkey.keycode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an X key press event.
|
||||
*
|
||||
* @param x_event
|
||||
* Pointer to the X event.
|
||||
* @param event
|
||||
* Pointer to the Jtk event.
|
||||
*/
|
||||
static bool ProcessXKeyPressEvent(XEvent * x_event, Jtk_Event * event)
|
||||
{
|
||||
unsigned int x_keycode = x_event->xkey.keycode;
|
||||
event->type = JTK_EVENT_KEY_PRESS;
|
||||
event->key.repeat = false;
|
||||
event->key.key = XKeyToJtkKey(x_keycode, x_event->xkey.state);
|
||||
event->key.x_keycode = x_keycode;
|
||||
/* Remove any following keypress events for the same keycode from the X
|
||||
* queue. */
|
||||
XEvent remove_event;
|
||||
while (XCheckIfEvent(g_display, &remove_event, MatchKeyPress, (XPointer)x_event) == True)
|
||||
{
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an X key release event.
|
||||
*
|
||||
* @param x_event
|
||||
* Pointer to the X event.
|
||||
* @param event
|
||||
* Pointer to the Jtk event.
|
||||
*/
|
||||
static bool ProcessXKeyReleaseEvent(XEvent * x_event, Jtk_Event * event)
|
||||
{
|
||||
#if 0
|
||||
if (IsRepeatKey(g_display, x_event))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
StopKeyRepeat(x_event->xkey.keycode);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static Bool MatchButtonPress(Display * display, XEvent * event, XPointer arg)
|
||||
{
|
||||
XEvent * match_event = (XEvent *)arg;
|
||||
return (event->type == match_event->type) &&
|
||||
(event->xbutton.window == match_event->xbutton.window) &&
|
||||
(event->xbutton.state == match_event->xbutton.state) &&
|
||||
(event->xbutton.button == match_event->xbutton.button);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an X button press event.
|
||||
*/
|
||||
static bool ProcessXButtonPressEvent(XEvent * x_event, Jtk_Event * event)
|
||||
{
|
||||
event->type = JTK_EVENT_BUTTON_PRESS;
|
||||
event->button.mods = XStateToJtkKeyMods(x_event->xbutton.state);
|
||||
event->button.button = x_event->xbutton.button;
|
||||
/* If this is a mouse wheel scroll event, remove any following scroll
|
||||
* events. */
|
||||
if ((event->button.button == 4) || (event->button.button == 5))
|
||||
{
|
||||
XEvent remove_event;
|
||||
while (XCheckIfEvent(g_display, &remove_event, MatchButtonPress, (XPointer)x_event) == True)
|
||||
{
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an X configure event.
|
||||
*
|
||||
* @param x_event
|
||||
* Pointer to the X event.
|
||||
* @param event
|
||||
* Pointer to the Jtk event.
|
||||
*/
|
||||
static bool ProcessConfigureEvent(XEvent * x_event, Jtk_Event * event)
|
||||
{
|
||||
event->type = JTK_EVENT_WINDOW_RESIZE;
|
||||
event->resize.width = x_event->xconfigure.width;
|
||||
event->resize.height = x_event->xconfigure.height;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an X ClientMessage event.
|
||||
*
|
||||
* @param x_event
|
||||
* Pointer to the X event.
|
||||
* @param event
|
||||
* Pointer to the Jtk event.
|
||||
*/
|
||||
static bool ProcessXClientMessageEvent(XEvent * x_event, Jtk_Event * event)
|
||||
{
|
||||
Atom wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", False);
|
||||
if (x_event->xclient.data.l[0] == (long)wm_delete_window_atom)
|
||||
{
|
||||
event->type = JTK_EVENT_WINDOW_CLOSE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an X event.
|
||||
*
|
||||
* @param x_event
|
||||
* Pointer to the X event.
|
||||
* @param event
|
||||
* Pointer to the Jtk event.
|
||||
*
|
||||
* @retval true
|
||||
* The event should be passed to the user and event has been filled in.
|
||||
* @retval false
|
||||
* The event should not be passed to the user.
|
||||
*/
|
||||
static bool ProcessXEvent(XEvent * x_event, Jtk_Event * event)
|
||||
{
|
||||
switch (x_event->type)
|
||||
{
|
||||
case KeyPress:
|
||||
return ProcessXKeyPressEvent(x_event, event);
|
||||
|
||||
case KeyRelease:
|
||||
return ProcessXKeyReleaseEvent(x_event, event);
|
||||
|
||||
case ButtonPress:
|
||||
return ProcessXButtonPressEvent(x_event, event);
|
||||
|
||||
case ButtonRelease:
|
||||
break;
|
||||
|
||||
case Expose:
|
||||
event->type = JTK_EVENT_WINDOW_EXPOSE;
|
||||
return true;
|
||||
|
||||
case GraphicsExpose:
|
||||
event->type = JTK_EVENT_WINDOW_EXPOSE;
|
||||
return true;
|
||||
|
||||
case MapNotify:
|
||||
event->type = JTK_EVENT_WINDOW_EXPOSE;
|
||||
return true;
|
||||
|
||||
case ConfigureNotify:
|
||||
return ProcessConfigureEvent(x_event, event);
|
||||
|
||||
case ClientMessage:
|
||||
return ProcessXClientMessageEvent(x_event, event);
|
||||
|
||||
case MappingNotify:
|
||||
XRefreshKeyboardMapping(&x_event->xmapping);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Jtk_CheckEvent(Jtk_Event * event)
|
||||
{
|
||||
/* First check for an X event. */
|
||||
while (XPending(g_display) > 0)
|
||||
{
|
||||
XEvent x_event;
|
||||
XNextEvent(g_display, &x_event);
|
||||
if (ProcessXEvent(&x_event, event))
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Next check if any timer has expired. */
|
||||
size_t timer_id = Jtk_GetExpiredTimer();
|
||||
if (timer_id != (size_t)-1)
|
||||
{
|
||||
#if 0
|
||||
auto it = g_key_repeat_timers.find(timer_id);
|
||||
if (it != g_key_repeat_timers.end())
|
||||
{
|
||||
event->type = JTK_EVENT_KEY_PRESS;
|
||||
event->key.repeat = true;
|
||||
event->key.key = XKeyToJtkKey(it->second);
|
||||
event->key.x_keycode = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
event->type = JTK_EVENT_TIMER;
|
||||
event->timer.timer_id = timer_id;
|
||||
event->timer.user1 = Jtk_GetTimerUserData(timer_id, 0u);
|
||||
event->timer.user2 = Jtk_GetTimerUserData(timer_id, 1u);
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
Jtk_ServiceTimer(timer_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Jtk_WaitEvent(Jtk_Event * event)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (Jtk_CheckEvent(event))
|
||||
return;
|
||||
|
||||
/* Wait for something to happen. */
|
||||
uint64_t time_to_wait = Jtk_TimeToNextTimerExpiration();
|
||||
if (time_to_wait > MAX_WAIT_TIME)
|
||||
{
|
||||
time_to_wait = MAX_WAIT_TIME;
|
||||
}
|
||||
|
||||
int x_fd = ConnectionNumber(g_display);
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(x_fd, &fds);
|
||||
struct timeval tv;
|
||||
tv.tv_sec = time_to_wait / 1000000u;
|
||||
tv.tv_usec = time_to_wait % 1000000u;
|
||||
select(x_fd + 1, &fds, nullptr, nullptr, &tv);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void Jtk_BeginKeyRepeat(Jtk_KeyEvent * key_event, uint32_t delay, uint32_t interval)
|
||||
{
|
||||
StopKeyRepeat(key_event->x_keycode);
|
||||
size_t timer_id = Jtk_AddTimer(delay, interval, nullptr, nullptr);
|
||||
g_repeating_keys[key_event->x_keycode] = timer_id;
|
||||
g_key_repeat_timers[timer_id] = key_event->x_keycode;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,62 +0,0 @@
|
||||
#ifndef JTK_EVENT_H
|
||||
#define JTK_EVENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define JTK_EVENT_WINDOW_CLOSE 1u
|
||||
#define JTK_EVENT_WINDOW_EXPOSE 2u
|
||||
#define JTK_EVENT_KEY_PRESS 3u
|
||||
#define JTK_EVENT_KEY_RELEASE 4u
|
||||
#define JTK_EVENT_BUTTON_PRESS 5u
|
||||
#define JTK_EVENT_BUTTON_RELEASE 6u
|
||||
#define JTK_EVENT_TIMER 7u
|
||||
#define JTK_EVENT_WINDOW_RESIZE 8u
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool repeat;
|
||||
uint32_t key;
|
||||
#ifdef JTK_X
|
||||
unsigned int x_keycode;
|
||||
#endif
|
||||
} Jtk_KeyEvent;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t mods;
|
||||
uint8_t button;
|
||||
} Jtk_ButtonEvent;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t timer_id;
|
||||
void * user1;
|
||||
void * user2;
|
||||
} Jtk_TimerEvent;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t width;
|
||||
size_t height;
|
||||
} Jtk_WindowResizeEvent;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t type;
|
||||
union
|
||||
{
|
||||
Jtk_KeyEvent key;
|
||||
Jtk_ButtonEvent button;
|
||||
Jtk_TimerEvent timer;
|
||||
Jtk_WindowResizeEvent resize;
|
||||
};
|
||||
} Jtk_Event;
|
||||
|
||||
bool Jtk_CheckEvent(Jtk_Event * event);
|
||||
void Jtk_WaitEvent(Jtk_Event * event);
|
||||
#if 0
|
||||
void Jtk_BeginKeyRepeat(Jtk_KeyEvent * key_event, uint32_t delay, uint32_t interval);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,9 +0,0 @@
|
||||
#ifndef JTK_INTERNAL_H
|
||||
#define JTK_INTERNAL_H
|
||||
|
||||
extern Display * g_display;
|
||||
extern XVisualInfo * g_vi;
|
||||
extern XSetWindowAttributes g_swa;
|
||||
extern GLXContext g_context;
|
||||
|
||||
#endif
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "Jtk.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
uint64_t Jtk_UsTime()
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
return (uint64_t)tv.tv_sec * 1000000u + (uint64_t)tv.tv_usec;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#ifndef JTK_TIME_H
|
||||
#define JTK_TIME_H
|
||||
|
||||
#include "Jtk_timer.h"
|
||||
|
||||
bool Jtk_Init();
|
||||
uint64_t Jtk_UsTime();
|
||||
|
||||
#endif
|
||||
@@ -1,157 +0,0 @@
|
||||
#include "Jtk.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t next; /**< Time the timer next expires (us). */
|
||||
uint64_t interval; /**< Timer interval (us). */
|
||||
size_t id; /**< Timer ID. */
|
||||
void * user[2]; /**< User data pointers. */
|
||||
} Timer;
|
||||
|
||||
/** Vector used to allocate timer IDs. */
|
||||
static std::vector<std::shared_ptr<Timer>> g_timers;
|
||||
|
||||
/** Linked list used to traverse all active timers. */
|
||||
static std::list<std::shared_ptr<Timer>> g_active_timers;
|
||||
|
||||
static size_t AllocateTimerID()
|
||||
{
|
||||
for (size_t i = 0; i < g_timers.size(); i++)
|
||||
{
|
||||
if (!g_timers[i])
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
g_timers.push_back(nullptr);
|
||||
return g_timers.size() - 1u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a timer.
|
||||
*
|
||||
* @param delay
|
||||
* Delay time in milliseconds.
|
||||
* @param interval
|
||||
* Interval time in milliseconds. A value of 0 indicates that the timer
|
||||
* is not periodic.
|
||||
* @param user1
|
||||
* User data pointer 1. This value is not used by Jtk but can be retrieved by
|
||||
* the user when a timer expires.
|
||||
* @param user2
|
||||
* User data pointer 2. This value is not used by Jtk but can be retrieved by
|
||||
* the user when a timer expires.
|
||||
*
|
||||
* @return
|
||||
* Timer ID.
|
||||
*/
|
||||
size_t Jtk_AddTimer(uint32_t delay, uint32_t interval, void * user1, void * user2)
|
||||
{
|
||||
uint64_t current_system_time = Jtk_UsTime();
|
||||
size_t timer_id = AllocateTimerID();
|
||||
auto timer = std::make_shared<Timer>();
|
||||
timer->next = current_system_time + (delay * 1000u);
|
||||
timer->interval = interval * 1000u;
|
||||
timer->id = timer_id;
|
||||
timer->user[0] = user1;
|
||||
timer->user[1] = user2;
|
||||
g_timers[timer_id] = timer;
|
||||
g_active_timers.push_back(timer);
|
||||
return timer_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a timer.
|
||||
*
|
||||
* @param timer_id
|
||||
* The ID of the timer to remove.
|
||||
*/
|
||||
void Jtk_RemoveTimer(size_t timer_id)
|
||||
{
|
||||
if (timer_id < g_timers.size())
|
||||
{
|
||||
auto timer = g_timers[timer_id];
|
||||
g_active_timers.remove(timer);
|
||||
g_timers[timer_id] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the amount of time until the next timer expires (in us).
|
||||
*
|
||||
* @return
|
||||
* Time (in us) until the next timer expires. This will be 0 if an active
|
||||
* timer has already expired, and will be (uint64_t)-1 if there are no
|
||||
* active timers.
|
||||
*/
|
||||
uint64_t Jtk_TimeToNextTimerExpiration()
|
||||
{
|
||||
uint64_t time = (uint64_t)-1;
|
||||
uint64_t current_system_time = Jtk_UsTime();
|
||||
for (auto & timer : g_active_timers)
|
||||
{
|
||||
if (timer->next <= current_system_time)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint64_t time_until_this_timer = timer->next - current_system_time;
|
||||
if (time_until_this_timer < time)
|
||||
{
|
||||
time = time_until_this_timer;
|
||||
}
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Service a timer.
|
||||
*
|
||||
* This will increment the timer's next activation time by its interval, or
|
||||
* for a timer with an interval of 0, will remove the timer.
|
||||
*
|
||||
* @param timer_id
|
||||
* The ID of the timer to service.
|
||||
*/
|
||||
void Jtk_ServiceTimer(size_t timer_id)
|
||||
{
|
||||
auto timer = g_timers[timer_id];
|
||||
if (timer->interval == 0u)
|
||||
{
|
||||
Jtk_RemoveTimer(timer_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
timer->next += timer->interval;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ID of an expired timer.
|
||||
*
|
||||
* @return
|
||||
* The ID of an expired timer, or (size_t)-1 if no timer is expired.
|
||||
*/
|
||||
size_t Jtk_GetExpiredTimer()
|
||||
{
|
||||
uint64_t current_system_time = Jtk_UsTime();
|
||||
for (auto & timer : g_active_timers)
|
||||
{
|
||||
if (timer->next <= current_system_time)
|
||||
{
|
||||
return timer->id;
|
||||
}
|
||||
}
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
void * Jtk_GetTimerUserData(size_t timer_id, uint8_t index)
|
||||
{
|
||||
if (timer_id < g_timers.size())
|
||||
{
|
||||
return g_timers[timer_id]->user[index];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef JTK_TIMER_H
|
||||
#define JTK_TIMER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
size_t Jtk_AddTimer(uint32_t delay, uint32_t interval, void * user1, void * user2);
|
||||
void Jtk_RemoveTimer(size_t timer_id);
|
||||
uint64_t Jtk_TimeToNextTimerExpiration();
|
||||
void Jtk_ServiceTimer(size_t timer_id);
|
||||
size_t Jtk_GetExpiredTimer();
|
||||
void * Jtk_GetTimerUserData(size_t timer_id, uint8_t index);
|
||||
|
||||
#endif
|
||||
@@ -1,95 +0,0 @@
|
||||
#include "Jtk.h"
|
||||
|
||||
#ifdef JTK_X
|
||||
|
||||
#include <GL/glx.h>
|
||||
#include "Jtk_internal.h"
|
||||
#include <stdio.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <cstring>
|
||||
|
||||
static Bool WaitForNotify(Display * display, XEvent * event, XPointer arg)
|
||||
{
|
||||
return (event->type == MapNotify) && (event->xmap.window == (Window)arg);
|
||||
}
|
||||
|
||||
void * Jtk_CreateWindow()
|
||||
{
|
||||
XEvent event;
|
||||
Window window = XCreateWindow(g_display,
|
||||
RootWindow(g_display, g_vi->screen),
|
||||
0, 0, 800, 800, 0, g_vi->depth, InputOutput, g_vi->visual,
|
||||
CWBorderPixel | CWColormap | CWEventMask, &g_swa);
|
||||
XMapWindow(g_display, window);
|
||||
XIfEvent(g_display, &event, WaitForNotify, (XPointer)window);
|
||||
if (glXMakeCurrent(g_display, window, g_context) == False)
|
||||
{
|
||||
fprintf(stderr, "glXMakeCurrent() failure\n");
|
||||
XDestroyWindow(g_display, window);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Disable the window close button. */
|
||||
Atom wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", False);
|
||||
XSetWMProtocols(g_display, window, &wm_delete_window_atom, 1);
|
||||
|
||||
return (void *)window;
|
||||
}
|
||||
|
||||
void Jtk_SwapBuffers(void * window)
|
||||
{
|
||||
glXSwapBuffers(g_display, (Window)window);
|
||||
}
|
||||
|
||||
void Jtk_CloseWindow(void * window)
|
||||
{
|
||||
XDestroyWindow(g_display, (Window)window);
|
||||
}
|
||||
|
||||
void Jtk_SetWindowTitle(void * window, const char * title)
|
||||
{
|
||||
XTextProperty title_property;
|
||||
if (XStringListToTextProperty((char **)&title, 1, &title_property) != 0)
|
||||
{
|
||||
XSetTextProperty(g_display, (Window)window, &title_property, XA_WM_NAME);
|
||||
XFree(title_property.value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the window icon.
|
||||
*
|
||||
* @param window
|
||||
* The window to operate on.
|
||||
* @param data
|
||||
* The format of data must be 32 bits per pixel in BGRA format (e.g. data[0]
|
||||
* is blue value, data[3] is alpha value of first pixel).
|
||||
* @param width
|
||||
* Icon width.
|
||||
* @param height
|
||||
* Icon height.
|
||||
*/
|
||||
void Jtk_SetWindowIcon(void * window, const uint8_t * data,
|
||||
size_t width, size_t height)
|
||||
{
|
||||
Atom net_wm_icon_atom = XInternAtom(g_display, "_NET_WM_ICON", False);
|
||||
size_t property_size = (2u + width * height) * sizeof(long);
|
||||
unsigned long * property_data = (unsigned long *)malloc(property_size);
|
||||
property_data[0] = width;
|
||||
property_data[1] = height;
|
||||
unsigned long * dest = &property_data[2];
|
||||
const uint32_t * src = (const uint32_t *)data;
|
||||
for (size_t row = 0u; row < height; row++)
|
||||
{
|
||||
for (size_t col = 0u; col < width; col++)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
}
|
||||
}
|
||||
XChangeProperty(g_display, (Window)window, net_wm_icon_atom, XA_CARDINAL,
|
||||
32, PropModeReplace, (uint8_t *)property_data, property_size);
|
||||
XFlush(g_display);
|
||||
free(property_data);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef JTK_WINDOW_H
|
||||
#define JTK_WINDOW_H
|
||||
|
||||
void * Jtk_CreateWindow();
|
||||
void Jtk_SwapBuffers(void * window);
|
||||
void Jtk_CloseWindow(void * window);
|
||||
void Jtk_SetWindowTitle(void * window, const char * title);
|
||||
void Jtk_SetWindowIcon(void * window, const uint8_t * data,
|
||||
size_t width, size_t height);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,178 @@
|
||||
module jes.core.databuffer;
|
||||
|
||||
import core.stdc.string;
|
||||
import core.stdc.stdlib;
|
||||
|
||||
class DataBuffer
|
||||
{
|
||||
/** Number of bytes to initially allocate for an empty data buffer. */
|
||||
enum size_t INITIAL_CAPACITY = 8u;
|
||||
|
||||
/** Number of extra bytes to allocate when growing. */
|
||||
enum size_t GROWTH_CAPACITY = 2000u;
|
||||
|
||||
/** Size of data. */
|
||||
private size_t m_size;
|
||||
|
||||
/** Underlying capacity in memory. */
|
||||
private size_t m_capacity;
|
||||
|
||||
/** Data. */
|
||||
private ubyte * m_data;
|
||||
|
||||
/**
|
||||
* Construct a DataBuffer object that is initially empty.
|
||||
*
|
||||
* @param capacity The number of bytes to initially allocate.
|
||||
*/
|
||||
this(size_t capacity = INITIAL_CAPACITY)
|
||||
{
|
||||
m_data = cast(ubyte *)malloc(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for a DataBuffer object.
|
||||
*/
|
||||
~this()
|
||||
{
|
||||
free(m_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the address of a byte in the data buffer.
|
||||
*
|
||||
* @param offset Byte offset into the data buffer.
|
||||
*/
|
||||
ubyte * address(size_t offset)
|
||||
{
|
||||
return &m_data[offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the address of a byte in the data buffer.
|
||||
*
|
||||
* @param offset Byte offset into the data buffer.
|
||||
*/
|
||||
const(ubyte) * address(size_t offset) const
|
||||
{
|
||||
return &m_data[offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase data from the data buffer.
|
||||
*
|
||||
* @param position The index of the data to remove.
|
||||
* @param n The number of bytes to remove.
|
||||
*/
|
||||
void erase(size_t position, size_t n)
|
||||
{
|
||||
if ((position < m_size) && (position + n <= m_size))
|
||||
{
|
||||
memmove(&m_data[position], &m_data[position + n], m_size - (position + n));
|
||||
m_size -= n;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert data into the data buffer.
|
||||
*
|
||||
* @param position The index at which to insert the data.
|
||||
* @param data The data to insert.
|
||||
* @param n The number of bytes to insert.
|
||||
*/
|
||||
void insert(size_t position, const ubyte * data, size_t n)
|
||||
{
|
||||
if (position <= m_size)
|
||||
{
|
||||
ensure_free(n);
|
||||
memmove(&m_data[position + n], &m_data[position], m_size - position);
|
||||
memcpy(&m_data[position], data, n);
|
||||
m_size += n;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the data in the data buffer.
|
||||
*/
|
||||
@property size_t size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that there are at least n free.
|
||||
*
|
||||
* @param n The number of bytes that must be free.
|
||||
*/
|
||||
private void ensure_free(size_t n)
|
||||
{
|
||||
if ((m_capacity - m_size) < n)
|
||||
{
|
||||
/* Grow the data buffer. */
|
||||
m_capacity = m_size + n + GROWTH_CAPACITY;
|
||||
ubyte * new_data = cast(ubyte *)malloc(m_capacity);
|
||||
memcpy(new_data, m_data, m_size);
|
||||
free(m_data);
|
||||
m_data = new_data;
|
||||
}
|
||||
}
|
||||
|
||||
version(unittest) invariant
|
||||
{
|
||||
assert(m_data !is null);
|
||||
assert(m_size <= m_capacity);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
DataBuffer tb = new DataBuffer();
|
||||
assert(tb.size == 0u);
|
||||
ubyte[20] dat = 5u;
|
||||
tb.insert(0u, dat.ptr, dat.length);
|
||||
ubyte * first_address = tb.address(5u);
|
||||
assert(tb.size() == 20u);
|
||||
for (size_t i = 0u; i < 20u; i++)
|
||||
{
|
||||
assert(*tb.address(i) == 5u);
|
||||
}
|
||||
dat[] = 10u;
|
||||
tb.insert(5u, dat.ptr, dat.length);
|
||||
assert(tb.size() == 40u);
|
||||
for (size_t i = 0u; i < 40u; i++)
|
||||
{
|
||||
if (i < 5u)
|
||||
{
|
||||
assert(*tb.address(i) == 5u);
|
||||
}
|
||||
else if (i < 25u)
|
||||
{
|
||||
assert(*tb.address(i) == 10u);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(*tb.address(i) == 5u);
|
||||
}
|
||||
}
|
||||
tb.erase(15u, 15u);
|
||||
assert(tb.size() == 25u);
|
||||
for (size_t i = 0u; i < 25u; i++)
|
||||
{
|
||||
if (i < 5u)
|
||||
{
|
||||
assert(*tb.address(i) == 5u);
|
||||
}
|
||||
else if (i < 15u)
|
||||
{
|
||||
assert(*tb.address(i) == 10u);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(*tb.address(i) == 5u);
|
||||
}
|
||||
}
|
||||
assert((tb.address(24u) - tb.address(0u)) == 24u);
|
||||
tb.insert(30u, dat.ptr, dat.length);
|
||||
assert(tb.size == 25u);
|
||||
assert(first_address == tb.address(5u));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
module jes.core.encoding;
|
||||
|
||||
struct Encoding
|
||||
{
|
||||
enum : ubyte
|
||||
{
|
||||
UTF8,
|
||||
CP1252,
|
||||
UTF16_LE,
|
||||
UTF16_BE,
|
||||
}
|
||||
|
||||
ubyte type;
|
||||
alias type this;
|
||||
|
||||
this(ubyte type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
uint decode(const(ubyte) * data, size_t * encoded_size)
|
||||
{
|
||||
uint result;
|
||||
size_t size;
|
||||
ubyte following_bytes;
|
||||
ubyte c;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case UTF8:
|
||||
c = *data;
|
||||
if ((c & 0x80u) == 0u)
|
||||
{
|
||||
result = c;
|
||||
size = 1u;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((c & 0xE0u) == 0xC0u)
|
||||
{
|
||||
result = c & 0x1Fu;
|
||||
following_bytes = 1u;
|
||||
}
|
||||
else if ((c & 0xF0u) == 0xE0u)
|
||||
{
|
||||
result = c & 0x0Fu;
|
||||
following_bytes = 2u;
|
||||
}
|
||||
else if ((c & 0xF8u) == 0xF0u)
|
||||
{
|
||||
result = c & 0x07u;
|
||||
following_bytes = 3u;
|
||||
}
|
||||
else if ((c & 0xFCu) == 0xF8u)
|
||||
{
|
||||
result = c & 0x03u;
|
||||
following_bytes = 4u;
|
||||
}
|
||||
else if ((c & 0xFEu) == 0xFCu)
|
||||
{
|
||||
result = c & 0x01u;
|
||||
following_bytes = 5u;
|
||||
}
|
||||
size = following_bytes + 1u;
|
||||
while (following_bytes-- > 0u)
|
||||
{
|
||||
data++;
|
||||
result <<= 6u;
|
||||
result |= *data & 0x3Fu;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CP1252:
|
||||
/* TODO */
|
||||
break;
|
||||
case UTF16_LE:
|
||||
result = data[0] | (data[1] << 8u);
|
||||
size = 2u;
|
||||
break;
|
||||
case UTF16_BE:
|
||||
result = (data[0] << 8u) | data[1];
|
||||
size = 2u;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (encoded_size != null)
|
||||
{
|
||||
*encoded_size = size;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ubyte num_bytes_to_encode_code_point(uint code_point)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UTF8:
|
||||
if (code_point <= 0x7Fu)
|
||||
{
|
||||
return 1u;
|
||||
}
|
||||
else if (code_point <= 0x7FFu)
|
||||
{
|
||||
return 2u;
|
||||
}
|
||||
else if (code_point <= 0xFFFFu)
|
||||
{
|
||||
return 3u;
|
||||
}
|
||||
else if (code_point <= 0x1FFFFFu)
|
||||
{
|
||||
return 4u;
|
||||
}
|
||||
else if (code_point <= 0x3FFFFFFu)
|
||||
{
|
||||
return 5u;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 6u;
|
||||
}
|
||||
case CP1252:
|
||||
/* TODO */
|
||||
break;
|
||||
case UTF16_LE:
|
||||
case UTF16_BE:
|
||||
return 2u;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
ubyte encode(uint code_point, ubyte * buffer)
|
||||
{
|
||||
ubyte size;
|
||||
switch (type)
|
||||
{
|
||||
case UTF8:
|
||||
size = num_bytes_to_encode_code_point(code_point);
|
||||
if (size == 1u)
|
||||
{
|
||||
*buffer = cast(ubyte)code_point;
|
||||
}
|
||||
else if (size > 1u)
|
||||
{
|
||||
*buffer = cast(ubyte)((0xFFu << (8u - size)) | (code_point >> (6u * (size - 1u))));
|
||||
const ubyte end = cast(ubyte)(size - 1u);
|
||||
for (ubyte i = 0u; i < end; i++)
|
||||
{
|
||||
buffer[end - i] = 0x80u | (code_point >> (6u * i) & 0x3Fu);
|
||||
}
|
||||
}
|
||||
return size;
|
||||
case CP1252:
|
||||
/* TODO */
|
||||
break;
|
||||
case UTF16_LE:
|
||||
buffer[0] = cast(ubyte)code_point;
|
||||
buffer[1] = cast(ubyte)(code_point >> 8u);
|
||||
return 2u;
|
||||
case UTF16_BE:
|
||||
buffer[0] = cast(ubyte)(code_point >> 8u);
|
||||
buffer[1] = cast(ubyte)code_point;
|
||||
return 2u;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
static Encoding detect_encoding(const ubyte * data, size_t n, size_t * bom_size)
|
||||
{
|
||||
*bom_size = 0u;
|
||||
|
||||
/* First check for BOM presence. */
|
||||
if ((n >= 3) &&
|
||||
(data[0..3] == [0xEFu, 0xBBu, 0xBFu]) &&
|
||||
validate_utf8(&data[3], n - 3u))
|
||||
{
|
||||
*bom_size = 3u;
|
||||
return Encoding(UTF8);
|
||||
}
|
||||
if ((n >= 2) &&
|
||||
(data[0..2] == [0xFEu, 0xFFu]) &&
|
||||
((n & 1u) == 0u))
|
||||
{
|
||||
*bom_size = 2u;
|
||||
return Encoding(UTF16_BE);
|
||||
}
|
||||
if ((n >= 2) &&
|
||||
(data[0..2] == [0xFFu, 0xFEu]) &&
|
||||
((n & 1u) == 0u))
|
||||
{
|
||||
*bom_size = 2u;
|
||||
return Encoding(UTF16_LE);
|
||||
}
|
||||
|
||||
/* No BOM found. Check heuristically. */
|
||||
if (check_utf16(data, n, true))
|
||||
{
|
||||
return Encoding(UTF16_LE);
|
||||
}
|
||||
|
||||
if (check_utf16(data, n, false))
|
||||
{
|
||||
return Encoding(UTF16_BE);
|
||||
}
|
||||
|
||||
if (validate_utf8(data, n))
|
||||
{
|
||||
return Encoding(UTF8);
|
||||
}
|
||||
|
||||
return Encoding(CP1252);
|
||||
}
|
||||
|
||||
private static bool check_utf8_continuation_bytes(const ubyte * data, size_t n)
|
||||
{
|
||||
for (size_t i = 0u; i < n; i++)
|
||||
{
|
||||
if ((data[i] & 0xC0u) != 0x80u)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool validate_utf8(const ubyte * data, size_t n)
|
||||
{
|
||||
for (size_t i = 0u; i < n; i++)
|
||||
{
|
||||
const ubyte c = data[i];
|
||||
size_t n_continuation_bytes;
|
||||
if ((c & 0x80u) != 0u)
|
||||
{
|
||||
if ((c & 0xE0u) == 0xC0u)
|
||||
{
|
||||
n_continuation_bytes = 1u;
|
||||
}
|
||||
else if ((c & 0xF0u) == 0xE0u)
|
||||
{
|
||||
n_continuation_bytes = 2u;
|
||||
}
|
||||
else if ((c & 0xF8u) == 0xF0u)
|
||||
{
|
||||
n_continuation_bytes = 3u;
|
||||
}
|
||||
else if ((c & 0xFCu) == 0xF8u)
|
||||
{
|
||||
n_continuation_bytes = 4u;
|
||||
}
|
||||
else if ((c & 0xFEu) == 0xFCu)
|
||||
{
|
||||
n_continuation_bytes = 5u;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (((i + n_continuation_bytes) < n) &&
|
||||
check_utf8_continuation_bytes(&data[i + 1], n_continuation_bytes))
|
||||
{
|
||||
i += n_continuation_bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool check_utf16(const ubyte * data, size_t n, bool le)
|
||||
{
|
||||
size_t n_high_zeros;
|
||||
if ((n == 0u) || ((n & 1u) != 0u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ubyte off = le ? 1u : 0u;
|
||||
for (size_t i = 0u; i < n; i += 2u)
|
||||
{
|
||||
if (data[i + off] == 0u)
|
||||
{
|
||||
n_high_zeros++;
|
||||
}
|
||||
}
|
||||
/* 20% threshold of high zeroes required. */
|
||||
return (40u * n_high_zeros / n) != 0u;
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
import std.stdio;
|
||||
import std.file;
|
||||
const(ubyte)[] dat;
|
||||
Encoding e;
|
||||
size_t bom_size = 54321;
|
||||
|
||||
e = Encoding.detect_encoding(null, 0, &bom_size);
|
||||
assert(e == Encoding.UTF8);
|
||||
assert(bom_size == 0u);
|
||||
|
||||
dat = cast(const(ubyte)[])std.file.read("test/files/encodings/utf-8.txt");
|
||||
e = Encoding.detect_encoding(dat.ptr, dat.length, &bom_size);
|
||||
assert(e == Encoding.UTF8);
|
||||
assert(bom_size == 0u);
|
||||
|
||||
dat = cast(const(ubyte)[])std.file.read("test/files/encodings/utf-8-bom.txt");
|
||||
e = Encoding.detect_encoding(dat.ptr, dat.length, &bom_size);
|
||||
assert(e == Encoding.UTF8);
|
||||
assert(bom_size == 3u);
|
||||
|
||||
dat = cast(const(ubyte)[])std.file.read("test/files/encodings/utf-16le.txt");
|
||||
e = Encoding.detect_encoding(dat.ptr, dat.length, &bom_size);
|
||||
assert(e == Encoding.UTF16_LE);
|
||||
assert(bom_size == 2u);
|
||||
|
||||
dat = cast(const(ubyte)[])std.file.read("test/files/encodings/utf-16le-nobom.txt");
|
||||
e = Encoding.detect_encoding(dat.ptr, dat.length, &bom_size);
|
||||
assert(e == Encoding.UTF16_LE);
|
||||
assert(bom_size == 0u);
|
||||
|
||||
dat = cast(const(ubyte)[])std.file.read("test/files/encodings/utf-16be.txt");
|
||||
e = Encoding.detect_encoding(dat.ptr, dat.length, &bom_size);
|
||||
assert(e == Encoding.UTF16_BE);
|
||||
assert(bom_size == 2u);
|
||||
|
||||
dat = cast(const(ubyte)[])std.file.read("test/files/encodings/utf-16be-nobom.txt");
|
||||
e = Encoding.detect_encoding(dat.ptr, dat.length, &bom_size);
|
||||
assert(e == Encoding.UTF16_BE);
|
||||
assert(bom_size == 0u);
|
||||
|
||||
dat = cast(const(ubyte)[])std.file.read("test/files/encodings/cp-1252.txt");
|
||||
e = Encoding.detect_encoding(dat.ptr, dat.length, &bom_size);
|
||||
assert(e == Encoding.CP1252);
|
||||
assert(bom_size == 0u);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,76 @@
|
||||
module jes.core.lineendings;
|
||||
|
||||
struct LineEndings
|
||||
{
|
||||
enum : ubyte
|
||||
{
|
||||
LF,
|
||||
CRLF,
|
||||
}
|
||||
|
||||
ubyte type;
|
||||
alias type this;
|
||||
|
||||
this(ubyte type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@property string text() const
|
||||
{
|
||||
if (type == LF)
|
||||
{
|
||||
return "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
static LineEndings detect_line_endings(const ubyte * data, size_t n)
|
||||
{
|
||||
size_t lf_count = 0u;
|
||||
for (size_t i = 0u; i < n; i++)
|
||||
{
|
||||
if (data[i] == '\n')
|
||||
{
|
||||
lf_count++;
|
||||
/* Every LF must be preceded by a CR for the content to have
|
||||
* CRLF line endings. */
|
||||
if ((i == 0u) || (data[i - 1u] != '\r'))
|
||||
{
|
||||
return LineEndings(LF);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lf_count > 0u)
|
||||
{
|
||||
return LineEndings(CRLF);
|
||||
}
|
||||
return LineEndings(LF);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
import std.stdio;
|
||||
import std.file;
|
||||
const(ubyte)[] dat;
|
||||
LineEndings le;
|
||||
|
||||
dat = cast(const(ubyte)[])std.file.read("test/files/line_endings/crlf_format.txt");
|
||||
le = LineEndings.detect_line_endings(dat.ptr, dat.length);
|
||||
assert(le == LineEndings.CRLF);
|
||||
assert(le.text == "\r\n");
|
||||
|
||||
dat = cast(const(ubyte)[])std.file.read("test/files/empty.txt");
|
||||
le = LineEndings.detect_line_endings(dat.ptr, 0u);
|
||||
assert(le == LineEndings.LF);
|
||||
assert(le.text == "\n");
|
||||
|
||||
dat = cast(const(ubyte)[])std.file.read("test/files/line_endings/lf_format.txt");
|
||||
le = LineEndings.detect_line_endings(dat.ptr, dat.length);
|
||||
assert(le == LineEndings.LF);
|
||||
assert(le.text == "\n");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
module jes.core.undobuffer;
|
||||
|
||||
import jes.core.databuffer;
|
||||
|
||||
class UndoBuffer
|
||||
{
|
||||
/**
|
||||
* An UndoUnit represents a single contiguous chunk of inserted or deleted
|
||||
* data.
|
||||
*/
|
||||
class UndoUnit
|
||||
{
|
||||
/** Index where operation took place in target buffer. */
|
||||
size_t target_index;
|
||||
|
||||
/** Index of data stored in undo buffer. */
|
||||
size_t undo_buffer_index;
|
||||
|
||||
/** Length of the unit. */
|
||||
size_t length;
|
||||
|
||||
/** Whether the unit represents an insertion or deletion. */
|
||||
bool insert;
|
||||
|
||||
this(size_t target_index, size_t undo_buffer_index, size_t length, bool insert)
|
||||
{
|
||||
this.target_index = target_index;
|
||||
this.undo_buffer_index = undo_buffer_index;
|
||||
this.length = length;
|
||||
this.insert = insert;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An UndoOperation is a collection of one or more UndoUnits.
|
||||
*
|
||||
* All units in an operation are applied together when undoing/redoing the
|
||||
* full operation.
|
||||
*/
|
||||
class UndoOperation
|
||||
{
|
||||
/** ID of parent operation. */
|
||||
size_t parent;
|
||||
|
||||
/** Units in this operation. */
|
||||
UndoUnit[] units;
|
||||
|
||||
/** ID(s) of child operation(s). */
|
||||
size_t[] children;
|
||||
|
||||
this(size_t parent, UndoUnit unit)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.units ~= unit;
|
||||
}
|
||||
}
|
||||
|
||||
/** List of all undo operations in the buffer. */
|
||||
private UndoOperation[] m_operations;
|
||||
|
||||
/** Buffer storing the inserted/deleted data. */
|
||||
private DataBuffer m_data_buffer;
|
||||
|
||||
/** Operation level, nonzero means wait to commit the operation. */
|
||||
private size_t m_operation_level;
|
||||
|
||||
/** Reference to the operation currently being built. */
|
||||
private UndoOperation m_current_operation;
|
||||
|
||||
/** ID of the operation representing the current buffer state. */
|
||||
private size_t m_current_id;
|
||||
|
||||
this()
|
||||
{
|
||||
m_data_buffer = new DataBuffer();
|
||||
m_operations ~= null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the operation level.
|
||||
*
|
||||
* The operation will not be committed until the level returns to 0.
|
||||
*/
|
||||
void push_operation()
|
||||
{
|
||||
m_operation_level++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the operation should be committed and commit it if so.
|
||||
*/
|
||||
private void check_commit()
|
||||
{
|
||||
if (m_operation_level == 0u)
|
||||
{
|
||||
m_current_operation = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrease operation level.
|
||||
*
|
||||
* All undo units will be collected in one operation until the operation
|
||||
* level returns to 0.
|
||||
*/
|
||||
void pop_operation()
|
||||
{
|
||||
m_operation_level--;
|
||||
check_commit();
|
||||
}
|
||||
|
||||
private bool augment_current_unit(const(ubyte) * data, size_t length, size_t target_index, bool insert)
|
||||
{
|
||||
/* Nothing to augment if no operation yet in progress. */
|
||||
if (m_current_operation is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Current undo unit is the last undo unit in the current operation. */
|
||||
UndoUnit cuu = m_current_operation.units[$ - 1];
|
||||
|
||||
size_t cuu_target_end_index = cuu.target_index + cuu.length;
|
||||
|
||||
if (cuu.insert)
|
||||
{
|
||||
if (insert)
|
||||
{
|
||||
/* Case 1: current unit is an insert, new unit is an insert,
|
||||
* and the inserted data can be combined with the current unit
|
||||
* data. */
|
||||
if ((cuu.target_index <= target_index) &&
|
||||
(target_index <= cuu_target_end_index))
|
||||
{
|
||||
m_data_buffer.insert(cuu.undo_buffer_index + target_index - cuu.target_index, data, length);
|
||||
cuu.length += length;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Case 2: current unit is an insert, new unit is a delete, and
|
||||
* the data to be deleted is part of the inserted data. */
|
||||
if ((cuu.target_index <= target_index) &&
|
||||
((target_index + length) <= cuu_target_end_index))
|
||||
{
|
||||
m_data_buffer.erase(cuu.undo_buffer_index + target_index - cuu.target_index, length);
|
||||
cuu.length -= length;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Case 3: current unit is a delete, new unit is a delete, and the
|
||||
* new delete range is congruent to the current unit delete range. */
|
||||
if (!insert)
|
||||
{
|
||||
if (cuu.target_index == target_index)
|
||||
{
|
||||
m_data_buffer.insert(cuu.undo_buffer_index + cuu.length, data, length);
|
||||
}
|
||||
else if ((target_index + length) == cuu.target_index)
|
||||
{
|
||||
m_data_buffer.insert(cuu.undo_buffer_index, data, length);
|
||||
cuu.target_index = target_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
cuu.length += length;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void record_new_unit(UndoUnit uu)
|
||||
{
|
||||
if (m_current_operation is null)
|
||||
{
|
||||
UndoOperation uo = new UndoOperation(m_current_id, uu);
|
||||
size_t new_id = m_operations.length;
|
||||
m_operations ~= uo;
|
||||
m_current_operation = uo;
|
||||
if (m_current_id > 0u)
|
||||
{
|
||||
m_operations[m_current_id].children ~= new_id;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_operation.units ~= uu;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record a unit of undoable activity.
|
||||
*
|
||||
* @param data The data being inserted/deleted.
|
||||
* @param length Length of the data.
|
||||
* @param target_index Position in the target buffer where the unit takes place.
|
||||
* @param insert Whether this unit is an insertion or a deletion.
|
||||
*/
|
||||
void record_unit(const(ubyte) * data, size_t length, size_t target_index, bool insert)
|
||||
{
|
||||
if (!augment_current_unit(data, length, target_index, insert))
|
||||
{
|
||||
size_t undo_buffer_index = m_data_buffer.size;
|
||||
m_data_buffer.insert(undo_buffer_index, data, length);
|
||||
UndoUnit uu = new UndoUnit(target_index, undo_buffer_index, length, insert);
|
||||
record_new_unit(uu);
|
||||
}
|
||||
check_commit();
|
||||
}
|
||||
|
||||
version(unittest) invariant
|
||||
{
|
||||
assert(m_operations !is null);
|
||||
assert(m_operations.length > 0u);
|
||||
}
|
||||
|
||||
version(unittest) private @property size_t n_operations() const
|
||||
{
|
||||
return m_operations.length - 1u;
|
||||
}
|
||||
|
||||
version(unittest) private @property size_t n_units() const
|
||||
{
|
||||
size_t n;
|
||||
foreach (operation; m_operations)
|
||||
{
|
||||
if (operation !is null)
|
||||
{
|
||||
n += operation.units.length;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
version(unittest) void record_unit(string data, size_t length, size_t target_index, bool insert)
|
||||
{
|
||||
return record_unit(cast(const(ubyte) *)data.ptr, length, target_index, insert);
|
||||
}
|
||||
|
||||
version(unittest) string uu_string(UndoUnit uu) const
|
||||
{
|
||||
return (cast(immutable(char) *)m_data_buffer.address(uu.undo_buffer_index))[0 .. uu.length];
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
UndoBuffer ub;
|
||||
|
||||
/* Each record_unit creates an operation when level == 0 */
|
||||
ub = new UndoBuffer();
|
||||
assert(ub.n_operations == 0u);
|
||||
assert(ub.n_units == 0u);
|
||||
|
||||
ub.record_unit("hi", 2u, 0u, true);
|
||||
assert(ub.n_operations == 1u);
|
||||
assert(ub.n_units == 1u);
|
||||
assert(ub.uu_string(ub.m_operations[1].units[0]) == "hi");
|
||||
|
||||
ub.record_unit("there", 5u, 2u, true);
|
||||
assert(ub.n_operations == 2u);
|
||||
assert(ub.n_units == 2u);
|
||||
assert(ub.uu_string(ub.m_operations[2].units[0]) == "there");
|
||||
|
||||
/* Multiple record_unit calls are combined into one operation until
|
||||
* opertaion level is popped. */
|
||||
ub = new UndoBuffer();
|
||||
assert(ub.n_operations == 0u);
|
||||
assert(ub.n_units == 0u);
|
||||
|
||||
ub.push_operation();
|
||||
|
||||
ub.record_unit("hi", 2u, 0u, true);
|
||||
assert(ub.n_operations == 1u);
|
||||
assert(ub.n_units == 1u);
|
||||
assert(ub.m_operations[1].units[0].target_index == 0u);
|
||||
|
||||
ub.record_unit("there", 5u, 2u, true);
|
||||
assert(ub.n_operations == 1u);
|
||||
|
||||
/* Consecutive inserts are combined into one unit. */
|
||||
assert(ub.n_units == 1u);
|
||||
assert(ub.uu_string(ub.m_operations[1].units[0]) == "hithere");
|
||||
assert(ub.m_operations[1].units[0].target_index == 0u);
|
||||
|
||||
/* Delete from end of last unit modifies last unit. */
|
||||
ub.record_unit("e", 1u, 6u, false);
|
||||
assert(ub.n_units == 1u);
|
||||
assert(ub.uu_string(ub.m_operations[1].units[0]) == "hither");
|
||||
assert(ub.m_operations[1].units[0].target_index == 0u);
|
||||
|
||||
/* Delete from beginning of last unit modifies last unit. */
|
||||
ub.record_unit("h", 1u, 0u, false);
|
||||
assert(ub.n_units == 1u);
|
||||
assert(ub.uu_string(ub.m_operations[1].units[0]) == "ither");
|
||||
assert(ub.m_operations[1].units[0].target_index == 0u);
|
||||
|
||||
/* Delete from middle of last unit modifies last unit. */
|
||||
ub.record_unit("h", 1u, 2u, false);
|
||||
assert(ub.n_units == 1u);
|
||||
assert(ub.uu_string(ub.m_operations[1].units[0]) == "iter");
|
||||
assert(ub.m_operations[1].units[0].target_index == 0u);
|
||||
|
||||
ub.pop_operation();
|
||||
|
||||
/* Congruent deletions are combined. */
|
||||
ub.push_operation();
|
||||
|
||||
ub.record_unit("e", 1u, 2u, false);
|
||||
assert(ub.n_units == 2u);
|
||||
assert(ub.uu_string(ub.m_operations[2].units[0]) == "e");
|
||||
assert(ub.m_operations[2].units[0].target_index == 2u);
|
||||
ub.record_unit("r", 1u, 2u, false);
|
||||
assert(ub.n_units == 2u);
|
||||
assert(ub.uu_string(ub.m_operations[2].units[0]) == "er");
|
||||
assert(ub.m_operations[2].units[0].target_index == 2u);
|
||||
ub.record_unit("t", 1u, 1u, false);
|
||||
assert(ub.n_units == 2u);
|
||||
assert(ub.uu_string(ub.m_operations[2].units[0]) == "ter");
|
||||
assert(ub.m_operations[2].units[0].target_index == 1u);
|
||||
|
||||
ub.pop_operation();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#define round_up_26_6(val) (((val) + 63) >> 6u)
|
||||
|
||||
static FT_Library Library_Handle;
|
||||
static bool Initialized;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t advance;
|
||||
int32_t line_height;
|
||||
int32_t baseline_offset;
|
||||
FT_Face face;
|
||||
} Font;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t * bitmap;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t left;
|
||||
int32_t top;
|
||||
int32_t advance;
|
||||
} Glyph;
|
||||
|
||||
static bool Load_FreeType(void)
|
||||
{
|
||||
if (Initialized)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (FT_Init_FreeType(&Library_Handle) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Initialized = true;
|
||||
}
|
||||
|
||||
Glyph * Font_LoadGlyph(Font * font, uint32_t char_code)
|
||||
{
|
||||
FT_Char ft_char_code = char_code;
|
||||
if (FT_Load_Char(font->face, ft_char_code, FT_LOAD_RENDER) != 0)
|
||||
return NULL;
|
||||
|
||||
Glyph * glyph = (Glyph *)malloc(sizeof(Glyph));
|
||||
glyph->width = font->face->glyph->bitmap.width;
|
||||
glyph->height = font->face->glyph->bitmap.rows;
|
||||
glyph->left = font->face->glyph->bitmap_left;
|
||||
glyph->top = font->face->glyph->bitmap_top;
|
||||
glyph->advance = round_up_26_6(font->face->glyph->advance.x);
|
||||
glyph->bitmap = malloc(glyph->width * glyph->height);
|
||||
memcpy(glyph->bitmap, font->face->glyph->bitmap.buffer, glyph->width * glyph->height);
|
||||
|
||||
return glyph;
|
||||
}
|
||||
|
||||
void Font_FreeGlyph(Glyph * glyph)
|
||||
{
|
||||
free(glyph->bitmap);
|
||||
free(glyph);
|
||||
}
|
||||
|
||||
static void PreloadGlyphs(Font * font)
|
||||
{
|
||||
static const char preload_glyph_list[] = "HMgjqxy_|^";
|
||||
|
||||
int max_top = -9999;
|
||||
int min_bottom = 9999;
|
||||
font->advance = 0;
|
||||
|
||||
for (size_t i = 0u; i < sizeof(preload_glyph_list) - 1u; i++)
|
||||
{
|
||||
Glyph * glyph = Font_LoadGlyph(font, (uint8_t)preload_glyph_list[i]);
|
||||
if (glyph != NULL)
|
||||
{
|
||||
if (font->face->glyph->bitmap_top > max_top)
|
||||
{
|
||||
max_top = font->face->glyph->bitmap_top;
|
||||
}
|
||||
int bitmap_bottom = font->face->glyph->bitmap_top - font->face->glyph->bitmap.rows;
|
||||
if (bitmap_bottom < min_bottom)
|
||||
{
|
||||
min_bottom = bitmap_bottom;
|
||||
}
|
||||
if (glyph->advance > font->advance)
|
||||
{
|
||||
font->advance = glyph->advance;
|
||||
}
|
||||
Font_FreeGlyph(glyph);
|
||||
}
|
||||
}
|
||||
|
||||
font->line_height = round_up_26_6(font->face->size->metrics.height);
|
||||
font->baseline_offset = (font->line_height - (max_top - min_bottom)) / 2 - min_bottom;
|
||||
}
|
||||
|
||||
Font * Font_Load(const char * fname, int32_t size)
|
||||
{
|
||||
FT_Face face;
|
||||
|
||||
if (!Load_FreeType())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (FT_New_Face(Library_Handle, fname, 0, &face) != 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Font * font = (Font *)malloc(sizeof(Font));
|
||||
font->face = face;
|
||||
|
||||
FT_Set_Pixel_Sizes(face, 0, size);
|
||||
|
||||
PreloadGlyphs(font);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
void Font_Free(Font * font)
|
||||
{
|
||||
free(font);
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
module jes.gui.font;
|
||||
import std.string;
|
||||
import derelict.opengl;
|
||||
import gltk;
|
||||
import core.stdc.string;
|
||||
|
||||
struct CFont
|
||||
{
|
||||
int advance;
|
||||
int line_height;
|
||||
int baseline_offset;
|
||||
}
|
||||
|
||||
struct CGlyph
|
||||
{
|
||||
ubyte * bitmap;
|
||||
int width;
|
||||
int height;
|
||||
int left;
|
||||
int top;
|
||||
int advance;
|
||||
}
|
||||
|
||||
private extern(C) CGlyph * Font_LoadGlyph(CFont * font, uint char_code);
|
||||
private extern(C) void Font_FreeGlyph(CGlyph * glyph);
|
||||
private extern(C) CFont * Font_Load(const char * fname, int size);
|
||||
private extern(C) void Font_Free(CFont * font);
|
||||
|
||||
class Font
|
||||
{
|
||||
private static __gshared Glyph[uint] glyphs;
|
||||
|
||||
class Glyph
|
||||
{
|
||||
int advance;
|
||||
gltk.Texture m_texture;
|
||||
gltk.Buffer m_buffer;
|
||||
gltk.Array m_array;
|
||||
|
||||
this(const(CGlyph) * cglyph)
|
||||
{
|
||||
advance = cglyph.advance;
|
||||
m_texture = new gltk.Texture();
|
||||
m_texture.bind(GL_TEXTURE_2D);
|
||||
int rounded_width = gltk.Texture.next_power_of_2(cglyph.width);
|
||||
int rounded_height = gltk.Texture.next_power_of_2(cglyph.height);
|
||||
ubyte[] texture = new ubyte[rounded_width * rounded_height];
|
||||
memset(texture.ptr, 0, rounded_width * rounded_height);
|
||||
for (int i = 0; i < cglyph.height; i++)
|
||||
{
|
||||
memcpy(&texture[rounded_width * i],
|
||||
&cglyph.bitmap[cglyph.width * (cglyph.height - i - 1)],
|
||||
cglyph.width);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, rounded_width, rounded_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texture.ptr);
|
||||
|
||||
m_array = new gltk.Array();
|
||||
m_array.bind();
|
||||
|
||||
int left = cglyph.left;
|
||||
int top = cglyph.top;
|
||||
float s_max = cglyph.width / cast(float)rounded_width;
|
||||
float t_max = cglyph.height / cast(float)rounded_height;
|
||||
m_buffer = new gltk.Buffer(GL_ARRAY_BUFFER);
|
||||
GLfloat[] data = [
|
||||
cast(GLfloat)left, cast(GLfloat)(top - cglyph.height), 0.0, 0.0,
|
||||
cast(GLfloat)(left + cglyph.width), cast(GLfloat)(top - cglyph.height), s_max, 0.0,
|
||||
cast(GLfloat)left, cast(GLfloat)top, 0.0, t_max,
|
||||
cast(GLfloat)(left + cglyph.width), cast(GLfloat)top, s_max, t_max,
|
||||
];
|
||||
m_buffer.set_buffer_data(GL_STATIC_DRAW, data);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, null);
|
||||
}
|
||||
|
||||
void render()
|
||||
{
|
||||
m_array.bind();
|
||||
m_texture.bind(GL_TEXTURE_2D);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
CFont * m_font;
|
||||
|
||||
this(const char * fname, int size)
|
||||
{
|
||||
m_font = Font_Load(fname, size);
|
||||
if (m_font == null)
|
||||
{
|
||||
throw new Exception("Could not load font");
|
||||
}
|
||||
}
|
||||
|
||||
this(string fname, int size)
|
||||
{
|
||||
this(fname.toStringz(), size);
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
Font_Free(m_font);
|
||||
}
|
||||
|
||||
@property int advance()
|
||||
{
|
||||
return m_font.advance;
|
||||
}
|
||||
|
||||
@property int line_height()
|
||||
{
|
||||
return m_font.line_height;
|
||||
}
|
||||
|
||||
@property int baseline_offset()
|
||||
{
|
||||
return m_font.baseline_offset;
|
||||
}
|
||||
|
||||
Glyph get_glyph(uint char_code)
|
||||
{
|
||||
if (char_code in glyphs)
|
||||
{
|
||||
return glyphs[char_code];
|
||||
}
|
||||
Glyph glyph;
|
||||
CGlyph * cglyph = Font_LoadGlyph(m_font, char_code);
|
||||
if (cglyph != null)
|
||||
{
|
||||
glyph = new Glyph(cglyph);
|
||||
Font_FreeGlyph(cglyph);
|
||||
}
|
||||
glyphs[char_code] = glyph;
|
||||
return glyph;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
module jes.gui.gl;
|
||||
|
||||
static import gltk;
|
||||
import derelict.opengl;
|
||||
import jes.gui.font;
|
||||
|
||||
class Gl
|
||||
{
|
||||
alias FlatProgram = gltk.Program!("viewport_size", "2i", "color", "4f", "position", "2i");
|
||||
alias TextProgram = gltk.Program!("viewport_size", "2i", "texture", "1i", "color", "4f", "position", "2i");
|
||||
alias RectProgram = gltk.Program!("viewport_size", "2i", "color", "4f", "position", "2i", "size", "2i");
|
||||
|
||||
private FlatProgram m_flat_program;
|
||||
private TextProgram m_text_program;
|
||||
private RectProgram m_rect_program;
|
||||
private gltk.Array m_rect_array;
|
||||
private gltk.Buffer m_rect_buffer;
|
||||
|
||||
private void build_flat_program()
|
||||
{
|
||||
m_flat_program = new FlatProgram(
|
||||
build_shader(GL_VERTEX_SHADER, "share/jes/shaders/flat.v.glsl"),
|
||||
build_shader(GL_FRAGMENT_SHADER, "share/jes/shaders/flat.f.glsl"),
|
||||
"coords", 0);
|
||||
}
|
||||
|
||||
private void build_text_program()
|
||||
{
|
||||
m_text_program = new TextProgram(
|
||||
build_shader(GL_VERTEX_SHADER, "share/jes/shaders/text.v.glsl"),
|
||||
build_shader(GL_FRAGMENT_SHADER, "share/jes/shaders/text.f.glsl"),
|
||||
"coords", 0);
|
||||
m_text_program.use();
|
||||
m_text_program.set_texture(0);
|
||||
}
|
||||
|
||||
private void build_rect_program()
|
||||
{
|
||||
m_rect_program = new RectProgram(
|
||||
build_shader(GL_VERTEX_SHADER, "share/jes/shaders/rect.v.glsl"),
|
||||
build_shader(GL_FRAGMENT_SHADER, "share/jes/shaders/rect.f.glsl"),
|
||||
"coords", 0);
|
||||
m_rect_array = new gltk.Array();
|
||||
m_rect_array.bind();
|
||||
m_rect_buffer = new gltk.Buffer(GL_ARRAY_BUFFER);
|
||||
GLint[] rect_coords = [0, 0, 1, 0, 1, 1, 0, 1];
|
||||
m_rect_buffer.set_buffer_data(GL_STATIC_DRAW, rect_coords);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, null);
|
||||
}
|
||||
|
||||
this()
|
||||
{
|
||||
build_flat_program();
|
||||
build_text_program();
|
||||
build_rect_program();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
void resize(int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
m_flat_program.use();
|
||||
m_flat_program.set_viewport_size(width, height);
|
||||
m_text_program.use();
|
||||
m_text_program.set_viewport_size(width, height);
|
||||
m_rect_program.use();
|
||||
m_rect_program.set_viewport_size(width, height);
|
||||
}
|
||||
|
||||
void draw_character(Font font, uint char_code, int x, int y, float r, float g, float b, float a)
|
||||
{
|
||||
m_text_program.use();
|
||||
m_text_program.set_color(r, g, b, a);
|
||||
m_text_program.set_position(x, y);
|
||||
auto glyph = font.get_glyph(char_code);
|
||||
glyph.render();
|
||||
}
|
||||
|
||||
void draw_rect(int x, int y, int width, int height,
|
||||
float r, float g, float b, float a)
|
||||
{
|
||||
m_rect_array.bind();
|
||||
m_rect_program.use();
|
||||
m_rect_program.set_color(r, g, b, a);
|
||||
m_rect_program.set_position(x, y);
|
||||
m_rect_program.set_size(width, height);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
|
||||
private gltk.Shader build_shader(GLenum shader_type, string filename)
|
||||
{
|
||||
auto shader = new gltk.Shader(shader_type);
|
||||
shader.set_source_from_file(filename);
|
||||
return shader;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,516 @@
|
||||
module jes.gui.icon;
|
||||
|
||||
const ubyte[] icon_32x32_bgra = [
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x50u, 0x50u, 0x50u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x20u, 0x20u, 0x20u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x50u, 0x50u, 0x50u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x20u, 0x20u, 0x20u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xc8u, 0xc8u, 0xc8u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x20u, 0x20u, 0x20u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x2au, 0x2au, 0x2au, 0xffu,
|
||||
0xb1u, 0xb1u, 0xb1u, 0xffu, 0xf1u, 0xf1u, 0xf1u, 0xffu,
|
||||
0xf5u, 0xf5u, 0xf5u, 0xffu, 0xb5u, 0xb5u, 0xb5u, 0xffu,
|
||||
0x22u, 0x22u, 0x22u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x3bu, 0x3bu, 0x3bu, 0xffu,
|
||||
0xc0u, 0xc0u, 0xc0u, 0xffu, 0xf0u, 0xf0u, 0xf0u, 0xffu,
|
||||
0xe7u, 0xe7u, 0xe7u, 0xffu, 0xa0u, 0xa0u, 0xa0u, 0xffu,
|
||||
0x1bu, 0x1bu, 0x1bu, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x50u, 0x50u, 0x50u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x20u, 0x20u, 0x20u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x26u, 0x26u, 0x26u, 0xffu, 0xf0u, 0xf0u, 0xf0u, 0xffu,
|
||||
0xaau, 0xaau, 0xaau, 0xffu, 0x1du, 0x1du, 0x1du, 0xffu,
|
||||
0x18u, 0x18u, 0x18u, 0xffu, 0xa7u, 0xa7u, 0xa7u, 0xffu,
|
||||
0xdcu, 0xdcu, 0xdcu, 0xffu, 0x05u, 0x05u, 0x05u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x12u, 0x12u, 0x12u, 0xffu, 0xf0u, 0xf0u, 0xf0u, 0xffu,
|
||||
0x91u, 0x91u, 0x91u, 0xffu, 0x12u, 0x12u, 0x12u, 0xffu,
|
||||
0x15u, 0x15u, 0x15u, 0xffu, 0x5bu, 0x5bu, 0x5bu, 0xffu,
|
||||
0x7fu, 0x7fu, 0x7fu, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x50u, 0x50u, 0x50u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x20u, 0x20u, 0x20u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0xaau, 0xaau, 0xaau, 0xffu, 0xe4u, 0xe4u, 0xe4u, 0xffu,
|
||||
0x08u, 0x08u, 0x08u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x0fu, 0x0fu, 0x0fu, 0xffu,
|
||||
0xf6u, 0xf6u, 0xf6u, 0xffu, 0x60u, 0x60u, 0x60u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x40u, 0x40u, 0x40u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu,
|
||||
0x34u, 0x34u, 0x34u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x50u, 0x50u, 0x50u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x20u, 0x20u, 0x20u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0xefu, 0xefu, 0xefu, 0xffu, 0x9eu, 0x9eu, 0x9eu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0xd0u, 0xd0u, 0xd0u, 0xffu, 0x92u, 0x92u, 0x92u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x1cu, 0x1cu, 0x1cu, 0xffu, 0xfau, 0xfau, 0xfau, 0xffu,
|
||||
0xbfu, 0xbfu, 0xbfu, 0xffu, 0x4au, 0x4au, 0x4au, 0xffu,
|
||||
0x0fu, 0x0fu, 0x0fu, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x50u, 0x50u, 0x50u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x20u, 0x20u, 0x20u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0xadu, 0xadu, 0xadu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x4cu, 0x4cu, 0x4cu, 0xffu,
|
||||
0xc8u, 0xc8u, 0xc8u, 0xffu, 0xfdu, 0xfdu, 0xfdu, 0xffu,
|
||||
0xfeu, 0xfeu, 0xfeu, 0xffu, 0xc7u, 0xc7u, 0xc7u, 0xffu,
|
||||
0x31u, 0x31u, 0x31u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x50u, 0x50u, 0x50u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x20u, 0x20u, 0x20u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0xf0u, 0xf0u, 0xf0u, 0xffu, 0x89u, 0x89u, 0x89u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x0bu, 0x0bu, 0x0bu, 0xffu,
|
||||
0x52u, 0x52u, 0x52u, 0xffu, 0xe2u, 0xe2u, 0xe2u, 0xffu,
|
||||
0xdcu, 0xdcu, 0xdcu, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x50u, 0x50u, 0x50u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x20u, 0x20u, 0x20u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0xadu, 0xadu, 0xadu, 0xffu, 0xcau, 0xcau, 0xcau, 0xffu,
|
||||
0x01u, 0x01u, 0x01u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x76u, 0x76u, 0x76u, 0xffu,
|
||||
0xfau, 0xfau, 0xfau, 0xffu, 0x03u, 0x03u, 0x03u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x50u, 0x50u, 0x50u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x20u, 0x20u, 0x20u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x2au, 0x2au, 0x2au, 0xffu, 0xf3u, 0xf3u, 0xf3u, 0xffu,
|
||||
0x9au, 0x9au, 0x9au, 0xffu, 0x22u, 0x22u, 0x22u, 0xffu,
|
||||
0x0bu, 0x0bu, 0x0bu, 0xffu, 0x35u, 0x35u, 0x35u, 0xffu,
|
||||
0x98u, 0x98u, 0x98u, 0xffu, 0x54u, 0x54u, 0x54u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x4du, 0x4du, 0x4du, 0xffu, 0x97u, 0x97u, 0x97u, 0xffu,
|
||||
0x33u, 0x33u, 0x33u, 0xffu, 0x0au, 0x0au, 0x0au, 0xffu,
|
||||
0x29u, 0x29u, 0x29u, 0xffu, 0xd0u, 0xd0u, 0xd0u, 0xffu,
|
||||
0xb6u, 0xb6u, 0xb6u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x50u, 0x50u, 0x50u, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x20u, 0x20u, 0x20u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x2bu, 0x2bu, 0x2bu, 0xffu,
|
||||
0xadu, 0xadu, 0xadu, 0xffu, 0xedu, 0xedu, 0xedu, 0xffu,
|
||||
0xf5u, 0xf5u, 0xf5u, 0xffu, 0xcau, 0xcau, 0xcau, 0xffu,
|
||||
0x69u, 0x69u, 0x69u, 0xffu, 0x07u, 0x07u, 0x07u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x06u, 0x06u, 0x06u, 0xffu, 0x68u, 0x68u, 0x68u, 0xffu,
|
||||
0xccu, 0xccu, 0xccu, 0xffu, 0xf5u, 0xf5u, 0xf5u, 0xffu,
|
||||
0xe3u, 0xe3u, 0xe3u, 0xffu, 0x98u, 0x98u, 0x98u, 0xffu,
|
||||
0x13u, 0x13u, 0x13u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x5eu, 0x5eu, 0x5eu, 0xffu,
|
||||
0xffu, 0xffu, 0xffu, 0xffu, 0x0eu, 0x0eu, 0x0eu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x0eu, 0x0eu, 0x0eu, 0xffu, 0xbcu, 0xbcu, 0xbcu, 0xffu,
|
||||
0xceu, 0xceu, 0xceu, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x8cu, 0x8cu, 0x8cu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu,
|
||||
0xf9u, 0xf9u, 0xf9u, 0xffu, 0xc6u, 0xc6u, 0xc6u, 0xffu,
|
||||
0x2bu, 0x2bu, 0x2bu, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0xffu, 0x33u, 0xffu, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
0x00u, 0x00u, 0x00u, 0xffu, 0x00u, 0x00u, 0x00u, 0xffu,
|
||||
];
|
||||
@@ -0,0 +1,54 @@
|
||||
module jes.gui;
|
||||
|
||||
static import jtk;
|
||||
import std.stdio;
|
||||
import jes.gui.window;
|
||||
|
||||
class Gui
|
||||
{
|
||||
this()
|
||||
{
|
||||
if (!jtk.initialize())
|
||||
{
|
||||
throw new Exception("JTK initialization failed.");
|
||||
}
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
new Window();
|
||||
event_loop();
|
||||
}
|
||||
finally
|
||||
{
|
||||
jtk.quit();
|
||||
}
|
||||
}
|
||||
|
||||
private void event_loop()
|
||||
{
|
||||
bool running = true;
|
||||
while (running)
|
||||
{
|
||||
jtk.Event event = jtk.wait_event();
|
||||
switch (event.type)
|
||||
{
|
||||
case jtk.Event.WINDOW_CLOSE:
|
||||
Window window = Window[event.window_close.window];
|
||||
window.close();
|
||||
running = false;
|
||||
break;
|
||||
|
||||
case jtk.Event.WINDOW_RESIZE:
|
||||
Window window = Window[event.window_resize.window];
|
||||
window.resize(event.window_resize.width, event.window_resize.height);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 117 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user